X86AsmPrinter.cpp 27 KB

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