LLVM 22.0.0git
X86AsmPrinter.cpp
Go to the documentation of this file.
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"
20#include "X86.h"
21#include "X86InstrInfo.h"
23#include "X86Subtarget.h"
24#include "llvm-c/Visibility.h"
33#include "llvm/IR/InlineAsm.h"
35#include "llvm/IR/Mangler.h"
36#include "llvm/IR/Module.h"
37#include "llvm/IR/Type.h"
38#include "llvm/MC/MCAsmInfo.h"
40#include "llvm/MC/MCContext.h"
41#include "llvm/MC/MCExpr.h"
42#include "llvm/MC/MCInst.h"
47#include "llvm/MC/MCStreamer.h"
48#include "llvm/MC/MCSymbol.h"
50#include "llvm/Support/Debug.h"
53
54using namespace llvm;
55
57 std::unique_ptr<MCStreamer> Streamer)
58 : AsmPrinter(TM, std::move(Streamer), ID), FM(*this) {}
59
60//===----------------------------------------------------------------------===//
61// Primitive Helper Functions.
62//===----------------------------------------------------------------------===//
63
64/// runOnMachineFunction - Emit the function body.
65///
67 if (auto *PSIW = getAnalysisIfAvailable<ProfileSummaryInfoWrapperPass>())
68 PSI = &PSIW->getPSI();
69 if (auto *SDPIW = getAnalysisIfAvailable<StaticDataProfileInfoWrapperPass>())
70 SDPI = &SDPIW->getStaticDataProfileInfo();
71
72 Subtarget = &MF.getSubtarget<X86Subtarget>();
73
74 SMShadowTracker.startFunction(MF);
75 CodeEmitter.reset(TM.getTarget().createMCCodeEmitter(
76 *Subtarget->getInstrInfo(), MF.getContext()));
77
78 const Module *M = MF.getFunction().getParent();
79 EmitFPOData = Subtarget->isTargetWin32() && M->getCodeViewFlag();
80
81 IndCSPrefix = M->getModuleFlag("indirect_branch_cs_prefix");
82
84
85 if (Subtarget->isTargetCOFF()) {
87 OutStreamer->beginCOFFSymbolDef(CurrentFnSym);
88 OutStreamer->emitCOFFSymbolStorageClass(
92 OutStreamer->endCOFFSymbolDef();
93 }
94
95 // Emit the rest of the function body.
97
98 // Emit the XRay table for this function.
100
101 EmitFPOData = false;
102
103 IndCSPrefix = false;
104
105 // We didn't modify anything.
106 return false;
107}
108
110 if (EmitFPOData) {
111 auto *XTS =
112 static_cast<X86TargetStreamer *>(OutStreamer->getTargetStreamer());
113 XTS->emitFPOProc(
116 }
117}
118
120 if (EmitFPOData) {
121 auto *XTS =
122 static_cast<X86TargetStreamer *>(OutStreamer->getTargetStreamer());
123 XTS->emitFPOEndProc();
124 }
125}
126
127uint32_t X86AsmPrinter::MaskKCFIType(uint32_t Value) {
128 // If the type hash matches an invalid pattern, mask the value.
129 const uint32_t InvalidValues[] = {
130 0xFA1E0FF3, /* ENDBR64 */
131 0xFB1E0FF3, /* ENDBR32 */
132 };
133 for (uint32_t N : InvalidValues) {
134 // LowerKCFI_CHECK emits -Value for indirect call checks, so we must also
135 // mask that. Note that -(Value + 1) == ~Value.
136 if (N == Value || -N == Value)
137 return Value + 1;
138 }
139 return Value;
140}
141
142void X86AsmPrinter::EmitKCFITypePadding(const MachineFunction &MF,
143 bool HasType) {
144 // Keep the function entry aligned, taking patchable-function-prefix into
145 // account if set.
146 int64_t PrefixBytes = 0;
147 (void)MF.getFunction()
148 .getFnAttribute("patchable-function-prefix")
150 .getAsInteger(10, PrefixBytes);
151
152 // Also take the type identifier into account if we're emitting
153 // one. Otherwise, just pad with nops. The X86::MOV32ri instruction emitted
154 // in X86AsmPrinter::emitKCFITypeId is 5 bytes long.
155 if (HasType)
156 PrefixBytes += 5;
157
158 emitNops(offsetToAlignment(PrefixBytes, MF.getAlignment()));
159}
160
161/// emitKCFITypeId - Emit the KCFI type information in architecture specific
162/// format.
164 const Function &F = MF.getFunction();
165 if (!F.getParent()->getModuleFlag("kcfi"))
166 return;
167
168 ConstantInt *Type = nullptr;
169 if (const MDNode *MD = F.getMetadata(LLVMContext::MD_kcfi_type))
170 Type = mdconst::extract<ConstantInt>(MD->getOperand(0));
171
172 // If we don't have a type to emit, just emit padding if needed to maintain
173 // the same alignment for all functions.
174 if (!Type) {
175 EmitKCFITypePadding(MF, /*HasType=*/false);
176 return;
177 }
178
179 // Emit a function symbol for the type data to avoid unreachable instruction
180 // warnings from binary validation tools, and use the same linkage as the
181 // parent function. Note that using local linkage would result in duplicate
182 // symbols for weak parent functions.
183 MCSymbol *FnSym = OutContext.getOrCreateSymbol("__cfi_" + MF.getName());
184 emitLinkage(&MF.getFunction(), FnSym);
186 OutStreamer->emitSymbolAttribute(FnSym, MCSA_ELF_TypeFunction);
187 OutStreamer->emitLabel(FnSym);
188
189 // Embed the type hash in the X86::MOV32ri instruction to avoid special
190 // casing object file parsers.
191 EmitKCFITypePadding(MF);
192 unsigned DestReg = X86::EAX;
193
194 if (F.getParent()->getModuleFlag("kcfi-arity")) {
195 // The ArityToRegMap assumes the 64-bit SysV ABI.
196 [[maybe_unused]] const auto &Triple = MF.getTarget().getTargetTriple();
198
199 // Determine the function's arity (i.e., the number of arguments) at the ABI
200 // level by counting the number of parameters that are passed
201 // as registers, such as pointers and 64-bit (or smaller) integers. The
202 // Linux x86-64 ABI allows up to 6 integer parameters to be passed in GPRs.
203 // Additional parameters or parameters larger than 64 bits may be passed on
204 // the stack, in which case the arity is denoted as 7. Floating-point
205 // arguments passed in XMM0-XMM7 are not counted toward arity because
206 // floating-point values are not relevant to enforcing kCFI at this time.
207 const unsigned ArityToRegMap[8] = {X86::EAX, X86::ECX, X86::EDX, X86::EBX,
208 X86::ESP, X86::EBP, X86::ESI, X86::EDI};
209 int Arity;
211 Arity = 7;
212 } else {
213 Arity = 0;
214 for (const auto &LI : MF.getRegInfo().liveins()) {
215 auto Reg = LI.first;
216 if (X86::GR8RegClass.contains(Reg) || X86::GR16RegClass.contains(Reg) ||
217 X86::GR32RegClass.contains(Reg) ||
218 X86::GR64RegClass.contains(Reg)) {
219 ++Arity;
220 }
221 }
222 }
223 DestReg = ArityToRegMap[Arity];
224 }
225
226 EmitAndCountInstruction(MCInstBuilder(X86::MOV32ri)
227 .addReg(DestReg)
228 .addImm(MaskKCFIType(Type->getZExtValue())));
229
231 MCSymbol *EndSym = OutContext.createTempSymbol("cfi_func_end");
232 OutStreamer->emitLabel(EndSym);
233
234 const MCExpr *SizeExp = MCBinaryExpr::createSub(
237 OutStreamer->emitELFSize(FnSym, SizeExp);
238 }
239}
240
241/// PrintSymbolOperand - Print a raw symbol reference operand. This handles
242/// jump tables, constant pools, global address and external symbols, all of
243/// which print to a label with various suffixes for relocation types etc.
244void X86AsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
245 raw_ostream &O) {
246 switch (MO.getType()) {
247 default: llvm_unreachable("unknown symbol type!");
249 GetCPISymbol(MO.getIndex())->print(O, MAI);
250 printOffset(MO.getOffset(), O);
251 break;
253 const GlobalValue *GV = MO.getGlobal();
254
255 MCSymbol *GVSym;
258 GVSym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
259 else
260 GVSym = getSymbolPreferLocal(*GV);
261
262 // Handle dllimport linkage.
264 GVSym = OutContext.getOrCreateSymbol(Twine("__imp_") + GVSym->getName());
265 else if (MO.getTargetFlags() == X86II::MO_COFFSTUB)
266 GVSym =
267 OutContext.getOrCreateSymbol(Twine(".refptr.") + GVSym->getName());
268
271 MCSymbol *Sym = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
273 MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(Sym);
274 if (!StubSym.getPointer())
276 !GV->hasInternalLinkage());
277 }
278
279 // If the name begins with a dollar-sign, enclose it in parens. We do this
280 // to avoid having it look like an integer immediate to the assembler.
281 if (GVSym->getName()[0] != '$')
282 GVSym->print(O, MAI);
283 else {
284 O << '(';
285 GVSym->print(O, MAI);
286 O << ')';
287 }
288 printOffset(MO.getOffset(), O);
289 break;
290 }
291 }
292
293 switch (MO.getTargetFlags()) {
294 default:
295 llvm_unreachable("Unknown target flag on GV operand");
296 case X86II::MO_NO_FLAG: // No flag.
297 break;
301 // These affect the name of the symbol, not any suffix.
302 break;
304 O << " + [.-";
306 O << ']';
307 break;
310 O << '-';
312 break;
313 case X86II::MO_TLSGD: O << "@TLSGD"; break;
314 case X86II::MO_TLSLD: O << "@TLSLD"; break;
315 case X86II::MO_TLSLDM: O << "@TLSLDM"; break;
316 case X86II::MO_GOTTPOFF: O << "@GOTTPOFF"; break;
317 case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break;
318 case X86II::MO_TPOFF: O << "@TPOFF"; break;
319 case X86II::MO_DTPOFF: O << "@DTPOFF"; break;
320 case X86II::MO_NTPOFF: O << "@NTPOFF"; break;
321 case X86II::MO_GOTNTPOFF: O << "@GOTNTPOFF"; break;
322 case X86II::MO_GOTPCREL: O << "@GOTPCREL"; break;
323 case X86II::MO_GOTPCREL_NORELAX: O << "@GOTPCREL_NORELAX"; break;
324 case X86II::MO_GOT: O << "@GOT"; break;
325 case X86II::MO_GOTOFF: O << "@GOTOFF"; break;
326 case X86II::MO_PLT: O << "@PLT"; break;
327 case X86II::MO_TLVP: O << "@TLVP"; break;
329 O << "@TLVP" << '-';
331 break;
332 case X86II::MO_SECREL: O << "@SECREL32"; break;
333 }
334}
335
336void X86AsmPrinter::PrintOperand(const MachineInstr *MI, unsigned OpNo,
337 raw_ostream &O) {
338 const MachineOperand &MO = MI->getOperand(OpNo);
339 const bool IsATT = MI->getInlineAsmDialect() == InlineAsm::AD_ATT;
340 switch (MO.getType()) {
341 default: llvm_unreachable("unknown operand type!");
343 if (IsATT)
344 O << '%';
346 return;
347 }
348
350 if (IsATT)
351 O << '$';
352 O << MO.getImm();
353 return;
354
357 switch (MI->getInlineAsmDialect()) {
359 O << '$';
360 break;
362 O << "offset ";
363 break;
364 }
365 PrintSymbolOperand(MO, O);
366 break;
367 }
370 Sym->print(O, MAI);
371 break;
372 }
373 }
374}
375
376/// PrintModifiedOperand - Print subregisters based on supplied modifier,
377/// deferring to PrintOperand() if no modifier was supplied or if operand is not
378/// a register.
379void X86AsmPrinter::PrintModifiedOperand(const MachineInstr *MI, unsigned OpNo,
380 raw_ostream &O, StringRef Modifier) {
381 const MachineOperand &MO = MI->getOperand(OpNo);
382 if (Modifier.empty() || !MO.isReg())
383 return PrintOperand(MI, OpNo, O);
384 if (MI->getInlineAsmDialect() == InlineAsm::AD_ATT)
385 O << '%';
386 Register Reg = MO.getReg();
387 if (Modifier.consume_front("subreg")) {
388 unsigned Size = (Modifier == "64") ? 64
389 : (Modifier == "32") ? 32
390 : (Modifier == "16") ? 16
391 : 8;
393 }
395}
396
397/// PrintPCRelImm - This is used to print an immediate value that ends up
398/// being encoded as a pc-relative value. These print slightly differently, for
399/// example, a $ is not emitted.
400void X86AsmPrinter::PrintPCRelImm(const MachineInstr *MI, unsigned OpNo,
401 raw_ostream &O) {
402 const MachineOperand &MO = MI->getOperand(OpNo);
403 switch (MO.getType()) {
404 default: llvm_unreachable("Unknown pcrel immediate operand");
406 // pc-relativeness was handled when computing the value in the reg.
407 PrintOperand(MI, OpNo, O);
408 return;
410 O << MO.getImm();
411 return;
413 PrintSymbolOperand(MO, O);
414 return;
415 }
416}
417
418void X86AsmPrinter::PrintLeaMemReference(const MachineInstr *MI, unsigned OpNo,
419 raw_ostream &O, StringRef Modifier) {
420 const MachineOperand &BaseReg = MI->getOperand(OpNo + X86::AddrBaseReg);
421 const MachineOperand &IndexReg = MI->getOperand(OpNo + X86::AddrIndexReg);
422 const MachineOperand &DispSpec = MI->getOperand(OpNo + X86::AddrDisp);
423
424 // If we really don't want to print out (rip), don't.
425 bool HasBaseReg = BaseReg.getReg() != 0;
426 if (HasBaseReg && Modifier == "no-rip" && BaseReg.getReg() == X86::RIP)
427 HasBaseReg = false;
428
429 // HasParenPart - True if we will print out the () part of the mem ref.
430 bool HasParenPart = IndexReg.getReg() || HasBaseReg;
431
432 switch (DispSpec.getType()) {
433 default:
434 llvm_unreachable("unknown operand type!");
436 int DispVal = DispSpec.getImm();
437 if (DispVal || !HasParenPart)
438 O << DispVal;
439 break;
440 }
443 PrintSymbolOperand(DispSpec, O);
444 break;
445 }
446
447 if (Modifier == "H")
448 O << "+8";
449
450 if (HasParenPart) {
451 assert(IndexReg.getReg() != X86::ESP &&
452 "X86 doesn't allow scaling by ESP");
453
454 O << '(';
455 if (HasBaseReg)
456 PrintModifiedOperand(MI, OpNo + X86::AddrBaseReg, O, Modifier);
457
458 if (IndexReg.getReg()) {
459 O << ',';
460 PrintModifiedOperand(MI, OpNo + X86::AddrIndexReg, O, Modifier);
461 unsigned ScaleVal = MI->getOperand(OpNo + X86::AddrScaleAmt).getImm();
462 if (ScaleVal != 1)
463 O << ',' << ScaleVal;
464 }
465 O << ')';
466 }
467}
468
469static bool isSimpleReturn(const MachineInstr &MI) {
470 // We exclude all tail calls here which set both isReturn and isCall.
471 return MI.getDesc().isReturn() && !MI.getDesc().isCall();
472}
473
475 unsigned Opc = MI.getOpcode();
476 return MI.getDesc().isIndirectBranch() /*Make below code in a good shape*/ ||
477 Opc == X86::TAILJMPr || Opc == X86::TAILJMPm ||
478 Opc == X86::TAILJMPr64 || Opc == X86::TAILJMPm64 ||
479 Opc == X86::TCRETURNri || Opc == X86::TCRETURNmi ||
480 Opc == X86::TCRETURNri64 || Opc == X86::TCRETURNmi64 ||
481 Opc == X86::TCRETURNri64_ImpCall || Opc == X86::TAILJMPr64_REX ||
482 Opc == X86::TAILJMPm64_REX;
483}
484
486 if (Subtarget->hardenSlsRet() || Subtarget->hardenSlsIJmp()) {
487 auto I = MBB.getLastNonDebugInstr();
488 if (I != MBB.end()) {
489 if ((Subtarget->hardenSlsRet() && isSimpleReturn(*I)) ||
490 (Subtarget->hardenSlsIJmp() && isIndirectBranchOrTailCall(*I))) {
491 MCInst TmpInst;
492 TmpInst.setOpcode(X86::INT3);
493 EmitToStreamer(*OutStreamer, TmpInst);
494 }
495 }
496 }
498 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
499}
500
501void X86AsmPrinter::PrintMemReference(const MachineInstr *MI, unsigned OpNo,
502 raw_ostream &O, StringRef Modifier) {
503 assert(isMem(*MI, OpNo) && "Invalid memory reference!");
504 const MachineOperand &Segment = MI->getOperand(OpNo + X86::AddrSegmentReg);
505 if (Segment.getReg()) {
506 PrintModifiedOperand(MI, OpNo + X86::AddrSegmentReg, O, Modifier);
507 O << ':';
508 }
509 PrintLeaMemReference(MI, OpNo, O, Modifier);
510}
511
512void X86AsmPrinter::PrintIntelMemReference(const MachineInstr *MI,
513 unsigned OpNo, raw_ostream &O,
514 StringRef Modifier) {
515 const MachineOperand &BaseReg = MI->getOperand(OpNo + X86::AddrBaseReg);
516 unsigned ScaleVal = MI->getOperand(OpNo + X86::AddrScaleAmt).getImm();
517 const MachineOperand &IndexReg = MI->getOperand(OpNo + X86::AddrIndexReg);
518 const MachineOperand &DispSpec = MI->getOperand(OpNo + X86::AddrDisp);
519 const MachineOperand &SegReg = MI->getOperand(OpNo + X86::AddrSegmentReg);
520
521 // If we really don't want to print out (rip), don't.
522 bool HasBaseReg = BaseReg.getReg() != 0;
523 if (HasBaseReg && Modifier == "no-rip" && BaseReg.getReg() == X86::RIP)
524 HasBaseReg = false;
525
526 // If we really just want to print out displacement.
527 if ((DispSpec.isGlobal() || DispSpec.isSymbol()) && Modifier == "disp-only") {
528 HasBaseReg = false;
529 }
530
531 // If this has a segment register, print it.
532 if (SegReg.getReg()) {
533 PrintOperand(MI, OpNo + X86::AddrSegmentReg, O);
534 O << ':';
535 }
536
537 O << '[';
538
539 bool NeedPlus = false;
540 if (HasBaseReg) {
541 PrintOperand(MI, OpNo + X86::AddrBaseReg, O);
542 NeedPlus = true;
543 }
544
545 if (IndexReg.getReg()) {
546 if (NeedPlus) O << " + ";
547 if (ScaleVal != 1)
548 O << ScaleVal << '*';
549 PrintOperand(MI, OpNo + X86::AddrIndexReg, O);
550 NeedPlus = true;
551 }
552
553 if (!DispSpec.isImm()) {
554 if (NeedPlus) O << " + ";
555 // Do not add `offset` operator. Matches the behaviour of
556 // X86IntelInstPrinter::printMemReference.
557 PrintSymbolOperand(DispSpec, O);
558 } else {
559 int64_t DispVal = DispSpec.getImm();
560 if (DispVal || (!IndexReg.getReg() && !HasBaseReg)) {
561 if (NeedPlus) {
562 if (DispVal > 0)
563 O << " + ";
564 else {
565 O << " - ";
566 DispVal = -DispVal;
567 }
568 }
569 O << DispVal;
570 }
571 }
572 O << ']';
573}
574
575const MCSubtargetInfo *X86AsmPrinter::getIFuncMCSubtargetInfo() const {
576 assert(Subtarget);
577 return Subtarget;
578}
579
580void X86AsmPrinter::emitMachOIFuncStubBody(Module &M, const GlobalIFunc &GI,
581 MCSymbol *LazyPointer) {
582 // _ifunc:
583 // jmpq *lazy_pointer(%rip)
584
585 OutStreamer->emitInstruction(
586 MCInstBuilder(X86::JMP32m)
587 .addReg(X86::RIP)
588 .addImm(1)
589 .addReg(0)
591 MCSymbolRefExpr::create(LazyPointer, OutContext)))
592 .addReg(0),
593 *Subtarget);
594}
595
596void X86AsmPrinter::emitMachOIFuncStubHelperBody(Module &M,
597 const GlobalIFunc &GI,
598 MCSymbol *LazyPointer) {
599 // _ifunc.stub_helper:
600 // push %rax
601 // push %rdi
602 // push %rsi
603 // push %rdx
604 // push %rcx
605 // push %r8
606 // push %r9
607 // callq foo
608 // movq %rax,lazy_pointer(%rip)
609 // pop %r9
610 // pop %r8
611 // pop %rcx
612 // pop %rdx
613 // pop %rsi
614 // pop %rdi
615 // pop %rax
616 // jmpq *lazy_pointer(%rip)
617
618 for (int Reg :
619 {X86::RAX, X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8, X86::R9})
620 OutStreamer->emitInstruction(MCInstBuilder(X86::PUSH64r).addReg(Reg),
621 *Subtarget);
622
623 OutStreamer->emitInstruction(
624 MCInstBuilder(X86::CALL64pcrel32)
626 *Subtarget);
627
628 OutStreamer->emitInstruction(
629 MCInstBuilder(X86::MOV64mr)
630 .addReg(X86::RIP)
631 .addImm(1)
632 .addReg(0)
634 MCSymbolRefExpr::create(LazyPointer, OutContext)))
635 .addReg(0)
636 .addReg(X86::RAX),
637 *Subtarget);
638
639 for (int Reg :
640 {X86::R9, X86::R8, X86::RCX, X86::RDX, X86::RSI, X86::RDI, X86::RAX})
641 OutStreamer->emitInstruction(MCInstBuilder(X86::POP64r).addReg(Reg),
642 *Subtarget);
643
644 OutStreamer->emitInstruction(
645 MCInstBuilder(X86::JMP32m)
646 .addReg(X86::RIP)
647 .addImm(1)
648 .addReg(0)
650 MCSymbolRefExpr::create(LazyPointer, OutContext)))
651 .addReg(0),
652 *Subtarget);
653}
654
655static bool printAsmMRegister(const X86AsmPrinter &P, const MachineOperand &MO,
656 char Mode, raw_ostream &O) {
657 Register Reg = MO.getReg();
658 bool EmitPercent = MO.getParent()->getInlineAsmDialect() == InlineAsm::AD_ATT;
659
660 if (!X86::GR8RegClass.contains(Reg) &&
661 !X86::GR16RegClass.contains(Reg) &&
662 !X86::GR32RegClass.contains(Reg) &&
663 !X86::GR64RegClass.contains(Reg))
664 return true;
665
666 switch (Mode) {
667 default: return true; // Unknown mode.
668 case 'b': // Print QImode register
669 Reg = getX86SubSuperRegister(Reg, 8);
670 break;
671 case 'h': // Print QImode high register
672 Reg = getX86SubSuperRegister(Reg, 8, true);
673 if (!Reg.isValid())
674 return true;
675 break;
676 case 'w': // Print HImode register
677 Reg = getX86SubSuperRegister(Reg, 16);
678 break;
679 case 'k': // Print SImode register
680 Reg = getX86SubSuperRegister(Reg, 32);
681 break;
682 case 'V':
683 EmitPercent = false;
684 [[fallthrough]];
685 case 'q':
686 // Print 64-bit register names if 64-bit integer registers are available.
687 // Otherwise, print 32-bit register names.
688 Reg = getX86SubSuperRegister(Reg, P.getSubtarget().is64Bit() ? 64 : 32);
689 break;
690 }
691
692 if (EmitPercent)
693 O << '%';
694
696 return false;
697}
698
699static bool printAsmVRegister(const MachineOperand &MO, char Mode,
700 raw_ostream &O) {
701 Register Reg = MO.getReg();
702 bool EmitPercent = MO.getParent()->getInlineAsmDialect() == InlineAsm::AD_ATT;
703
704 unsigned Index;
705 if (X86::VR128XRegClass.contains(Reg))
706 Index = Reg - X86::XMM0;
707 else if (X86::VR256XRegClass.contains(Reg))
708 Index = Reg - X86::YMM0;
709 else if (X86::VR512RegClass.contains(Reg))
710 Index = Reg - X86::ZMM0;
711 else
712 return true;
713
714 switch (Mode) {
715 default: // Unknown mode.
716 return true;
717 case 'x': // Print V4SFmode register
718 Reg = X86::XMM0 + Index;
719 break;
720 case 't': // Print V8SFmode register
721 Reg = X86::YMM0 + Index;
722 break;
723 case 'g': // Print V16SFmode register
724 Reg = X86::ZMM0 + Index;
725 break;
726 }
727
728 if (EmitPercent)
729 O << '%';
730
732 return false;
733}
734
735/// PrintAsmOperand - Print out an operand for an inline asm expression.
736///
738 const char *ExtraCode, raw_ostream &O) {
739 // Does this asm operand have a single letter operand modifier?
740 if (ExtraCode && ExtraCode[0]) {
741 if (ExtraCode[1] != 0) return true; // Unknown modifier.
742
743 const MachineOperand &MO = MI->getOperand(OpNo);
744
745 switch (ExtraCode[0]) {
746 default:
747 // See if this is a generic print operand
748 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
749 case 'a': // This is an address. Currently only 'i' and 'r' are expected.
750 switch (MO.getType()) {
751 default:
752 return true;
754 O << MO.getImm();
755 return false;
759 llvm_unreachable("unexpected operand type!");
761 PrintSymbolOperand(MO, O);
762 if (Subtarget->is64Bit())
763 O << "(%rip)";
764 return false;
766 O << '(';
767 PrintOperand(MI, OpNo, O);
768 O << ')';
769 return false;
770 }
771
772 case 'c': // Don't print "$" before a global var name or constant.
773 switch (MO.getType()) {
774 default:
775 PrintOperand(MI, OpNo, O);
776 break;
778 O << MO.getImm();
779 break;
783 llvm_unreachable("unexpected operand type!");
785 PrintSymbolOperand(MO, O);
786 break;
787 }
788 return false;
789
790 case 'A': // Print '*' before a register (it must be a register)
791 if (MO.isReg()) {
792 O << '*';
793 PrintOperand(MI, OpNo, O);
794 return false;
795 }
796 return true;
797
798 case 'b': // Print QImode register
799 case 'h': // Print QImode high register
800 case 'w': // Print HImode register
801 case 'k': // Print SImode register
802 case 'q': // Print DImode register
803 case 'V': // Print native register without '%'
804 if (MO.isReg())
805 return printAsmMRegister(*this, MO, ExtraCode[0], O);
806 PrintOperand(MI, OpNo, O);
807 return false;
808
809 case 'x': // Print V4SFmode register
810 case 't': // Print V8SFmode register
811 case 'g': // Print V16SFmode register
812 if (MO.isReg())
813 return printAsmVRegister(MO, ExtraCode[0], O);
814 PrintOperand(MI, OpNo, O);
815 return false;
816
817 case 'p': {
818 const MachineOperand &MO = MI->getOperand(OpNo);
820 return true;
821 PrintSymbolOperand(MO, O);
822 return false;
823 }
824
825 case 'P': // This is the operand of a call, treat specially.
826 PrintPCRelImm(MI, OpNo, O);
827 return false;
828
829 case 'n': // Negate the immediate or print a '-' before the operand.
830 // Note: this is a temporary solution. It should be handled target
831 // independently as part of the 'MC' work.
832 if (MO.isImm()) {
833 O << -MO.getImm();
834 return false;
835 }
836 O << '-';
837 }
838 }
839
840 PrintOperand(MI, OpNo, O);
841 return false;
842}
843
845 const char *ExtraCode,
846 raw_ostream &O) {
847 if (ExtraCode && ExtraCode[0]) {
848 if (ExtraCode[1] != 0) return true; // Unknown modifier.
849
850 switch (ExtraCode[0]) {
851 default: return true; // Unknown modifier.
852 case 'b': // Print QImode register
853 case 'h': // Print QImode high register
854 case 'w': // Print HImode register
855 case 'k': // Print SImode register
856 case 'q': // Print SImode register
857 // These only apply to registers, ignore on mem.
858 break;
859 case 'H':
860 if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
861 return true; // Unsupported modifier in Intel inline assembly.
862 } else {
863 PrintMemReference(MI, OpNo, O, "H");
864 }
865 return false;
866 // Print memory only with displacement. The Modifer 'P' is used in inline
867 // asm to present a call symbol or a global symbol which can not use base
868 // reg or index reg.
869 case 'P':
870 if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
871 PrintIntelMemReference(MI, OpNo, O, "disp-only");
872 } else {
873 PrintMemReference(MI, OpNo, O, "disp-only");
874 }
875 return false;
876 }
877 }
878 if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
879 PrintIntelMemReference(MI, OpNo, O);
880 } else {
881 PrintMemReference(MI, OpNo, O);
882 }
883 return false;
884}
885
887 const Triple &TT = TM.getTargetTriple();
888
889 if (TT.isOSBinFormatELF()) {
890 // Assemble feature flags that may require creation of a note section.
891 unsigned FeatureFlagsAnd = 0;
892 if (M.getModuleFlag("cf-protection-branch"))
893 FeatureFlagsAnd |= ELF::GNU_PROPERTY_X86_FEATURE_1_IBT;
894 if (M.getModuleFlag("cf-protection-return"))
895 FeatureFlagsAnd |= ELF::GNU_PROPERTY_X86_FEATURE_1_SHSTK;
896
897 if (FeatureFlagsAnd) {
898 // Emit a .note.gnu.property section with the flags.
899 assert((TT.isArch32Bit() || TT.isArch64Bit()) &&
900 "CFProtection used on invalid architecture!");
901 MCSection *Cur = OutStreamer->getCurrentSectionOnly();
903 ".note.gnu.property", ELF::SHT_NOTE, ELF::SHF_ALLOC);
904 OutStreamer->switchSection(Nt);
905
906 // Emitting note header.
907 const int WordSize = TT.isArch64Bit() && !TT.isX32() ? 8 : 4;
908 emitAlignment(WordSize == 4 ? Align(4) : Align(8));
909 OutStreamer->emitIntValue(4, 4 /*size*/); // data size for "GNU\0"
910 OutStreamer->emitIntValue(8 + WordSize, 4 /*size*/); // Elf_Prop size
911 OutStreamer->emitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4 /*size*/);
912 OutStreamer->emitBytes(StringRef("GNU", 4)); // note name
913
914 // Emitting an Elf_Prop for the CET properties.
916 OutStreamer->emitInt32(4); // data size
917 OutStreamer->emitInt32(FeatureFlagsAnd); // data
918 emitAlignment(WordSize == 4 ? Align(4) : Align(8)); // padding
919
920 OutStreamer->switchSection(Cur);
921 }
922 }
923
924 if (TT.isOSBinFormatMachO())
925 OutStreamer->switchSection(getObjFileLowering().getTextSection());
926
927 if (TT.isOSBinFormatCOFF()) {
930
931 if (M.getModuleFlag("import-call-optimization"))
932 EnableImportCallOptimization = true;
933 }
934 OutStreamer->emitSyntaxDirective();
935
936 // If this is not inline asm and we're in 16-bit
937 // mode prefix assembly with .code16.
938 bool is16 = TT.getEnvironment() == Triple::CODE16;
939 if (M.getModuleInlineAsm().empty() && is16) {
940 auto *XTS =
941 static_cast<X86TargetStreamer *>(OutStreamer->getTargetStreamer());
942 XTS->emitCode16();
943 }
944}
945
946static void
949 // L_foo$stub:
950 OutStreamer.emitLabel(StubLabel);
951 // .indirect_symbol _foo
953
954 if (MCSym.getInt())
955 // External to current translation unit.
956 OutStreamer.emitIntValue(0, 4/*size*/);
957 else
958 // Internal to current translation unit.
959 //
960 // When we place the LSDA into the TEXT section, the type info
961 // pointers need to be indirect and pc-rel. We accomplish this by
962 // using NLPs; however, sometimes the types are local to the file.
963 // We need to fill in the value for the NLP in those cases.
964 OutStreamer.emitValue(
965 MCSymbolRefExpr::create(MCSym.getPointer(), OutStreamer.getContext()),
966 4 /*size*/);
967}
968
969static void emitNonLazyStubs(MachineModuleInfo *MMI, MCStreamer &OutStreamer) {
970
971 MachineModuleInfoMachO &MMIMacho =
973
974 // Output stubs for dynamically-linked functions.
976
977 // Output stubs for external and common global variables.
978 Stubs = MMIMacho.GetGVStubList();
979 if (!Stubs.empty()) {
980 OutStreamer.switchSection(MMI->getContext().getMachOSection(
981 "__IMPORT", "__pointers", MachO::S_NON_LAZY_SYMBOL_POINTERS,
983
984 for (auto &Stub : Stubs)
985 emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second);
986
987 Stubs.clear();
988 OutStreamer.addBlankLine();
989 }
990}
991
992/// True if this module is being built for windows/msvc, and uses floating
993/// point. This is used to emit an undefined reference to _fltused. This is
994/// needed in Windows kernel or driver contexts to find and prevent code from
995/// modifying non-GPR registers.
996///
997/// TODO: It would be better if this was computed from MIR by looking for
998/// selected floating-point instructions.
999static bool usesMSVCFloatingPoint(const Triple &TT, const Module &M) {
1000 // Only needed for MSVC
1001 if (!TT.isWindowsMSVCEnvironment())
1002 return false;
1003
1004 for (const Function &F : M) {
1005 for (const Instruction &I : instructions(F)) {
1006 if (I.getType()->isFloatingPointTy())
1007 return true;
1008
1009 for (const auto &Op : I.operands()) {
1010 if (Op->getType()->isFloatingPointTy())
1011 return true;
1012 }
1013 }
1014 }
1015
1016 return false;
1017}
1018
1020 const Triple &TT = TM.getTargetTriple();
1021
1022 if (TT.isOSBinFormatMachO()) {
1023 // Mach-O uses non-lazy symbol stubs to encode per-TU information into
1024 // global table for symbol lookup.
1026
1027 // Emit fault map information.
1029
1030 // This flag tells the linker that no global symbols contain code that fall
1031 // through to other global symbols (e.g. an implementation of multiple entry
1032 // points). If this doesn't occur, the linker can safely perform dead code
1033 // stripping. Since LLVM never generates code that does this, it is always
1034 // safe to set.
1035 OutStreamer->emitSubsectionsViaSymbols();
1036 } else if (TT.isOSBinFormatCOFF()) {
1037 // If import call optimization is enabled, emit the appropriate section.
1038 // We do this whether or not we recorded any items.
1039 if (EnableImportCallOptimization) {
1040 OutStreamer->switchSection(getObjFileLowering().getImportCallSection());
1041
1042 // Section always starts with some magic.
1043 constexpr char ImpCallMagic[12] = "RetpolineV1";
1044 OutStreamer->emitBytes(StringRef{ImpCallMagic, sizeof(ImpCallMagic)});
1045
1046 // Layout of this section is:
1047 // Per section that contains an item to record:
1048 // uint32_t SectionSize: Size in bytes for information in this section.
1049 // uint32_t Section Number
1050 // Per call to imported function in section:
1051 // uint32_t Kind: the kind of item.
1052 // uint32_t InstOffset: the offset of the instr in its parent section.
1053 for (auto &[Section, CallsToImportedFuncs] :
1054 SectionToImportedFunctionCalls) {
1055 unsigned SectionSize =
1056 sizeof(uint32_t) * (2 + 2 * CallsToImportedFuncs.size());
1057 OutStreamer->emitInt32(SectionSize);
1058 OutStreamer->emitCOFFSecNumber(Section->getBeginSymbol());
1059 for (auto &[CallsiteSymbol, Kind] : CallsToImportedFuncs) {
1060 OutStreamer->emitInt32(Kind);
1061 OutStreamer->emitCOFFSecOffset(CallsiteSymbol);
1062 }
1063 }
1064 }
1065
1066 if (usesMSVCFloatingPoint(TT, M)) {
1067 // In Windows' libcmt.lib, there is a file which is linked in only if the
1068 // symbol _fltused is referenced. Linking this in causes some
1069 // side-effects:
1070 //
1071 // 1. For x86-32, it will set the x87 rounding mode to 53-bit instead of
1072 // 64-bit mantissas at program start.
1073 //
1074 // 2. It links in support routines for floating-point in scanf and printf.
1075 //
1076 // MSVC emits an undefined reference to _fltused when there are any
1077 // floating point operations in the program (including calls). A program
1078 // that only has: `scanf("%f", &global_float);` may fail to trigger this,
1079 // but oh well...that's a documented issue.
1080 StringRef SymbolName =
1081 (TT.getArch() == Triple::x86) ? "__fltused" : "_fltused";
1082 MCSymbol *S = MMI->getContext().getOrCreateSymbol(SymbolName);
1083 OutStreamer->emitSymbolAttribute(S, MCSA_Global);
1084 return;
1085 }
1086 } else if (TT.isOSBinFormatELF()) {
1088 }
1089
1090 // Emit __morestack address if needed for indirect calls.
1091 if (TT.getArch() == Triple::x86_64 && TM.getCodeModel() == CodeModel::Large) {
1092 if (MCSymbol *AddrSymbol = OutContext.lookupSymbol("__morestack_addr")) {
1093 Align Alignment(1);
1096 /*C=*/nullptr, Alignment);
1097 OutStreamer->switchSection(ReadOnlySection);
1098 OutStreamer->emitLabel(AddrSymbol);
1099
1100 unsigned PtrSize = MAI->getCodePointerSize();
1101 OutStreamer->emitSymbolValue(GetExternalSymbolSymbol("__morestack"),
1102 PtrSize);
1103 }
1104 }
1105}
1106
1107char X86AsmPrinter::ID = 0;
1108
1109INITIALIZE_PASS(X86AsmPrinter, "x86-asm-printer", "X86 Assembly Printer", false,
1110 false)
1111
1112//===----------------------------------------------------------------------===//
1113// Target Registry Stuff
1114//===----------------------------------------------------------------------===//
1115
1116// Force static initialization.
1117extern "C" LLVM_C_ABI void LLVMInitializeX86AsmPrinter() {
1120}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
static void emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, MachineModuleInfoImpl::StubValueTy &MCSym)
MachineBasicBlock & MBB
Expand Atomic instructions
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
#define P(N)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:56
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:480
#define LLVM_C_ABI
LLVM_C_ABI is the export/visibility macro used to mark symbols declared in llvm-c as exported when bu...
Definition: Visibility.h:40
static bool printAsmMRegister(const X86AsmPrinter &P, const MachineOperand &MO, char Mode, raw_ostream &O)
static bool isSimpleReturn(const MachineInstr &MI)
static bool usesMSVCFloatingPoint(const Triple &TT, const Module &M)
True if this module is being built for windows/msvc, and uses floating point.
static bool isIndirectBranchOrTailCall(const MachineInstr &MI)
static bool printAsmVRegister(const MachineOperand &MO, char Mode, raw_ostream &O)
static void emitNonLazyStubs(MachineModuleInfo *MMI, MCStreamer &OutStreamer)
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:90
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
Definition: AsmPrinter.cpp:413
MCSymbol * getSymbolWithGlobalValueBase(const GlobalValue *GV, StringRef Suffix) const
Return the MCSymbol for a private symbol with global value name as its base, with the specified suffi...
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:706
void emitNops(unsigned N)
Emit N NOP instructions.
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
Definition: AsmPrinter.cpp:433
TargetMachine & TM
Target machine description.
Definition: AsmPrinter.h:93
void emitXRayTable()
Emit a table with all XRay instrumentation points.
virtual void emitBasicBlockEnd(const MachineBasicBlock &MBB)
Targets can override this to emit stuff at the end of a basic block.
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
const MCAsmInfo * MAI
Target Asm Printer information.
Definition: AsmPrinter.h:96
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:108
virtual const MCExpr * lowerConstant(const Constant *CV, const Constant *BaseCV=nullptr, uint64_t Offset=0)
Lower the specified LLVM Constant to an MCExpr.
virtual void SetupMachineFunction(MachineFunction &MF)
This should be called when a new MachineFunction is being processed from runOnMachineFunction.
void emitFunctionBody()
This method emits the body and trailer for a function.
virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const
This emits linkage information about GVSym based on GV, if this is supported by the target.
Definition: AsmPrinter.cpp:661
void printOffset(int64_t Offset, raw_ostream &OS) const
This is just convenient handler for printing offsets.
MCSymbol * getSymbolPreferLocal(const GlobalValue &GV) const
Similar to getSymbol() but preferred for references.
Definition: AsmPrinter.cpp:710
MCSymbol * CurrentFnSym
The symbol for the current function.
Definition: AsmPrinter.h:127
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
Definition: AsmPrinter.h:111
void emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const
Emit an alignment directive to the specified power of two boundary.
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition: AsmPrinter.h:100
const StaticDataProfileInfo * SDPI
Provides the profile information for constants.
Definition: AsmPrinter.h:146
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:105
const ProfileSummaryInfo * PSI
The profile summary information.
Definition: AsmPrinter.h:149
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
const DataLayout & getDataLayout() const
Return information about data layout.
Definition: AsmPrinter.cpp:417
void emitCOFFFeatureSymbol(Module &M)
Emits the @feat.00 symbol indicating the features enabled in this module.
MCSymbol * GetExternalSymbolSymbol(const Twine &Sym) const
Return the MCSymbol for the specified ExternalSymbol.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
Definition: AsmPrinter.cpp:428
void emitCOFFReplaceableFunctionData(Module &M)
Emits symbols and data to allow functions marked with the loader-replaceable attribute to be replacea...
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:400
This is the shared class of boolean and integer constants.
Definition: Constants.h:87
This class represents an Operation in the Expression.
void serializeToFaultMapSection()
Definition: FaultMaps.cpp:45
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.cpp:762
const Constant * getResolver() const
Definition: GlobalIFunc.h:73
bool hasLocalLinkage() const
Definition: GlobalValue.h:530
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:663
bool hasInternalLinkage() const
Definition: GlobalValue.h:528
bool hasDotTypeDotSizeDirective() const
Definition: MCAsmInfo.h:606
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
Definition: MCAsmInfo.h:443
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:428
LLVM_ABI MCSectionMachO * getMachOSection(StringRef Segment, StringRef Section, unsigned TypeAndAttributes, unsigned Reserved2, SectionKind K, const char *BeginSymName=nullptr)
Return the MCSection for the specified mach-o section.
Definition: MCContext.cpp:533
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:386
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
Definition: MCContext.h:549
LLVM_ABI MCSymbol * lookupSymbol(const Twine &Name) const
Get the symbol for Name, or null.
Definition: MCContext.cpp:457
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:203
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:188
void setOpcode(unsigned Op)
Definition: MCInst.h:201
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:166
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:496
Streaming machine code generation interface.
Definition: MCStreamer.h:220
virtual void addBlankLine()
Emit a blank line to a .s file to pretty it up.
Definition: MCStreamer.h:408
virtual bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute)=0
Add the given Attribute to Symbol.
MCContext & getContext() const
Definition: MCStreamer.h:314
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:178
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:395
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
Definition: MCStreamer.cpp:132
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
Generic base class for all target subtargets.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.h:214
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:59
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:188
Metadata node.
Definition: Metadata.h:1077
LLVM_ABI iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
MCSymbol * getPICBaseSymbol() const
getPICBaseSymbol - Return a function-local symbol to represent the PIC base.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MCContext & getContext() const
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Align getAlignment() const
getAlignment - Return the alignment of the function.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
Definition: MachineInstr.h:72
LLVM_ABI InlineAsm::AsmDialect getInlineAsmDialect() const
std::vector< std::pair< MCSymbol *, StubValueTy > > SymbolListTy
PointerIntPair< MCSymbol *, 1, bool > StubValueTy
MachineModuleInfoMachO - This is a MachineModuleInfoImpl implementation for MachO targets.
SymbolListTy GetGVStubList()
Accessor methods to return the set of stubs in sorted order.
This class contains meta information specific to a module.
const MCContext & getContext() const
Ty & getObjFileInfo()
Keep track of various per-module pieces of information for backends that would like to do so.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
const BlockAddress * getBlockAddress() const
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
int64_t getOffset() const
Return the offset from the symbol in this operand.
ArrayRef< std::pair< MCRegister, Register > > liveins() const
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
PointerIntPair - This class implements a pair of a pointer and small integer.
IntType getInt() const
PointerTy getPointer() const
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
static SectionKind getMetadata()
Definition: SectionKind.h:188
static SectionKind getReadOnly()
Definition: SectionKind.h:192
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:480
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:151
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition: StringRef.h:645
virtual MCSection * getSectionForConstant(const DataLayout &DL, SectionKind Kind, const Constant *C, Align &Alignment) const
Given a constant with the SectionKind, return a section that it should be placed in.
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:83
const Triple & getTargetTriple() const
const Target & getTarget() const
CodeModel::Model getCodeModel() const
Returns the code model.
MCCodeEmitter * createMCCodeEmitter(const MCInstrInfo &II, MCContext &Ctx) const
createMCCodeEmitter - Create a target specific code emitter.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:47
bool isOSWindows() const
Tests whether the OS is Windows.
Definition: Triple.h:676
LLVM_ABI bool isArch64Bit() const
Test whether the architecture is 64-bit.
Definition: Triple.cpp:1771
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:75
static const char * getRegisterName(MCRegister Reg)
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - Emit the function body.
void emitKCFITypeId(const MachineFunction &MF) override
emitKCFITypeId - Emit the KCFI type information in architecture specific format.
void emitStartOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the start of their fi...
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
void emitFunctionBodyEnd() override
Targets can override this to emit stuff after the last basic block in the function.
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
void emitBasicBlockEnd(const MachineBasicBlock &MBB) override
Targets can override this to emit stuff at the end of a basic block.
X86AsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &O) override
PrintAsmOperand - Print out an operand for an inline asm expression.
void emitFunctionBodyStart() override
Targets can override this to emit stuff before the first basic block in the function.
X86MachineFunctionInfo - This class is derived from MachineFunction and contains private X86 target-s...
const X86InstrInfo * getInstrInfo() const override
Definition: X86Subtarget.h:122
bool isTargetCOFF() const
Definition: X86Subtarget.h:291
bool isTargetWin32() const
Definition: X86Subtarget.h:331
X86 target streamer implementing x86-only assembly directives.
virtual bool emitFPOProc(const MCSymbol *ProcSym, unsigned ParamsSize, SMLoc L={})
virtual bool emitFPOEndProc(SMLoc L={})
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
Definition: COFF.h:224
@ IMAGE_SYM_CLASS_STATIC
Static.
Definition: COFF.h:225
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
Definition: COFF.h:276
@ SCT_COMPLEX_TYPE_SHIFT
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
Definition: COFF.h:280
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ NT_GNU_PROPERTY_TYPE_0
Definition: ELF.h:1801
@ GNU_PROPERTY_X86_FEATURE_1_AND
Definition: ELF.h:1836
@ SHT_NOTE
Definition: ELF.h:1146
@ GNU_PROPERTY_X86_FEATURE_1_SHSTK
Definition: ELF.h:1883
@ GNU_PROPERTY_X86_FEATURE_1_IBT
Definition: ELF.h:1882
@ SHF_ALLOC
Definition: ELF.h:1240
@ S_NON_LAZY_SYMBOL_POINTERS
S_NON_LAZY_SYMBOL_POINTERS - Section with non-lazy symbol pointers.
Definition: MachO.h:139
Reg
All possible values of the reg field in the ModR/M byte.
@ MO_TLSLD
MO_TLSLD - On a symbol operand this indicates that the immediate is the offset of the GOT entry with ...
Definition: X86BaseInfo.h:411
@ MO_GOTPCREL_NORELAX
MO_GOTPCREL_NORELAX - Same as MO_GOTPCREL except that R_X86_64_GOTPCREL relocations are guaranteed to...
Definition: X86BaseInfo.h:391
@ MO_GOTOFF
MO_GOTOFF - On a symbol operand this indicates that the immediate is the offset to the location of th...
Definition: X86BaseInfo.h:381
@ MO_DARWIN_NONLAZY_PIC_BASE
MO_DARWIN_NONLAZY_PIC_BASE - On a symbol operand "FOO", this indicates that the reference is actually...
Definition: X86BaseInfo.h:468
@ MO_GOT_ABSOLUTE_ADDRESS
MO_GOT_ABSOLUTE_ADDRESS - On a symbol operand, this represents a relocation of: SYMBOL_LABEL + [.
Definition: X86BaseInfo.h:367
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
Definition: X86BaseInfo.h:488
@ MO_NTPOFF
MO_NTPOFF - On a symbol operand this indicates that the immediate is the negative thread-pointer offs...
Definition: X86BaseInfo.h:450
@ MO_DARWIN_NONLAZY
MO_DARWIN_NONLAZY - On a symbol operand "FOO", this indicates that the reference is actually to the "...
Definition: X86BaseInfo.h:464
@ MO_INDNTPOFF
MO_INDNTPOFF - On a symbol operand this indicates that the immediate is the absolute address of the G...
Definition: X86BaseInfo.h:432
@ MO_GOTNTPOFF
MO_GOTNTPOFF - On a symbol operand this indicates that the immediate is the offset of the GOT entry w...
Definition: X86BaseInfo.h:456
@ MO_TPOFF
MO_TPOFF - On a symbol operand this indicates that the immediate is the thread-pointer offset for the...
Definition: X86BaseInfo.h:438
@ MO_TLVP_PIC_BASE
MO_TLVP_PIC_BASE - On a symbol operand this indicates that the immediate is some TLS offset from the ...
Definition: X86BaseInfo.h:476
@ MO_GOT
MO_GOT - On a symbol operand this indicates that the immediate is the offset to the GOT entry for the...
Definition: X86BaseInfo.h:376
@ MO_PLT
MO_PLT - On a symbol operand this indicates that the immediate is offset to the PLT entry of symbol n...
Definition: X86BaseInfo.h:396
@ MO_TLSGD
MO_TLSGD - On a symbol operand this indicates that the immediate is the offset of the GOT entry with ...
Definition: X86BaseInfo.h:403
@ MO_NO_FLAG
MO_NO_FLAG - No flag for the operand.
Definition: X86BaseInfo.h:363
@ MO_TLVP
MO_TLVP - On a symbol operand this indicates that the immediate is some TLS offset.
Definition: X86BaseInfo.h:472
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the reference is actually to the "__imp...
Definition: X86BaseInfo.h:460
@ MO_GOTTPOFF
MO_GOTTPOFF - On a symbol operand this indicates that the immediate is the offset of the GOT entry wi...
Definition: X86BaseInfo.h:425
@ MO_SECREL
MO_SECREL - On a symbol operand this indicates that the immediate is the offset from beginning of sec...
Definition: X86BaseInfo.h:480
@ MO_DTPOFF
MO_DTPOFF - On a symbol operand this indicates that the immediate is the offset of the GOT entry with...
Definition: X86BaseInfo.h:444
@ MO_PIC_BASE_OFFSET
MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the immediate should get the value of th...
Definition: X86BaseInfo.h:371
@ MO_TLSLDM
MO_TLSLDM - On a symbol operand this indicates that the immediate is the offset of the GOT entry with...
Definition: X86BaseInfo.h:419
@ MO_GOTPCREL
MO_GOTPCREL - On a symbol operand this indicates that the immediate is offset to the GOT entry for th...
Definition: X86BaseInfo.h:387
@ AddrScaleAmt
Definition: X86BaseInfo.h:30
@ AddrSegmentReg
Definition: X86BaseInfo.h:34
@ AddrIndexReg
Definition: X86BaseInfo.h:31
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition: SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:170
MCRegister getX86SubSuperRegister(MCRegister Reg, unsigned Size, bool High=false)
Target & getTheX86_32Target()
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
Definition: Alignment.h:197
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1886
Target & getTheX86_64Target()
@ MCSA_IndirectSymbol
.indirect_symbol (MachO)
Definition: MCDirectives.h:35
@ MCSA_Global
.type _foo, @gnu_unique_object
Definition: MCDirectives.h:30
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Definition: MCDirectives.h:23
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...