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