Home | History | Annotate | Download | only in X86
      1 //===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly --------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains a printer that converts from our internal representation
     11 // of machine-dependent LLVM code to X86 machine code.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #include "X86AsmPrinter.h"
     16 #include "InstPrinter/X86ATTInstPrinter.h"
     17 #include "MCTargetDesc/X86BaseInfo.h"
     18 #include "X86InstrInfo.h"
     19 #include "X86MachineFunctionInfo.h"
     20 #include "llvm/ADT/SmallString.h"
     21 #include "llvm/CodeGen/MachineConstantPool.h"
     22 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
     23 #include "llvm/CodeGen/MachineValueType.h"
     24 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
     25 #include "llvm/IR/DebugInfo.h"
     26 #include "llvm/IR/DerivedTypes.h"
     27 #include "llvm/IR/Mangler.h"
     28 #include "llvm/IR/Module.h"
     29 #include "llvm/IR/Type.h"
     30 #include "llvm/MC/MCAsmInfo.h"
     31 #include "llvm/MC/MCContext.h"
     32 #include "llvm/MC/MCExpr.h"
     33 #include "llvm/MC/MCSectionCOFF.h"
     34 #include "llvm/MC/MCSectionMachO.h"
     35 #include "llvm/MC/MCStreamer.h"
     36 #include "llvm/MC/MCSymbol.h"
     37 #include "llvm/Support/COFF.h"
     38 #include "llvm/Support/Debug.h"
     39 #include "llvm/Support/ErrorHandling.h"
     40 #include "llvm/Support/TargetRegistry.h"
     41 using namespace llvm;
     42 
     43 //===----------------------------------------------------------------------===//
     44 // Primitive Helper Functions.
     45 //===----------------------------------------------------------------------===//
     46 
     47 /// runOnMachineFunction - Emit the function body.
     48 ///
     49 bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
     50   Subtarget = &MF.getSubtarget<X86Subtarget>();
     51 
     52   SMShadowTracker.startFunction(MF);
     53 
     54   SetupMachineFunction(MF);
     55 
     56   if (Subtarget->isTargetCOFF()) {
     57     bool Intrn = MF.getFunction()->hasInternalLinkage();
     58     OutStreamer->BeginCOFFSymbolDef(CurrentFnSym);
     59     OutStreamer->EmitCOFFSymbolStorageClass(Intrn ? COFF::IMAGE_SYM_CLASS_STATIC
     60                                             : COFF::IMAGE_SYM_CLASS_EXTERNAL);
     61     OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
     62                                                << COFF::SCT_COMPLEX_TYPE_SHIFT);
     63     OutStreamer->EndCOFFSymbolDef();
     64   }
     65 
     66   // Emit the rest of the function body.
     67   EmitFunctionBody();
     68 
     69   // We didn't modify anything.
     70   return false;
     71 }
     72 
     73 /// printSymbolOperand - Print a raw symbol reference operand.  This handles
     74 /// jump tables, constant pools, global address and external symbols, all of
     75 /// which print to a label with various suffixes for relocation types etc.
     76 static void printSymbolOperand(X86AsmPrinter &P, const MachineOperand &MO,
     77                                raw_ostream &O) {
     78   switch (MO.getType()) {
     79   default: llvm_unreachable("unknown symbol type!");
     80   case MachineOperand::MO_ConstantPoolIndex:
     81     P.GetCPISymbol(MO.getIndex())->print(O, P.MAI);
     82     P.printOffset(MO.getOffset(), O);
     83     break;
     84   case MachineOperand::MO_GlobalAddress: {
     85     const GlobalValue *GV = MO.getGlobal();
     86 
     87     MCSymbol *GVSym;
     88     if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
     89       GVSym = P.getSymbolWithGlobalValueBase(GV, "$stub");
     90     else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
     91              MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
     92              MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
     93       GVSym = P.getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
     94     else
     95       GVSym = P.getSymbol(GV);
     96 
     97     // Handle dllimport linkage.
     98     if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
     99       GVSym =
    100           P.OutContext.getOrCreateSymbol(Twine("__imp_") + GVSym->getName());
    101 
    102     if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
    103         MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
    104       MCSymbol *Sym = P.getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
    105       MachineModuleInfoImpl::StubValueTy &StubSym =
    106           P.MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym);
    107       if (!StubSym.getPointer())
    108         StubSym = MachineModuleInfoImpl::
    109           StubValueTy(P.getSymbol(GV), !GV->hasInternalLinkage());
    110     } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){
    111       MCSymbol *Sym = P.getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
    112       MachineModuleInfoImpl::StubValueTy &StubSym =
    113           P.MMI->getObjFileInfo<MachineModuleInfoMachO>().getHiddenGVStubEntry(
    114               Sym);
    115       if (!StubSym.getPointer())
    116         StubSym = MachineModuleInfoImpl::
    117           StubValueTy(P.getSymbol(GV), !GV->hasInternalLinkage());
    118     } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
    119       MCSymbol *Sym = P.getSymbolWithGlobalValueBase(GV, "$stub");
    120       MachineModuleInfoImpl::StubValueTy &StubSym =
    121           P.MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym);
    122       if (!StubSym.getPointer())
    123         StubSym = MachineModuleInfoImpl::
    124           StubValueTy(P.getSymbol(GV), !GV->hasInternalLinkage());
    125     }
    126 
    127     // If the name begins with a dollar-sign, enclose it in parens.  We do this
    128     // to avoid having it look like an integer immediate to the assembler.
    129     if (GVSym->getName()[0] != '$')
    130       GVSym->print(O, P.MAI);
    131     else {
    132       O << '(';
    133       GVSym->print(O, P.MAI);
    134       O << ')';
    135     }
    136     P.printOffset(MO.getOffset(), O);
    137     break;
    138   }
    139   }
    140 
    141   switch (MO.getTargetFlags()) {
    142   default:
    143     llvm_unreachable("Unknown target flag on GV operand");
    144   case X86II::MO_NO_FLAG:    // No flag.
    145     break;
    146   case X86II::MO_DARWIN_NONLAZY:
    147   case X86II::MO_DLLIMPORT:
    148   case X86II::MO_DARWIN_STUB:
    149     // These affect the name of the symbol, not any suffix.
    150     break;
    151   case X86II::MO_GOT_ABSOLUTE_ADDRESS:
    152     O << " + [.-";
    153     P.MF->getPICBaseSymbol()->print(O, P.MAI);
    154     O << ']';
    155     break;
    156   case X86II::MO_PIC_BASE_OFFSET:
    157   case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
    158   case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
    159     O << '-';
    160     P.MF->getPICBaseSymbol()->print(O, P.MAI);
    161     break;
    162   case X86II::MO_TLSGD:     O << "@TLSGD";     break;
    163   case X86II::MO_TLSLD:     O << "@TLSLD";     break;
    164   case X86II::MO_TLSLDM:    O << "@TLSLDM";    break;
    165   case X86II::MO_GOTTPOFF:  O << "@GOTTPOFF";  break;
    166   case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break;
    167   case X86II::MO_TPOFF:     O << "@TPOFF";     break;
    168   case X86II::MO_DTPOFF:    O << "@DTPOFF";    break;
    169   case X86II::MO_NTPOFF:    O << "@NTPOFF";    break;
    170   case X86II::MO_GOTNTPOFF: O << "@GOTNTPOFF"; break;
    171   case X86II::MO_GOTPCREL:  O << "@GOTPCREL";  break;
    172   case X86II::MO_GOT:       O << "@GOT";       break;
    173   case X86II::MO_GOTOFF:    O << "@GOTOFF";    break;
    174   case X86II::MO_PLT:       O << "@PLT";       break;
    175   case X86II::MO_TLVP:      O << "@TLVP";      break;
    176   case X86II::MO_TLVP_PIC_BASE:
    177     O << "@TLVP" << '-';
    178     P.MF->getPICBaseSymbol()->print(O, P.MAI);
    179     break;
    180   case X86II::MO_SECREL:    O << "@SECREL32";  break;
    181   }
    182 }
    183 
    184 static void printOperand(X86AsmPrinter &P, const MachineInstr *MI,
    185                          unsigned OpNo, raw_ostream &O,
    186                          const char *Modifier = nullptr, unsigned AsmVariant = 0);
    187 
    188 /// printPCRelImm - This is used to print an immediate value that ends up
    189 /// being encoded as a pc-relative value.  These print slightly differently, for
    190 /// example, a $ is not emitted.
    191 static void printPCRelImm(X86AsmPrinter &P, const MachineInstr *MI,
    192                           unsigned OpNo, raw_ostream &O) {
    193   const MachineOperand &MO = MI->getOperand(OpNo);
    194   switch (MO.getType()) {
    195   default: llvm_unreachable("Unknown pcrel immediate operand");
    196   case MachineOperand::MO_Register:
    197     // pc-relativeness was handled when computing the value in the reg.
    198     printOperand(P, MI, OpNo, O);
    199     return;
    200   case MachineOperand::MO_Immediate:
    201     O << MO.getImm();
    202     return;
    203   case MachineOperand::MO_GlobalAddress:
    204     printSymbolOperand(P, MO, O);
    205     return;
    206   }
    207 }
    208 
    209 static void printOperand(X86AsmPrinter &P, const MachineInstr *MI,
    210                          unsigned OpNo, raw_ostream &O, const char *Modifier,
    211                          unsigned AsmVariant) {
    212   const MachineOperand &MO = MI->getOperand(OpNo);
    213   switch (MO.getType()) {
    214   default: llvm_unreachable("unknown operand type!");
    215   case MachineOperand::MO_Register: {
    216     // FIXME: Enumerating AsmVariant, so we can remove magic number.
    217     if (AsmVariant == 0) O << '%';
    218     unsigned Reg = MO.getReg();
    219     if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
    220       MVT::SimpleValueType VT = (strcmp(Modifier+6,"64") == 0) ?
    221         MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 :
    222                     ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8));
    223       Reg = getX86SubSuperRegister(Reg, VT);
    224     }
    225     O << X86ATTInstPrinter::getRegisterName(Reg);
    226     return;
    227   }
    228 
    229   case MachineOperand::MO_Immediate:
    230     if (AsmVariant == 0) O << '$';
    231     O << MO.getImm();
    232     return;
    233 
    234   case MachineOperand::MO_GlobalAddress: {
    235     if (AsmVariant == 0) O << '$';
    236     printSymbolOperand(P, MO, O);
    237     break;
    238   }
    239   }
    240 }
    241 
    242 static void printLeaMemReference(X86AsmPrinter &P, const MachineInstr *MI,
    243                                  unsigned Op, raw_ostream &O,
    244                                  const char *Modifier = nullptr) {
    245   const MachineOperand &BaseReg  = MI->getOperand(Op+X86::AddrBaseReg);
    246   const MachineOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg);
    247   const MachineOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp);
    248 
    249   // If we really don't want to print out (rip), don't.
    250   bool HasBaseReg = BaseReg.getReg() != 0;
    251   if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") &&
    252       BaseReg.getReg() == X86::RIP)
    253     HasBaseReg = false;
    254 
    255   // HasParenPart - True if we will print out the () part of the mem ref.
    256   bool HasParenPart = IndexReg.getReg() || HasBaseReg;
    257 
    258   switch (DispSpec.getType()) {
    259   default:
    260     llvm_unreachable("unknown operand type!");
    261   case MachineOperand::MO_Immediate: {
    262     int DispVal = DispSpec.getImm();
    263     if (DispVal || !HasParenPart)
    264       O << DispVal;
    265     break;
    266   }
    267   case MachineOperand::MO_GlobalAddress:
    268   case MachineOperand::MO_ConstantPoolIndex:
    269     printSymbolOperand(P, DispSpec, O);
    270   }
    271 
    272   if (Modifier && strcmp(Modifier, "H") == 0)
    273     O << "+8";
    274 
    275   if (HasParenPart) {
    276     assert(IndexReg.getReg() != X86::ESP &&
    277            "X86 doesn't allow scaling by ESP");
    278 
    279     O << '(';
    280     if (HasBaseReg)
    281       printOperand(P, MI, Op+X86::AddrBaseReg, O, Modifier);
    282 
    283     if (IndexReg.getReg()) {
    284       O << ',';
    285       printOperand(P, MI, Op+X86::AddrIndexReg, O, Modifier);
    286       unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm();
    287       if (ScaleVal != 1)
    288         O << ',' << ScaleVal;
    289     }
    290     O << ')';
    291   }
    292 }
    293 
    294 static void printMemReference(X86AsmPrinter &P, const MachineInstr *MI,
    295                               unsigned Op, raw_ostream &O,
    296                               const char *Modifier = nullptr) {
    297   assert(isMem(MI, Op) && "Invalid memory reference!");
    298   const MachineOperand &Segment = MI->getOperand(Op+X86::AddrSegmentReg);
    299   if (Segment.getReg()) {
    300     printOperand(P, MI, Op+X86::AddrSegmentReg, O, Modifier);
    301     O << ':';
    302   }
    303   printLeaMemReference(P, MI, Op, O, Modifier);
    304 }
    305 
    306 static void printIntelMemReference(X86AsmPrinter &P, const MachineInstr *MI,
    307                                    unsigned Op, raw_ostream &O,
    308                                    const char *Modifier = nullptr,
    309                                    unsigned AsmVariant = 1) {
    310   const MachineOperand &BaseReg  = MI->getOperand(Op+X86::AddrBaseReg);
    311   unsigned ScaleVal = MI->getOperand(Op+X86::AddrScaleAmt).getImm();
    312   const MachineOperand &IndexReg = MI->getOperand(Op+X86::AddrIndexReg);
    313   const MachineOperand &DispSpec = MI->getOperand(Op+X86::AddrDisp);
    314   const MachineOperand &SegReg   = MI->getOperand(Op+X86::AddrSegmentReg);
    315 
    316   // If this has a segment register, print it.
    317   if (SegReg.getReg()) {
    318     printOperand(P, MI, Op+X86::AddrSegmentReg, O, Modifier, AsmVariant);
    319     O << ':';
    320   }
    321 
    322   O << '[';
    323 
    324   bool NeedPlus = false;
    325   if (BaseReg.getReg()) {
    326     printOperand(P, MI, Op+X86::AddrBaseReg, O, Modifier, AsmVariant);
    327     NeedPlus = true;
    328   }
    329 
    330   if (IndexReg.getReg()) {
    331     if (NeedPlus) O << " + ";
    332     if (ScaleVal != 1)
    333       O << ScaleVal << '*';
    334     printOperand(P, MI, Op+X86::AddrIndexReg, O, Modifier, AsmVariant);
    335     NeedPlus = true;
    336   }
    337 
    338   if (!DispSpec.isImm()) {
    339     if (NeedPlus) O << " + ";
    340     printOperand(P, MI, Op+X86::AddrDisp, O, Modifier, AsmVariant);
    341   } else {
    342     int64_t DispVal = DispSpec.getImm();
    343     if (DispVal || (!IndexReg.getReg() && !BaseReg.getReg())) {
    344       if (NeedPlus) {
    345         if (DispVal > 0)
    346           O << " + ";
    347         else {
    348           O << " - ";
    349           DispVal = -DispVal;
    350         }
    351       }
    352       O << DispVal;
    353     }
    354   }
    355   O << ']';
    356 }
    357 
    358 static bool printAsmMRegister(X86AsmPrinter &P, const MachineOperand &MO,
    359                               char Mode, raw_ostream &O) {
    360   unsigned Reg = MO.getReg();
    361   switch (Mode) {
    362   default: return true;  // Unknown mode.
    363   case 'b': // Print QImode register
    364     Reg = getX86SubSuperRegister(Reg, MVT::i8);
    365     break;
    366   case 'h': // Print QImode high register
    367     Reg = getX86SubSuperRegister(Reg, MVT::i8, true);
    368     break;
    369   case 'w': // Print HImode register
    370     Reg = getX86SubSuperRegister(Reg, MVT::i16);
    371     break;
    372   case 'k': // Print SImode register
    373     Reg = getX86SubSuperRegister(Reg, MVT::i32);
    374     break;
    375   case 'q':
    376     // Print 64-bit register names if 64-bit integer registers are available.
    377     // Otherwise, print 32-bit register names.
    378     MVT::SimpleValueType Ty = P.getSubtarget().is64Bit() ? MVT::i64 : MVT::i32;
    379     Reg = getX86SubSuperRegister(Reg, Ty);
    380     break;
    381   }
    382 
    383   O << '%' << X86ATTInstPrinter::getRegisterName(Reg);
    384   return false;
    385 }
    386 
    387 /// PrintAsmOperand - Print out an operand for an inline asm expression.
    388 ///
    389 bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
    390                                     unsigned AsmVariant,
    391                                     const char *ExtraCode, raw_ostream &O) {
    392   // Does this asm operand have a single letter operand modifier?
    393   if (ExtraCode && ExtraCode[0]) {
    394     if (ExtraCode[1] != 0) return true; // Unknown modifier.
    395 
    396     const MachineOperand &MO = MI->getOperand(OpNo);
    397 
    398     switch (ExtraCode[0]) {
    399     default:
    400       // See if this is a generic print operand
    401       return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
    402     case 'a': // This is an address.  Currently only 'i' and 'r' are expected.
    403       switch (MO.getType()) {
    404       default:
    405         return true;
    406       case MachineOperand::MO_Immediate:
    407         O << MO.getImm();
    408         return false;
    409       case MachineOperand::MO_ConstantPoolIndex:
    410       case MachineOperand::MO_JumpTableIndex:
    411       case MachineOperand::MO_ExternalSymbol:
    412         llvm_unreachable("unexpected operand type!");
    413       case MachineOperand::MO_GlobalAddress:
    414         printSymbolOperand(*this, MO, O);
    415         if (Subtarget->isPICStyleRIPRel())
    416           O << "(%rip)";
    417         return false;
    418       case MachineOperand::MO_Register:
    419         O << '(';
    420         printOperand(*this, MI, OpNo, O);
    421         O << ')';
    422         return false;
    423       }
    424 
    425     case 'c': // Don't print "$" before a global var name or constant.
    426       switch (MO.getType()) {
    427       default:
    428         printOperand(*this, MI, OpNo, O);
    429         break;
    430       case MachineOperand::MO_Immediate:
    431         O << MO.getImm();
    432         break;
    433       case MachineOperand::MO_ConstantPoolIndex:
    434       case MachineOperand::MO_JumpTableIndex:
    435       case MachineOperand::MO_ExternalSymbol:
    436         llvm_unreachable("unexpected operand type!");
    437       case MachineOperand::MO_GlobalAddress:
    438         printSymbolOperand(*this, MO, O);
    439         break;
    440       }
    441       return false;
    442 
    443     case 'A': // Print '*' before a register (it must be a register)
    444       if (MO.isReg()) {
    445         O << '*';
    446         printOperand(*this, MI, OpNo, O);
    447         return false;
    448       }
    449       return true;
    450 
    451     case 'b': // Print QImode register
    452     case 'h': // Print QImode high register
    453     case 'w': // Print HImode register
    454     case 'k': // Print SImode register
    455     case 'q': // Print DImode register
    456       if (MO.isReg())
    457         return printAsmMRegister(*this, MO, ExtraCode[0], O);
    458       printOperand(*this, MI, OpNo, O);
    459       return false;
    460 
    461     case 'P': // This is the operand of a call, treat specially.
    462       printPCRelImm(*this, MI, OpNo, O);
    463       return false;
    464 
    465     case 'n':  // Negate the immediate or print a '-' before the operand.
    466       // Note: this is a temporary solution. It should be handled target
    467       // independently as part of the 'MC' work.
    468       if (MO.isImm()) {
    469         O << -MO.getImm();
    470         return false;
    471       }
    472       O << '-';
    473     }
    474   }
    475 
    476   printOperand(*this, MI, OpNo, O, /*Modifier*/ nullptr, AsmVariant);
    477   return false;
    478 }
    479 
    480 bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
    481                                           unsigned OpNo, unsigned AsmVariant,
    482                                           const char *ExtraCode,
    483                                           raw_ostream &O) {
    484   if (AsmVariant) {
    485     printIntelMemReference(*this, MI, OpNo, O);
    486     return false;
    487   }
    488 
    489   if (ExtraCode && ExtraCode[0]) {
    490     if (ExtraCode[1] != 0) return true; // Unknown modifier.
    491 
    492     switch (ExtraCode[0]) {
    493     default: return true;  // Unknown modifier.
    494     case 'b': // Print QImode register
    495     case 'h': // Print QImode high register
    496     case 'w': // Print HImode register
    497     case 'k': // Print SImode register
    498     case 'q': // Print SImode register
    499       // These only apply to registers, ignore on mem.
    500       break;
    501     case 'H':
    502       printMemReference(*this, MI, OpNo, O, "H");
    503       return false;
    504     case 'P': // Don't print @PLT, but do print as memory.
    505       printMemReference(*this, MI, OpNo, O, "no-rip");
    506       return false;
    507     }
    508   }
    509   printMemReference(*this, MI, OpNo, O);
    510   return false;
    511 }
    512 
    513 void X86AsmPrinter::EmitStartOfAsmFile(Module &M) {
    514   const Triple &TT = TM.getTargetTriple();
    515 
    516   if (TT.isOSBinFormatMachO())
    517     OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
    518 
    519   if (TT.isOSBinFormatCOFF()) {
    520     // Emit an absolute @feat.00 symbol.  This appears to be some kind of
    521     // compiler features bitfield read by link.exe.
    522     if (TT.getArch() == Triple::x86) {
    523       MCSymbol *S = MMI->getContext().getOrCreateSymbol(StringRef("@feat.00"));
    524       OutStreamer->BeginCOFFSymbolDef(S);
    525       OutStreamer->EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
    526       OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);
    527       OutStreamer->EndCOFFSymbolDef();
    528       // According to the PE-COFF spec, the LSB of this value marks the object
    529       // for "registered SEH".  This means that all SEH handler entry points
    530       // must be registered in .sxdata.  Use of any unregistered handlers will
    531       // cause the process to terminate immediately.  LLVM does not know how to
    532       // register any SEH handlers, so its object files should be safe.
    533       OutStreamer->EmitSymbolAttribute(S, MCSA_Global);
    534       OutStreamer->EmitAssignment(
    535           S, MCConstantExpr::create(int64_t(1), MMI->getContext()));
    536     }
    537   }
    538   OutStreamer->EmitSyntaxDirective();
    539 }
    540 
    541 static void
    542 emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel,
    543                          MachineModuleInfoImpl::StubValueTy &MCSym) {
    544   // L_foo$stub:
    545   OutStreamer.EmitLabel(StubLabel);
    546   //   .indirect_symbol _foo
    547   OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
    548 
    549   if (MCSym.getInt())
    550     // External to current translation unit.
    551     OutStreamer.EmitIntValue(0, 4/*size*/);
    552   else
    553     // Internal to current translation unit.
    554     //
    555     // When we place the LSDA into the TEXT section, the type info
    556     // pointers need to be indirect and pc-rel. We accomplish this by
    557     // using NLPs; however, sometimes the types are local to the file.
    558     // We need to fill in the value for the NLP in those cases.
    559     OutStreamer.EmitValue(
    560         MCSymbolRefExpr::create(MCSym.getPointer(), OutStreamer.getContext()),
    561         4 /*size*/);
    562 }
    563 
    564 MCSymbol *X86AsmPrinter::GetCPISymbol(unsigned CPID) const {
    565   if (Subtarget->isTargetKnownWindowsMSVC()) {
    566     const MachineConstantPoolEntry &CPE =
    567         MF->getConstantPool()->getConstants()[CPID];
    568     if (!CPE.isMachineConstantPoolEntry()) {
    569       const DataLayout &DL = MF->getDataLayout();
    570       SectionKind Kind = CPE.getSectionKind(&DL);
    571       const Constant *C = CPE.Val.ConstVal;
    572       if (const MCSectionCOFF *S = dyn_cast<MCSectionCOFF>(
    573               getObjFileLowering().getSectionForConstant(DL, Kind, C))) {
    574         if (MCSymbol *Sym = S->getCOMDATSymbol()) {
    575           if (Sym->isUndefined())
    576             OutStreamer->EmitSymbolAttribute(Sym, MCSA_Global);
    577           return Sym;
    578         }
    579       }
    580     }
    581   }
    582 
    583   return AsmPrinter::GetCPISymbol(CPID);
    584 }
    585 
    586 void X86AsmPrinter::EmitEndOfAsmFile(Module &M) {
    587   const Triple &TT = TM.getTargetTriple();
    588 
    589   if (TT.isOSBinFormatMachO()) {
    590     // All darwin targets use mach-o.
    591     MachineModuleInfoMachO &MMIMacho =
    592         MMI->getObjFileInfo<MachineModuleInfoMachO>();
    593 
    594     // Output stubs for dynamically-linked functions.
    595     MachineModuleInfoMachO::SymbolListTy Stubs;
    596 
    597     Stubs = MMIMacho.GetFnStubList();
    598     if (!Stubs.empty()) {
    599       MCSection *TheSection = OutContext.getMachOSection(
    600           "__IMPORT", "__jump_table",
    601           MachO::S_SYMBOL_STUBS | MachO::S_ATTR_SELF_MODIFYING_CODE |
    602               MachO::S_ATTR_PURE_INSTRUCTIONS,
    603           5, SectionKind::getMetadata());
    604       OutStreamer->SwitchSection(TheSection);
    605 
    606       for (const auto &Stub : Stubs) {
    607         // L_foo$stub:
    608         OutStreamer->EmitLabel(Stub.first);
    609         //   .indirect_symbol _foo
    610         OutStreamer->EmitSymbolAttribute(Stub.second.getPointer(),
    611                                          MCSA_IndirectSymbol);
    612         // hlt; hlt; hlt; hlt; hlt     hlt = 0xf4.
    613         const char HltInsts[] = "\xf4\xf4\xf4\xf4\xf4";
    614         OutStreamer->EmitBytes(StringRef(HltInsts, 5));
    615       }
    616 
    617       Stubs.clear();
    618       OutStreamer->AddBlankLine();
    619     }
    620 
    621     // Output stubs for external and common global variables.
    622     Stubs = MMIMacho.GetGVStubList();
    623     if (!Stubs.empty()) {
    624       MCSection *TheSection = OutContext.getMachOSection(
    625           "__IMPORT", "__pointers", MachO::S_NON_LAZY_SYMBOL_POINTERS,
    626           SectionKind::getMetadata());
    627       OutStreamer->SwitchSection(TheSection);
    628 
    629       for (auto &Stub : Stubs)
    630         emitNonLazySymbolPointer(*OutStreamer, Stub.first, Stub.second);
    631 
    632       Stubs.clear();
    633       OutStreamer->AddBlankLine();
    634     }
    635 
    636     Stubs = MMIMacho.GetHiddenGVStubList();
    637     if (!Stubs.empty()) {
    638       MCSection *TheSection = OutContext.getMachOSection(
    639           "__IMPORT", "__pointers", MachO::S_NON_LAZY_SYMBOL_POINTERS,
    640           SectionKind::getMetadata());
    641       OutStreamer->SwitchSection(TheSection);
    642 
    643       for (auto &Stub : Stubs)
    644         emitNonLazySymbolPointer(*OutStreamer, Stub.first, Stub.second);
    645 
    646       Stubs.clear();
    647       OutStreamer->AddBlankLine();
    648     }
    649 
    650     SM.serializeToStackMapSection();
    651     FM.serializeToFaultMapSection();
    652 
    653     // Funny Darwin hack: This flag tells the linker that no global symbols
    654     // contain code that falls through to other global symbols (e.g. the obvious
    655     // implementation of multiple entry points).  If this doesn't occur, the
    656     // linker can safely perform dead code stripping.  Since LLVM never
    657     // generates code that does this, it is always safe to set.
    658     OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
    659   }
    660 
    661   if (TT.isKnownWindowsMSVCEnvironment() && MMI->usesVAFloatArgument()) {
    662     StringRef SymbolName =
    663         (TT.getArch() == Triple::x86_64) ? "_fltused" : "__fltused";
    664     MCSymbol *S = MMI->getContext().getOrCreateSymbol(SymbolName);
    665     OutStreamer->EmitSymbolAttribute(S, MCSA_Global);
    666   }
    667 
    668   if (TT.isOSBinFormatCOFF()) {
    669     const TargetLoweringObjectFileCOFF &TLOFCOFF =
    670         static_cast<const TargetLoweringObjectFileCOFF&>(getObjFileLowering());
    671 
    672     std::string Flags;
    673     raw_string_ostream FlagsOS(Flags);
    674 
    675     for (const auto &Function : M)
    676       TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Function, *Mang);
    677     for (const auto &Global : M.globals())
    678       TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Global, *Mang);
    679     for (const auto &Alias : M.aliases())
    680       TLOFCOFF.emitLinkerFlagsForGlobal(FlagsOS, &Alias, *Mang);
    681 
    682     FlagsOS.flush();
    683 
    684     // Output collected flags.
    685     if (!Flags.empty()) {
    686       OutStreamer->SwitchSection(TLOFCOFF.getDrectveSection());
    687       OutStreamer->EmitBytes(Flags);
    688     }
    689 
    690     SM.serializeToStackMapSection();
    691   }
    692 
    693   if (TT.isOSBinFormatELF()) {
    694     SM.serializeToStackMapSection();
    695     FM.serializeToFaultMapSection();
    696   }
    697 }
    698 
    699 //===----------------------------------------------------------------------===//
    700 // Target Registry Stuff
    701 //===----------------------------------------------------------------------===//
    702 
    703 // Force static initialization.
    704 extern "C" void LLVMInitializeX86AsmPrinter() {
    705   RegisterAsmPrinter<X86AsmPrinter> X(TheX86_32Target);
    706   RegisterAsmPrinter<X86AsmPrinter> Y(TheX86_64Target);
    707 }
    708