Home | History | Annotate | Line # | Download | only in X86
      1 //===-- X86AsmPrinter.cpp - Convert X86 LLVM code to AT&T assembly --------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file contains a printer that converts from our internal representation
     10 // of machine-dependent LLVM code to X86 machine code.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "X86AsmPrinter.h"
     15 #include "MCTargetDesc/X86ATTInstPrinter.h"
     16 #include "MCTargetDesc/X86BaseInfo.h"
     17 #include "MCTargetDesc/X86TargetStreamer.h"
     18 #include "TargetInfo/X86TargetInfo.h"
     19 #include "X86InstrInfo.h"
     20 #include "X86MachineFunctionInfo.h"
     21 #include "X86Subtarget.h"
     22 #include "llvm/BinaryFormat/COFF.h"
     23 #include "llvm/BinaryFormat/ELF.h"
     24 #include "llvm/CodeGen/MachineConstantPool.h"
     25 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
     26 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
     27 #include "llvm/IR/DerivedTypes.h"
     28 #include "llvm/IR/InlineAsm.h"
     29 #include "llvm/IR/Mangler.h"
     30 #include "llvm/IR/Module.h"
     31 #include "llvm/IR/Type.h"
     32 #include "llvm/MC/MCCodeEmitter.h"
     33 #include "llvm/MC/MCContext.h"
     34 #include "llvm/MC/MCExpr.h"
     35 #include "llvm/MC/MCSectionCOFF.h"
     36 #include "llvm/MC/MCSectionELF.h"
     37 #include "llvm/MC/MCSectionMachO.h"
     38 #include "llvm/MC/MCStreamer.h"
     39 #include "llvm/MC/MCSymbol.h"
     40 #include "llvm/Support/Debug.h"
     41 #include "llvm/Support/ErrorHandling.h"
     42 #include "llvm/Support/MachineValueType.h"
     43 #include "llvm/Support/TargetRegistry.h"
     44 #include "llvm/Target/TargetMachine.h"
     45 
     46 using namespace llvm;
     47 
     48 X86AsmPrinter::X86AsmPrinter(TargetMachine &TM,
     49                              std::unique_ptr<MCStreamer> Streamer)
     50     : AsmPrinter(TM, std::move(Streamer)), SM(*this), FM(*this) {}
     51 
     52 //===----------------------------------------------------------------------===//
     53 // Primitive Helper Functions.
     54 //===----------------------------------------------------------------------===//
     55 
     56 /// runOnMachineFunction - Emit the function body.
     57 ///
     58 bool X86AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
     59   Subtarget = &MF.getSubtarget<X86Subtarget>();
     60 
     61   SMShadowTracker.startFunction(MF);
     62   CodeEmitter.reset(TM.getTarget().createMCCodeEmitter(
     63       *Subtarget->getInstrInfo(), *Subtarget->getRegisterInfo(),
     64       MF.getContext()));
     65 
     66   EmitFPOData =
     67       Subtarget->isTargetWin32() && MF.getMMI().getModule()->getCodeViewFlag();
     68 
     69   SetupMachineFunction(MF);
     70 
     71   if (Subtarget->isTargetCOFF()) {
     72     bool Local = MF.getFunction().hasLocalLinkage();
     73     OutStreamer->BeginCOFFSymbolDef(CurrentFnSym);
     74     OutStreamer->EmitCOFFSymbolStorageClass(
     75         Local ? COFF::IMAGE_SYM_CLASS_STATIC : COFF::IMAGE_SYM_CLASS_EXTERNAL);
     76     OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_FUNCTION
     77                                                << COFF::SCT_COMPLEX_TYPE_SHIFT);
     78     OutStreamer->EndCOFFSymbolDef();
     79   }
     80 
     81   // Emit the rest of the function body.
     82   emitFunctionBody();
     83 
     84   // Emit the XRay table for this function.
     85   emitXRayTable();
     86 
     87   EmitFPOData = false;
     88 
     89   // We didn't modify anything.
     90   return false;
     91 }
     92 
     93 void X86AsmPrinter::emitFunctionBodyStart() {
     94   if (EmitFPOData) {
     95     if (auto *XTS =
     96         static_cast<X86TargetStreamer *>(OutStreamer->getTargetStreamer()))
     97       XTS->emitFPOProc(
     98           CurrentFnSym,
     99           MF->getInfo<X86MachineFunctionInfo>()->getArgumentStackSize());
    100   }
    101 }
    102 
    103 void X86AsmPrinter::emitFunctionBodyEnd() {
    104   if (EmitFPOData) {
    105     if (auto *XTS =
    106             static_cast<X86TargetStreamer *>(OutStreamer->getTargetStreamer()))
    107       XTS->emitFPOEndProc();
    108   }
    109 }
    110 
    111 /// PrintSymbolOperand - Print a raw symbol reference operand.  This handles
    112 /// jump tables, constant pools, global address and external symbols, all of
    113 /// which print to a label with various suffixes for relocation types etc.
    114 void X86AsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
    115                                        raw_ostream &O) {
    116   switch (MO.getType()) {
    117   default: llvm_unreachable("unknown symbol type!");
    118   case MachineOperand::MO_ConstantPoolIndex:
    119     GetCPISymbol(MO.getIndex())->print(O, MAI);
    120     printOffset(MO.getOffset(), O);
    121     break;
    122   case MachineOperand::MO_GlobalAddress: {
    123     const GlobalValue *GV = MO.getGlobal();
    124 
    125     MCSymbol *GVSym;
    126     if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
    127         MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE)
    128       GVSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
    129     else
    130       GVSym = getSymbolPreferLocal(*GV);
    131 
    132     // Handle dllimport linkage.
    133     if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
    134       GVSym = OutContext.getOrCreateSymbol(Twine("__imp_") + GVSym->getName());
    135     else if (MO.getTargetFlags() == X86II::MO_COFFSTUB)
    136       GVSym =
    137           OutContext.getOrCreateSymbol(Twine(".refptr.") + GVSym->getName());
    138 
    139     if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
    140         MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
    141       MCSymbol *Sym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
    142       MachineModuleInfoImpl::StubValueTy &StubSym =
    143           MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym);
    144       if (!StubSym.getPointer())
    145         StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
    146                                                      !GV->hasInternalLinkage());
    147     }
    148 
    149     // If the name begins with a dollar-sign, enclose it in parens.  We do this
    150     // to avoid having it look like an integer immediate to the assembler.
    151     if (GVSym->getName()[0] != '$')
    152       GVSym->print(O, MAI);
    153     else {
    154       O << '(';
    155       GVSym->print(O, MAI);
    156       O << ')';
    157     }
    158     printOffset(MO.getOffset(), O);
    159     break;
    160   }
    161   }
    162 
    163   switch (MO.getTargetFlags()) {
    164   default:
    165     llvm_unreachable("Unknown target flag on GV operand");
    166   case X86II::MO_NO_FLAG:    // No flag.
    167     break;
    168   case X86II::MO_DARWIN_NONLAZY:
    169   case X86II::MO_DLLIMPORT:
    170   case X86II::MO_COFFSTUB:
    171     // These affect the name of the symbol, not any suffix.
    172     break;
    173   case X86II::MO_GOT_ABSOLUTE_ADDRESS:
    174     O << " + [.-";
    175     MF->getPICBaseSymbol()->print(O, MAI);
    176     O << ']';
    177     break;
    178   case X86II::MO_PIC_BASE_OFFSET:
    179   case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
    180     O << '-';
    181     MF->getPICBaseSymbol()->print(O, MAI);
    182     break;
    183   case X86II::MO_TLSGD:     O << "@TLSGD";     break;
    184   case X86II::MO_TLSLD:     O << "@TLSLD";     break;
    185   case X86II::MO_TLSLDM:    O << "@TLSLDM";    break;
    186   case X86II::MO_GOTTPOFF:  O << "@GOTTPOFF";  break;
    187   case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break;
    188   case X86II::MO_TPOFF:     O << "@TPOFF";     break;
    189   case X86II::MO_DTPOFF:    O << "@DTPOFF";    break;
    190   case X86II::MO_NTPOFF:    O << "@NTPOFF";    break;
    191   case X86II::MO_GOTNTPOFF: O << "@GOTNTPOFF"; break;
    192   case X86II::MO_GOTPCREL:  O << "@GOTPCREL";  break;
    193   case X86II::MO_GOT:       O << "@GOT";       break;
    194   case X86II::MO_GOTOFF:    O << "@GOTOFF";    break;
    195   case X86II::MO_PLT:       O << "@PLT";       break;
    196   case X86II::MO_TLVP:      O << "@TLVP";      break;
    197   case X86II::MO_TLVP_PIC_BASE:
    198     O << "@TLVP" << '-';
    199     MF->getPICBaseSymbol()->print(O, MAI);
    200     break;
    201   case X86II::MO_SECREL:    O << "@SECREL32";  break;
    202   }
    203 }
    204 
    205 void X86AsmPrinter::PrintOperand(const MachineInstr *MI, unsigned OpNo,
    206                                  raw_ostream &O) {
    207   const MachineOperand &MO = MI->getOperand(OpNo);
    208   const bool IsATT = MI->getInlineAsmDialect() == InlineAsm::AD_ATT;
    209   switch (MO.getType()) {
    210   default: llvm_unreachable("unknown operand type!");
    211   case MachineOperand::MO_Register: {
    212     if (IsATT)
    213       O << '%';
    214     O << X86ATTInstPrinter::getRegisterName(MO.getReg());
    215     return;
    216   }
    217 
    218   case MachineOperand::MO_Immediate:
    219     if (IsATT)
    220       O << '$';
    221     O << MO.getImm();
    222     return;
    223 
    224   case MachineOperand::MO_ConstantPoolIndex:
    225   case MachineOperand::MO_GlobalAddress: {
    226     switch (MI->getInlineAsmDialect()) {
    227     case InlineAsm::AD_ATT:
    228       O << '$';
    229       break;
    230     case InlineAsm::AD_Intel:
    231       O << "offset ";
    232       break;
    233     }
    234     PrintSymbolOperand(MO, O);
    235     break;
    236   }
    237   case MachineOperand::MO_BlockAddress: {
    238     MCSymbol *Sym = GetBlockAddressSymbol(MO.getBlockAddress());
    239     Sym->print(O, MAI);
    240     break;
    241   }
    242   }
    243 }
    244 
    245 /// PrintModifiedOperand - Print subregisters based on supplied modifier,
    246 /// deferring to PrintOperand() if no modifier was supplied or if operand is not
    247 /// a register.
    248 void X86AsmPrinter::PrintModifiedOperand(const MachineInstr *MI, unsigned OpNo,
    249                                          raw_ostream &O, const char *Modifier) {
    250   const MachineOperand &MO = MI->getOperand(OpNo);
    251   if (!Modifier || MO.getType() != MachineOperand::MO_Register)
    252     return PrintOperand(MI, OpNo, O);
    253   if (MI->getInlineAsmDialect() == InlineAsm::AD_ATT)
    254     O << '%';
    255   Register Reg = MO.getReg();
    256   if (strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
    257     unsigned Size = (strcmp(Modifier+6,"64") == 0) ? 64 :
    258         (strcmp(Modifier+6,"32") == 0) ? 32 :
    259         (strcmp(Modifier+6,"16") == 0) ? 16 : 8;
    260     Reg = getX86SubSuperRegister(Reg, Size);
    261   }
    262   O << X86ATTInstPrinter::getRegisterName(Reg);
    263 }
    264 
    265 /// PrintPCRelImm - This is used to print an immediate value that ends up
    266 /// being encoded as a pc-relative value.  These print slightly differently, for
    267 /// example, a $ is not emitted.
    268 void X86AsmPrinter::PrintPCRelImm(const MachineInstr *MI, unsigned OpNo,
    269                                   raw_ostream &O) {
    270   const MachineOperand &MO = MI->getOperand(OpNo);
    271   switch (MO.getType()) {
    272   default: llvm_unreachable("Unknown pcrel immediate operand");
    273   case MachineOperand::MO_Register:
    274     // pc-relativeness was handled when computing the value in the reg.
    275     PrintOperand(MI, OpNo, O);
    276     return;
    277   case MachineOperand::MO_Immediate:
    278     O << MO.getImm();
    279     return;
    280   case MachineOperand::MO_GlobalAddress:
    281     PrintSymbolOperand(MO, O);
    282     return;
    283   }
    284 }
    285 
    286 void X86AsmPrinter::PrintLeaMemReference(const MachineInstr *MI, unsigned OpNo,
    287                                          raw_ostream &O, const char *Modifier) {
    288   const MachineOperand &BaseReg = MI->getOperand(OpNo + X86::AddrBaseReg);
    289   const MachineOperand &IndexReg = MI->getOperand(OpNo + X86::AddrIndexReg);
    290   const MachineOperand &DispSpec = MI->getOperand(OpNo + X86::AddrDisp);
    291 
    292   // If we really don't want to print out (rip), don't.
    293   bool HasBaseReg = BaseReg.getReg() != 0;
    294   if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") &&
    295       BaseReg.getReg() == X86::RIP)
    296     HasBaseReg = false;
    297 
    298   // HasParenPart - True if we will print out the () part of the mem ref.
    299   bool HasParenPart = IndexReg.getReg() || HasBaseReg;
    300 
    301   switch (DispSpec.getType()) {
    302   default:
    303     llvm_unreachable("unknown operand type!");
    304   case MachineOperand::MO_Immediate: {
    305     int DispVal = DispSpec.getImm();
    306     if (DispVal || !HasParenPart)
    307       O << DispVal;
    308     break;
    309   }
    310   case MachineOperand::MO_GlobalAddress:
    311   case MachineOperand::MO_ConstantPoolIndex:
    312     PrintSymbolOperand(DispSpec, O);
    313     break;
    314   }
    315 
    316   if (Modifier && strcmp(Modifier, "H") == 0)
    317     O << "+8";
    318 
    319   if (HasParenPart) {
    320     assert(IndexReg.getReg() != X86::ESP &&
    321            "X86 doesn't allow scaling by ESP");
    322 
    323     O << '(';
    324     if (HasBaseReg)
    325       PrintModifiedOperand(MI, OpNo + X86::AddrBaseReg, O, Modifier);
    326 
    327     if (IndexReg.getReg()) {
    328       O << ',';
    329       PrintModifiedOperand(MI, OpNo + X86::AddrIndexReg, O, Modifier);
    330       unsigned ScaleVal = MI->getOperand(OpNo + X86::AddrScaleAmt).getImm();
    331       if (ScaleVal != 1)
    332         O << ',' << ScaleVal;
    333     }
    334     O << ')';
    335   }
    336 }
    337 
    338 void X86AsmPrinter::PrintMemReference(const MachineInstr *MI, unsigned OpNo,
    339                                       raw_ostream &O, const char *Modifier) {
    340   assert(isMem(*MI, OpNo) && "Invalid memory reference!");
    341   const MachineOperand &Segment = MI->getOperand(OpNo + X86::AddrSegmentReg);
    342   if (Segment.getReg()) {
    343     PrintModifiedOperand(MI, OpNo + X86::AddrSegmentReg, O, Modifier);
    344     O << ':';
    345   }
    346   PrintLeaMemReference(MI, OpNo, O, Modifier);
    347 }
    348 
    349 
    350 void X86AsmPrinter::PrintIntelMemReference(const MachineInstr *MI,
    351                                            unsigned OpNo, raw_ostream &O,
    352                                            const char *Modifier) {
    353   const MachineOperand &BaseReg = MI->getOperand(OpNo + X86::AddrBaseReg);
    354   unsigned ScaleVal = MI->getOperand(OpNo + X86::AddrScaleAmt).getImm();
    355   const MachineOperand &IndexReg = MI->getOperand(OpNo + X86::AddrIndexReg);
    356   const MachineOperand &DispSpec = MI->getOperand(OpNo + X86::AddrDisp);
    357   const MachineOperand &SegReg = MI->getOperand(OpNo + X86::AddrSegmentReg);
    358 
    359   // If we really don't want to print out (rip), don't.
    360   bool HasBaseReg = BaseReg.getReg() != 0;
    361   if (HasBaseReg && Modifier && !strcmp(Modifier, "no-rip") &&
    362       BaseReg.getReg() == X86::RIP)
    363     HasBaseReg = false;
    364 
    365   // If this has a segment register, print it.
    366   if (SegReg.getReg()) {
    367     PrintOperand(MI, OpNo + X86::AddrSegmentReg, O);
    368     O << ':';
    369   }
    370 
    371   O << '[';
    372 
    373   bool NeedPlus = false;
    374   if (HasBaseReg) {
    375     PrintOperand(MI, OpNo + X86::AddrBaseReg, O);
    376     NeedPlus = true;
    377   }
    378 
    379   if (IndexReg.getReg()) {
    380     if (NeedPlus) O << " + ";
    381     if (ScaleVal != 1)
    382       O << ScaleVal << '*';
    383     PrintOperand(MI, OpNo + X86::AddrIndexReg, O);
    384     NeedPlus = true;
    385   }
    386 
    387   if (!DispSpec.isImm()) {
    388     if (NeedPlus) O << " + ";
    389     PrintOperand(MI, OpNo + X86::AddrDisp, O);
    390   } else {
    391     int64_t DispVal = DispSpec.getImm();
    392     if (DispVal || (!IndexReg.getReg() && !HasBaseReg)) {
    393       if (NeedPlus) {
    394         if (DispVal > 0)
    395           O << " + ";
    396         else {
    397           O << " - ";
    398           DispVal = -DispVal;
    399         }
    400       }
    401       O << DispVal;
    402     }
    403   }
    404   O << ']';
    405 }
    406 
    407 static bool printAsmMRegister(const X86AsmPrinter &P, const MachineOperand &MO,
    408                               char Mode, raw_ostream &O) {
    409   Register Reg = MO.getReg();
    410   bool EmitPercent = MO.getParent()->getInlineAsmDialect() == InlineAsm::AD_ATT;
    411 
    412   if (!X86::GR8RegClass.contains(Reg) &&
    413       !X86::GR16RegClass.contains(Reg) &&
    414       !X86::GR32RegClass.contains(Reg) &&
    415       !X86::GR64RegClass.contains(Reg))
    416     return true;
    417 
    418   switch (Mode) {
    419   default: return true;  // Unknown mode.
    420   case 'b': // Print QImode register
    421     Reg = getX86SubSuperRegister(Reg, 8);
    422     break;
    423   case 'h': // Print QImode high register
    424     Reg = getX86SubSuperRegister(Reg, 8, true);
    425     break;
    426   case 'w': // Print HImode register
    427     Reg = getX86SubSuperRegister(Reg, 16);
    428     break;
    429   case 'k': // Print SImode register
    430     Reg = getX86SubSuperRegister(Reg, 32);
    431     break;
    432   case 'V':
    433     EmitPercent = false;
    434     LLVM_FALLTHROUGH;
    435   case 'q':
    436     // Print 64-bit register names if 64-bit integer registers are available.
    437     // Otherwise, print 32-bit register names.
    438     Reg = getX86SubSuperRegister(Reg, P.getSubtarget().is64Bit() ? 64 : 32);
    439     break;
    440   }
    441 
    442   if (EmitPercent)
    443     O << '%';
    444 
    445   O << X86ATTInstPrinter::getRegisterName(Reg);
    446   return false;
    447 }
    448 
    449 static bool printAsmVRegister(const MachineOperand &MO, char Mode,
    450                               raw_ostream &O) {
    451   Register Reg = MO.getReg();
    452   bool EmitPercent = MO.getParent()->getInlineAsmDialect() == InlineAsm::AD_ATT;
    453 
    454   unsigned Index;
    455   if (X86::VR128XRegClass.contains(Reg))
    456     Index = Reg - X86::XMM0;
    457   else if (X86::VR256XRegClass.contains(Reg))
    458     Index = Reg - X86::YMM0;
    459   else if (X86::VR512RegClass.contains(Reg))
    460     Index = Reg - X86::ZMM0;
    461   else
    462     return true;
    463 
    464   switch (Mode) {
    465   default: // Unknown mode.
    466     return true;
    467   case 'x': // Print V4SFmode register
    468     Reg = X86::XMM0 + Index;
    469     break;
    470   case 't': // Print V8SFmode register
    471     Reg = X86::YMM0 + Index;
    472     break;
    473   case 'g': // Print V16SFmode register
    474     Reg = X86::ZMM0 + Index;
    475     break;
    476   }
    477 
    478   if (EmitPercent)
    479     O << '%';
    480 
    481   O << X86ATTInstPrinter::getRegisterName(Reg);
    482   return false;
    483 }
    484 
    485 /// PrintAsmOperand - Print out an operand for an inline asm expression.
    486 ///
    487 bool X86AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
    488                                     const char *ExtraCode, raw_ostream &O) {
    489   // Does this asm operand have a single letter operand modifier?
    490   if (ExtraCode && ExtraCode[0]) {
    491     if (ExtraCode[1] != 0) return true; // Unknown modifier.
    492 
    493     const MachineOperand &MO = MI->getOperand(OpNo);
    494 
    495     switch (ExtraCode[0]) {
    496     default:
    497       // See if this is a generic print operand
    498       return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
    499     case 'a': // This is an address.  Currently only 'i' and 'r' are expected.
    500       switch (MO.getType()) {
    501       default:
    502         return true;
    503       case MachineOperand::MO_Immediate:
    504         O << MO.getImm();
    505         return false;
    506       case MachineOperand::MO_ConstantPoolIndex:
    507       case MachineOperand::MO_JumpTableIndex:
    508       case MachineOperand::MO_ExternalSymbol:
    509         llvm_unreachable("unexpected operand type!");
    510       case MachineOperand::MO_GlobalAddress:
    511         PrintSymbolOperand(MO, O);
    512         if (Subtarget->isPICStyleRIPRel())
    513           O << "(%rip)";
    514         return false;
    515       case MachineOperand::MO_Register:
    516         O << '(';
    517         PrintOperand(MI, OpNo, O);
    518         O << ')';
    519         return false;
    520       }
    521 
    522     case 'c': // Don't print "$" before a global var name or constant.
    523       switch (MO.getType()) {
    524       default:
    525         PrintOperand(MI, OpNo, O);
    526         break;
    527       case MachineOperand::MO_Immediate:
    528         O << MO.getImm();
    529         break;
    530       case MachineOperand::MO_ConstantPoolIndex:
    531       case MachineOperand::MO_JumpTableIndex:
    532       case MachineOperand::MO_ExternalSymbol:
    533         llvm_unreachable("unexpected operand type!");
    534       case MachineOperand::MO_GlobalAddress:
    535         PrintSymbolOperand(MO, O);
    536         break;
    537       }
    538       return false;
    539 
    540     case 'A': // Print '*' before a register (it must be a register)
    541       if (MO.isReg()) {
    542         O << '*';
    543         PrintOperand(MI, OpNo, O);
    544         return false;
    545       }
    546       return true;
    547 
    548     case 'b': // Print QImode register
    549     case 'h': // Print QImode high register
    550     case 'w': // Print HImode register
    551     case 'k': // Print SImode register
    552     case 'q': // Print DImode register
    553     case 'V': // Print native register without '%'
    554       if (MO.isReg())
    555         return printAsmMRegister(*this, MO, ExtraCode[0], O);
    556       PrintOperand(MI, OpNo, O);
    557       return false;
    558 
    559     case 'x': // Print V4SFmode register
    560     case 't': // Print V8SFmode register
    561     case 'g': // Print V16SFmode register
    562       if (MO.isReg())
    563         return printAsmVRegister(MO, ExtraCode[0], O);
    564       PrintOperand(MI, OpNo, O);
    565       return false;
    566 
    567     case 'P': // This is the operand of a call, treat specially.
    568       PrintPCRelImm(MI, OpNo, O);
    569       return false;
    570 
    571     case 'n': // Negate the immediate or print a '-' before the operand.
    572       // Note: this is a temporary solution. It should be handled target
    573       // independently as part of the 'MC' work.
    574       if (MO.isImm()) {
    575         O << -MO.getImm();
    576         return false;
    577       }
    578       O << '-';
    579     }
    580   }
    581 
    582   PrintOperand(MI, OpNo, O);
    583   return false;
    584 }
    585 
    586 bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
    587                                           const char *ExtraCode,
    588                                           raw_ostream &O) {
    589   if (ExtraCode && ExtraCode[0]) {
    590     if (ExtraCode[1] != 0) return true; // Unknown modifier.
    591 
    592     switch (ExtraCode[0]) {
    593     default: return true;  // Unknown modifier.
    594     case 'b': // Print QImode register
    595     case 'h': // Print QImode high register
    596     case 'w': // Print HImode register
    597     case 'k': // Print SImode register
    598     case 'q': // Print SImode register
    599       // These only apply to registers, ignore on mem.
    600       break;
    601     case 'H':
    602       if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
    603         return true;  // Unsupported modifier in Intel inline assembly.
    604       } else {
    605         PrintMemReference(MI, OpNo, O, "H");
    606       }
    607       return false;
    608     case 'P': // Don't print @PLT, but do print as memory.
    609       if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
    610         PrintIntelMemReference(MI, OpNo, O, "no-rip");
    611       } else {
    612         PrintMemReference(MI, OpNo, O, "no-rip");
    613       }
    614       return false;
    615     }
    616   }
    617   if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
    618     PrintIntelMemReference(MI, OpNo, O, nullptr);
    619   } else {
    620     PrintMemReference(MI, OpNo, O, nullptr);
    621   }
    622   return false;
    623 }
    624 
    625 void X86AsmPrinter::emitStartOfAsmFile(Module &M) {
    626   const Triple &TT = TM.getTargetTriple();
    627 
    628   if (TT.isOSBinFormatELF()) {
    629     // Assemble feature flags that may require creation of a note section.
    630     unsigned FeatureFlagsAnd = 0;
    631     if (M.getModuleFlag("cf-protection-branch"))
    632       FeatureFlagsAnd |= ELF::GNU_PROPERTY_X86_FEATURE_1_IBT;
    633     if (M.getModuleFlag("cf-protection-return"))
    634       FeatureFlagsAnd |= ELF::GNU_PROPERTY_X86_FEATURE_1_SHSTK;
    635 
    636     if (FeatureFlagsAnd) {
    637       // Emit a .note.gnu.property section with the flags.
    638       if (!TT.isArch32Bit() && !TT.isArch64Bit())
    639         llvm_unreachable("CFProtection used on invalid architecture!");
    640       MCSection *Cur = OutStreamer->getCurrentSectionOnly();
    641       MCSection *Nt = MMI->getContext().getELFSection(
    642           ".note.gnu.property", ELF::SHT_NOTE, ELF::SHF_ALLOC);
    643       OutStreamer->SwitchSection(Nt);
    644 
    645       // Emitting note header.
    646       const int WordSize =
    647           TT.isArch64Bit() && TT.getEnvironment() != Triple::GNUX32 ? 8 : 4;
    648       emitAlignment(WordSize == 4 ? Align(4) : Align(8));
    649       OutStreamer->emitIntValue(4, 4 /*size*/); // data size for "GNU\0"
    650       OutStreamer->emitIntValue(8 + WordSize, 4 /*size*/); // Elf_Prop size
    651       OutStreamer->emitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4 /*size*/);
    652       OutStreamer->emitBytes(StringRef("GNU", 4)); // note name
    653 
    654       // Emitting an Elf_Prop for the CET properties.
    655       OutStreamer->emitInt32(ELF::GNU_PROPERTY_X86_FEATURE_1_AND);
    656       OutStreamer->emitInt32(4);                          // data size
    657       OutStreamer->emitInt32(FeatureFlagsAnd);            // data
    658       emitAlignment(WordSize == 4 ? Align(4) : Align(8)); // padding
    659 
    660       OutStreamer->endSection(Nt);
    661       OutStreamer->SwitchSection(Cur);
    662     }
    663   }
    664 
    665   if (TT.isOSBinFormatMachO())
    666     OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
    667 
    668   if (TT.isOSBinFormatCOFF()) {
    669     // Emit an absolute @feat.00 symbol.  This appears to be some kind of
    670     // compiler features bitfield read by link.exe.
    671     MCSymbol *S = MMI->getContext().getOrCreateSymbol(StringRef("@feat.00"));
    672     OutStreamer->BeginCOFFSymbolDef(S);
    673     OutStreamer->EmitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
    674     OutStreamer->EmitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);
    675     OutStreamer->EndCOFFSymbolDef();
    676     int64_t Feat00Flags = 0;
    677 
    678     if (TT.getArch() == Triple::x86) {
    679       // According to the PE-COFF spec, the LSB of this value marks the object
    680       // for "registered SEH".  This means that all SEH handler entry points
    681       // must be registered in .sxdata.  Use of any unregistered handlers will
    682       // cause the process to terminate immediately.  LLVM does not know how to
    683       // register any SEH handlers, so its object files should be safe.
    684       Feat00Flags |= 1;
    685     }
    686 
    687     if (M.getModuleFlag("cfguard")) {
    688       Feat00Flags |= 0x800; // Object is CFG-aware.
    689     }
    690 
    691     if (M.getModuleFlag("ehcontguard")) {
    692       Feat00Flags |= 0x4000; // Object also has EHCont.
    693     }
    694 
    695     OutStreamer->emitSymbolAttribute(S, MCSA_Global);
    696     OutStreamer->emitAssignment(
    697         S, MCConstantExpr::create(Feat00Flags, MMI->getContext()));
    698   }
    699   OutStreamer->emitSyntaxDirective();
    700 
    701   // If this is not inline asm and we're in 16-bit
    702   // mode prefix assembly with .code16.
    703   bool is16 = TT.getEnvironment() == Triple::CODE16;
    704   if (M.getModuleInlineAsm().empty() && is16)
    705     OutStreamer->emitAssemblerFlag(MCAF_Code16);
    706 }
    707 
    708 static void
    709 emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel,
    710                          MachineModuleInfoImpl::StubValueTy &MCSym) {
    711   // L_foo$stub:
    712   OutStreamer.emitLabel(StubLabel);
    713   //   .indirect_symbol _foo
    714   OutStreamer.emitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol);
    715 
    716   if (MCSym.getInt())
    717     // External to current translation unit.
    718     OutStreamer.emitIntValue(0, 4/*size*/);
    719   else
    720     // Internal to current translation unit.
    721     //
    722     // When we place the LSDA into the TEXT section, the type info
    723     // pointers need to be indirect and pc-rel. We accomplish this by
    724     // using NLPs; however, sometimes the types are local to the file.
    725     // We need to fill in the value for the NLP in those cases.
    726     OutStreamer.emitValue(
    727         MCSymbolRefExpr::create(MCSym.getPointer(), OutStreamer.getContext()),
    728         4 /*size*/);
    729 }
    730 
    731 static void emitNonLazyStubs(MachineModuleInfo *MMI, MCStreamer &OutStreamer) {
    732 
    733   MachineModuleInfoMachO &MMIMacho =
    734       MMI->getObjFileInfo<MachineModuleInfoMachO>();
    735 
    736   // Output stubs for dynamically-linked functions.
    737   MachineModuleInfoMachO::SymbolListTy Stubs;
    738 
    739   // Output stubs for external and common global variables.
    740   Stubs = MMIMacho.GetGVStubList();
    741   if (!Stubs.empty()) {
    742     OutStreamer.SwitchSection(MMI->getContext().getMachOSection(
    743         "__IMPORT", "__pointers", MachO::S_NON_LAZY_SYMBOL_POINTERS,
    744         SectionKind::getMetadata()));
    745 
    746     for (auto &Stub : Stubs)
    747       emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second);
    748 
    749     Stubs.clear();
    750     OutStreamer.AddBlankLine();
    751   }
    752 }
    753 
    754 void X86AsmPrinter::emitEndOfAsmFile(Module &M) {
    755   const Triple &TT = TM.getTargetTriple();
    756 
    757   if (TT.isOSBinFormatMachO()) {
    758     // Mach-O uses non-lazy symbol stubs to encode per-TU information into
    759     // global table for symbol lookup.
    760     emitNonLazyStubs(MMI, *OutStreamer);
    761 
    762     // Emit stack and fault map information.
    763     emitStackMaps(SM);
    764     FM.serializeToFaultMapSection();
    765 
    766     // This flag tells the linker that no global symbols contain code that fall
    767     // through to other global symbols (e.g. an implementation of multiple entry
    768     // points). If this doesn't occur, the linker can safely perform dead code
    769     // stripping. Since LLVM never generates code that does this, it is always
    770     // safe to set.
    771     OutStreamer->emitAssemblerFlag(MCAF_SubsectionsViaSymbols);
    772   } else if (TT.isOSBinFormatCOFF()) {
    773     if (MMI->usesMSVCFloatingPoint()) {
    774       // In Windows' libcmt.lib, there is a file which is linked in only if the
    775       // symbol _fltused is referenced. Linking this in causes some
    776       // side-effects:
    777       //
    778       // 1. For x86-32, it will set the x87 rounding mode to 53-bit instead of
    779       // 64-bit mantissas at program start.
    780       //
    781       // 2. It links in support routines for floating-point in scanf and printf.
    782       //
    783       // MSVC emits an undefined reference to _fltused when there are any
    784       // floating point operations in the program (including calls). A program
    785       // that only has: `scanf("%f", &global_float);` may fail to trigger this,
    786       // but oh well...that's a documented issue.
    787       StringRef SymbolName =
    788           (TT.getArch() == Triple::x86) ? "__fltused" : "_fltused";
    789       MCSymbol *S = MMI->getContext().getOrCreateSymbol(SymbolName);
    790       OutStreamer->emitSymbolAttribute(S, MCSA_Global);
    791       return;
    792     }
    793     emitStackMaps(SM);
    794   } else if (TT.isOSBinFormatELF()) {
    795     emitStackMaps(SM);
    796     FM.serializeToFaultMapSection();
    797   }
    798 }
    799 
    800 //===----------------------------------------------------------------------===//
    801 // Target Registry Stuff
    802 //===----------------------------------------------------------------------===//
    803 
    804 // Force static initialization.
    805 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86AsmPrinter() {
    806   RegisterAsmPrinter<X86AsmPrinter> X(getTheX86_32Target());
    807   RegisterAsmPrinter<X86AsmPrinter> Y(getTheX86_64Target());
    808 }
    809