LLVM 23.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///
68 PSI = &PSIW->getPSI();
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()) {
86 bool Local = MF.getFunction().hasLocalLinkage();
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")
149 .getValueAsString()
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);
185 if (MAI->hasDotTypeDotSizeDirective())
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;
210 if (MF.getInfo<X86MachineFunctionInfo>()->getArgumentStackSize() > 0) {
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
230 if (MAI->hasDotTypeDotSizeDirective()) {
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 << " + [.-";
305 MF->getPICBaseSymbol()->print(O, MAI);
306 O << ']';
307 break;
310 O << '-';
311 MF->getPICBaseSymbol()->print(O, MAI);
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" << '-';
330 MF->getPICBaseSymbol()->print(O, MAI);
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::TCRETURN_WIN64ri ||
480 Opc == X86::TCRETURN_HIPE32ri || Opc == X86::TCRETURNmi ||
481 Opc == X86::TCRETURN_WINmi64 || Opc == X86::TCRETURNri64 ||
482 Opc == X86::TCRETURNmi64 || Opc == X86::TCRETURNri64_ImpCall ||
483 Opc == X86::TAILJMPr64_REX || Opc == X86::TAILJMPm64_REX;
484}
485
487 if (Subtarget->hardenSlsRet() || Subtarget->hardenSlsIJmp()) {
488 auto I = MBB.getLastNonDebugInstr();
489 if (I != MBB.end()) {
490 if ((Subtarget->hardenSlsRet() && isSimpleReturn(*I)) ||
491 (Subtarget->hardenSlsIJmp() && isIndirectBranchOrTailCall(*I))) {
492 MCInst TmpInst;
493 TmpInst.setOpcode(X86::INT3);
494 EmitToStreamer(*OutStreamer, TmpInst);
495 }
496 }
497 }
498 if (SplitChainedAtEndOfBlock) {
499 OutStreamer->emitWinCFISplitChained();
500 // Splitting into a new unwind info implicitly starts a prolog. We have no
501 // instructions to add to the prolog, so immediately end it.
502 OutStreamer->emitWinCFIEndProlog();
503 SplitChainedAtEndOfBlock = false;
504 }
506 SMShadowTracker.emitShadowPadding(*OutStreamer, getSubtargetInfo());
507}
508
509void X86AsmPrinter::PrintMemReference(const MachineInstr *MI, unsigned OpNo,
510 raw_ostream &O, StringRef Modifier) {
511 assert(isMem(*MI, OpNo) && "Invalid memory reference!");
512 const MachineOperand &Segment = MI->getOperand(OpNo + X86::AddrSegmentReg);
513 if (Segment.getReg()) {
514 PrintModifiedOperand(MI, OpNo + X86::AddrSegmentReg, O, Modifier);
515 O << ':';
516 }
517 PrintLeaMemReference(MI, OpNo, O, Modifier);
518}
519
520void X86AsmPrinter::PrintIntelMemReference(const MachineInstr *MI,
521 unsigned OpNo, raw_ostream &O,
522 StringRef Modifier) {
523 const MachineOperand &BaseReg = MI->getOperand(OpNo + X86::AddrBaseReg);
524 unsigned ScaleVal = MI->getOperand(OpNo + X86::AddrScaleAmt).getImm();
525 const MachineOperand &IndexReg = MI->getOperand(OpNo + X86::AddrIndexReg);
526 const MachineOperand &DispSpec = MI->getOperand(OpNo + X86::AddrDisp);
527 const MachineOperand &SegReg = MI->getOperand(OpNo + X86::AddrSegmentReg);
528
529 // If we really don't want to print out (rip), don't.
530 bool HasBaseReg = BaseReg.getReg() != 0;
531 if (HasBaseReg && Modifier == "no-rip" && BaseReg.getReg() == X86::RIP)
532 HasBaseReg = false;
533
534 // If we really just want to print out displacement.
535 if ((DispSpec.isGlobal() || DispSpec.isSymbol()) && Modifier == "disp-only") {
536 HasBaseReg = false;
537 }
538
539 // If this has a segment register, print it.
540 if (SegReg.getReg()) {
541 PrintOperand(MI, OpNo + X86::AddrSegmentReg, O);
542 O << ':';
543 }
544
545 O << '[';
546
547 bool NeedPlus = false;
548 if (HasBaseReg) {
549 PrintOperand(MI, OpNo + X86::AddrBaseReg, O);
550 NeedPlus = true;
551 }
552
553 if (IndexReg.getReg()) {
554 if (NeedPlus) O << " + ";
555 if (ScaleVal != 1)
556 O << ScaleVal << '*';
557 PrintOperand(MI, OpNo + X86::AddrIndexReg, O);
558 NeedPlus = true;
559 }
560
561 if (!DispSpec.isImm()) {
562 if (NeedPlus) O << " + ";
563 // Do not add `offset` operator. Matches the behaviour of
564 // X86IntelInstPrinter::printMemReference.
565 PrintSymbolOperand(DispSpec, O);
566 } else {
567 int64_t DispVal = DispSpec.getImm();
568 if (DispVal || (!IndexReg.getReg() && !HasBaseReg)) {
569 if (NeedPlus) {
570 if (DispVal > 0)
571 O << " + ";
572 else {
573 O << " - ";
574 DispVal = -DispVal;
575 }
576 }
577 O << DispVal;
578 }
579 }
580 O << ']';
581}
582
584 assert(Subtarget);
585 return Subtarget;
586}
587
588void X86AsmPrinter::emitMachOIFuncStubBody(Module &M, const GlobalIFunc &GI,
589 MCSymbol *LazyPointer) {
590 // _ifunc:
591 // jmpq *lazy_pointer(%rip)
592
593 OutStreamer->emitInstruction(
594 MCInstBuilder(X86::JMP32m)
595 .addReg(X86::RIP)
596 .addImm(1)
597 .addReg(0)
599 MCSymbolRefExpr::create(LazyPointer, OutContext)))
600 .addReg(0),
601 *Subtarget);
602}
603
604void X86AsmPrinter::emitMachOIFuncStubHelperBody(Module &M,
605 const GlobalIFunc &GI,
606 MCSymbol *LazyPointer) {
607 // _ifunc.stub_helper:
608 // push %rax
609 // push %rdi
610 // push %rsi
611 // push %rdx
612 // push %rcx
613 // push %r8
614 // push %r9
615 // callq foo
616 // movq %rax,lazy_pointer(%rip)
617 // pop %r9
618 // pop %r8
619 // pop %rcx
620 // pop %rdx
621 // pop %rsi
622 // pop %rdi
623 // pop %rax
624 // jmpq *lazy_pointer(%rip)
625
626 for (int Reg :
627 {X86::RAX, X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8, X86::R9})
628 OutStreamer->emitInstruction(MCInstBuilder(X86::PUSH64r).addReg(Reg),
629 *Subtarget);
630
631 OutStreamer->emitInstruction(
632 MCInstBuilder(X86::CALL64pcrel32)
634 *Subtarget);
635
636 OutStreamer->emitInstruction(
637 MCInstBuilder(X86::MOV64mr)
638 .addReg(X86::RIP)
639 .addImm(1)
640 .addReg(0)
642 MCSymbolRefExpr::create(LazyPointer, OutContext)))
643 .addReg(0)
644 .addReg(X86::RAX),
645 *Subtarget);
646
647 for (int Reg :
648 {X86::R9, X86::R8, X86::RCX, X86::RDX, X86::RSI, X86::RDI, X86::RAX})
649 OutStreamer->emitInstruction(MCInstBuilder(X86::POP64r).addReg(Reg),
650 *Subtarget);
651
652 OutStreamer->emitInstruction(
653 MCInstBuilder(X86::JMP32m)
654 .addReg(X86::RIP)
655 .addImm(1)
656 .addReg(0)
658 MCSymbolRefExpr::create(LazyPointer, OutContext)))
659 .addReg(0),
660 *Subtarget);
661}
662
663static bool printAsmMRegister(const X86AsmPrinter &P, const MachineOperand &MO,
664 char Mode, raw_ostream &O) {
665 Register Reg = MO.getReg();
666 bool EmitPercent = MO.getParent()->getInlineAsmDialect() == InlineAsm::AD_ATT;
667
668 if (!X86::GR8RegClass.contains(Reg) &&
669 !X86::GR16RegClass.contains(Reg) &&
670 !X86::GR32RegClass.contains(Reg) &&
671 !X86::GR64RegClass.contains(Reg))
672 return true;
673
674 switch (Mode) {
675 default: return true; // Unknown mode.
676 case 'b': // Print QImode register
678 break;
679 case 'h': // Print QImode high register
680 Reg = getX86SubSuperRegister(Reg, 8, true);
681 if (!Reg.isValid())
682 return true;
683 break;
684 case 'w': // Print HImode register
686 break;
687 case 'k': // Print SImode register
689 break;
690 case 'V':
691 EmitPercent = false;
692 [[fallthrough]];
693 case 'q':
694 // Print 64-bit register names if 64-bit integer registers are available.
695 // Otherwise, print 32-bit register names.
696 Reg = getX86SubSuperRegister(Reg, P.getSubtarget().is64Bit() ? 64 : 32);
697 break;
698 }
699
700 if (EmitPercent)
701 O << '%';
702
704 return false;
705}
706
707static bool printAsmVRegister(const MachineOperand &MO, char Mode,
708 raw_ostream &O) {
709 Register Reg = MO.getReg();
710 bool EmitPercent = MO.getParent()->getInlineAsmDialect() == InlineAsm::AD_ATT;
711
712 unsigned Index;
713 if (X86::VR128XRegClass.contains(Reg))
714 Index = Reg - X86::XMM0;
715 else if (X86::VR256XRegClass.contains(Reg))
716 Index = Reg - X86::YMM0;
717 else if (X86::VR512RegClass.contains(Reg))
718 Index = Reg - X86::ZMM0;
719 else
720 return true;
721
722 switch (Mode) {
723 default: // Unknown mode.
724 return true;
725 case 'x': // Print V4SFmode register
726 Reg = X86::XMM0 + Index;
727 break;
728 case 't': // Print V8SFmode register
729 Reg = X86::YMM0 + Index;
730 break;
731 case 'g': // Print V16SFmode register
732 Reg = X86::ZMM0 + Index;
733 break;
734 }
735
736 if (EmitPercent)
737 O << '%';
738
740 return false;
741}
742
743/// PrintAsmOperand - Print out an operand for an inline asm expression.
744///
746 const char *ExtraCode, raw_ostream &O) {
747 // Does this asm operand have a single letter operand modifier?
748 if (ExtraCode && ExtraCode[0]) {
749 if (ExtraCode[1] != 0) return true; // Unknown modifier.
750
751 const MachineOperand &MO = MI->getOperand(OpNo);
752
753 switch (ExtraCode[0]) {
754 default:
755 // See if this is a generic print operand
756 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
757 case 'a': // This is an address. Currently only 'i' and 'r' are expected.
758 switch (MO.getType()) {
759 default:
760 return true;
762 O << MO.getImm();
763 return false;
767 llvm_unreachable("unexpected operand type!");
769 PrintSymbolOperand(MO, O);
770 if (Subtarget->is64Bit())
771 O << "(%rip)";
772 return false;
774 O << '(';
775 PrintOperand(MI, OpNo, O);
776 O << ')';
777 return false;
778 }
779
780 case 'c': // Don't print "$" before a global var name or constant.
781 switch (MO.getType()) {
782 default:
783 PrintOperand(MI, OpNo, O);
784 break;
786 O << MO.getImm();
787 break;
791 llvm_unreachable("unexpected operand type!");
793 PrintSymbolOperand(MO, O);
794 break;
795 }
796 return false;
797
798 case 'A': // Print '*' before a register (it must be a register)
799 if (MO.isReg()) {
800 O << '*';
801 PrintOperand(MI, OpNo, O);
802 return false;
803 }
804 return true;
805
806 case 'b': // Print QImode register
807 case 'h': // Print QImode high register
808 case 'w': // Print HImode register
809 case 'k': // Print SImode register
810 case 'q': // Print DImode register
811 case 'V': // Print native register without '%'
812 if (MO.isReg())
813 return printAsmMRegister(*this, MO, ExtraCode[0], O);
814 PrintOperand(MI, OpNo, O);
815 return false;
816
817 case 'x': // Print V4SFmode register
818 case 't': // Print V8SFmode register
819 case 'g': // Print V16SFmode register
820 if (MO.isReg())
821 return printAsmVRegister(MO, ExtraCode[0], O);
822 PrintOperand(MI, OpNo, O);
823 return false;
824
825 case 'p': {
826 const MachineOperand &MO = MI->getOperand(OpNo);
828 return true;
829 PrintSymbolOperand(MO, O);
830 return false;
831 }
832
833 case 'P': // This is the operand of a call, treat specially.
834 PrintPCRelImm(MI, OpNo, O);
835 return false;
836
837 case 'n': // Negate the immediate or print a '-' before the operand.
838 // Note: this is a temporary solution. It should be handled target
839 // independently as part of the 'MC' work.
840 if (MO.isImm()) {
841 O << -MO.getImm();
842 return false;
843 }
844 O << '-';
845 }
846 }
847
848 PrintOperand(MI, OpNo, O);
849 return false;
850}
851
853 const char *ExtraCode,
854 raw_ostream &O) {
855 if (ExtraCode && ExtraCode[0]) {
856 if (ExtraCode[1] != 0) return true; // Unknown modifier.
857
858 switch (ExtraCode[0]) {
859 default: return true; // Unknown modifier.
860 case 'b': // Print QImode register
861 case 'h': // Print QImode high register
862 case 'w': // Print HImode register
863 case 'k': // Print SImode register
864 case 'q': // Print SImode register
865 // These only apply to registers, ignore on mem.
866 break;
867 case 'H':
868 if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
869 return true; // Unsupported modifier in Intel inline assembly.
870 } else {
871 PrintMemReference(MI, OpNo, O, "H");
872 }
873 return false;
874 // Print memory only with displacement. The Modifer 'P' is used in inline
875 // asm to present a call symbol or a global symbol which can not use base
876 // reg or index reg.
877 case 'P':
878 if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
879 PrintIntelMemReference(MI, OpNo, O, "disp-only");
880 } else {
881 PrintMemReference(MI, OpNo, O, "disp-only");
882 }
883 return false;
884 }
885 }
886 if (MI->getInlineAsmDialect() == InlineAsm::AD_Intel) {
887 PrintIntelMemReference(MI, OpNo, O);
888 } else {
889 PrintMemReference(MI, OpNo, O);
890 }
891 return false;
892}
893
895 const Triple &TT = TM.getTargetTriple();
896
897 if (TT.isOSBinFormatELF()) {
898 // Assemble feature flags that may require creation of a note section.
899 unsigned FeatureFlagsAnd = 0;
900 if (M.getModuleFlag("cf-protection-branch"))
901 FeatureFlagsAnd |= ELF::GNU_PROPERTY_X86_FEATURE_1_IBT;
902 if (M.getModuleFlag("cf-protection-return"))
903 FeatureFlagsAnd |= ELF::GNU_PROPERTY_X86_FEATURE_1_SHSTK;
904
905 if (FeatureFlagsAnd) {
906 // Emit a .note.gnu.property section with the flags.
907 assert((TT.isX86_32() || TT.isX86_64()) &&
908 "CFProtection used on invalid architecture!");
909 MCSection *Cur = OutStreamer->getCurrentSectionOnly();
910 MCSection *Nt = MMI->getContext().getELFSection(
911 ".note.gnu.property", ELF::SHT_NOTE, ELF::SHF_ALLOC);
912 OutStreamer->switchSection(Nt);
913
914 // Emitting note header.
915 const int WordSize = TT.isX86_64() && !TT.isX32() ? 8 : 4;
916 emitAlignment(WordSize == 4 ? Align(4) : Align(8));
917 OutStreamer->emitIntValue(4, 4 /*size*/); // data size for "GNU\0"
918 OutStreamer->emitIntValue(8 + WordSize, 4 /*size*/); // Elf_Prop size
919 OutStreamer->emitIntValue(ELF::NT_GNU_PROPERTY_TYPE_0, 4 /*size*/);
920 OutStreamer->emitBytes(StringRef("GNU", 4)); // note name
921
922 // Emitting an Elf_Prop for the CET properties.
924 OutStreamer->emitInt32(4); // data size
925 OutStreamer->emitInt32(FeatureFlagsAnd); // data
926 emitAlignment(WordSize == 4 ? Align(4) : Align(8)); // padding
927
928 OutStreamer->switchSection(Cur);
929 }
930 }
931
932 if (TT.isOSBinFormatMachO())
933 OutStreamer->switchSection(getObjFileLowering().getTextSection());
934
935 if (TT.isOSBinFormatCOFF()) {
938
939 if (M.getModuleFlag("import-call-optimization"))
940 EnableImportCallOptimization = true;
941 }
942
943 // TODO: Support prefixed registers for the Intel syntax.
944 const bool IntelSyntax = MAI->getAssemblerDialect() == InlineAsm::AD_Intel;
945 OutStreamer->emitSyntaxDirective(IntelSyntax ? "intel" : "att",
946 IntelSyntax ? "noprefix" : "");
947
948 // If this is not inline asm and we're in 16-bit
949 // mode prefix assembly with .code16.
950 bool is16 = TT.getEnvironment() == Triple::CODE16;
951 if (M.getModuleInlineAsm().empty() && is16) {
952 auto *XTS =
953 static_cast<X86TargetStreamer *>(OutStreamer->getTargetStreamer());
954 XTS->emitCode16();
955 }
956}
957
958static void
961 // L_foo$stub:
962 OutStreamer.emitLabel(StubLabel);
963 // .indirect_symbol _foo
965
966 if (MCSym.getInt())
967 // External to current translation unit.
968 OutStreamer.emitIntValue(0, 4/*size*/);
969 else
970 // Internal to current translation unit.
971 //
972 // When we place the LSDA into the TEXT section, the type info
973 // pointers need to be indirect and pc-rel. We accomplish this by
974 // using NLPs; however, sometimes the types are local to the file.
975 // We need to fill in the value for the NLP in those cases.
976 OutStreamer.emitValue(
977 MCSymbolRefExpr::create(MCSym.getPointer(), OutStreamer.getContext()),
978 4 /*size*/);
979}
980
981static void emitNonLazyStubs(MachineModuleInfo *MMI, MCStreamer &OutStreamer) {
982
983 MachineModuleInfoMachO &MMIMacho =
985
986 // Output stubs for dynamically-linked functions.
988
989 // Output stubs for external and common global variables.
990 Stubs = MMIMacho.GetGVStubList();
991 if (!Stubs.empty()) {
992 OutStreamer.switchSection(MMI->getContext().getMachOSection(
993 "__IMPORT", "__pointers", MachO::S_NON_LAZY_SYMBOL_POINTERS,
995
996 for (auto &Stub : Stubs)
997 emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second);
998
999 Stubs.clear();
1000 OutStreamer.addBlankLine();
1001 }
1002}
1003
1004/// True if this module is being built for windows/msvc, and uses floating
1005/// point. This is used to emit an undefined reference to _fltused. This is
1006/// needed in Windows kernel or driver contexts to find and prevent code from
1007/// modifying non-GPR registers.
1008///
1009/// TODO: It would be better if this was computed from MIR by looking for
1010/// selected floating-point instructions.
1011static bool usesMSVCFloatingPoint(const Triple &TT, const Module &M) {
1012 // Only needed for MSVC
1013 if (!TT.isWindowsMSVCEnvironment())
1014 return false;
1015
1016 for (const Function &F : M) {
1017 for (const Instruction &I : instructions(F)) {
1018 if (I.getType()->isFloatingPointTy())
1019 return true;
1020
1021 for (const auto &Op : I.operands()) {
1022 if (Op->getType()->isFloatingPointTy())
1023 return true;
1024 }
1025 }
1026 }
1027
1028 return false;
1029}
1030
1032 const Triple &TT = TM.getTargetTriple();
1033
1034 if (TT.isOSBinFormatMachO()) {
1035 // Mach-O uses non-lazy symbol stubs to encode per-TU information into
1036 // global table for symbol lookup.
1038
1039 // Emit fault map information.
1040 FM.serializeToFaultMapSection();
1041
1042 // This flag tells the linker that no global symbols contain code that fall
1043 // through to other global symbols (e.g. an implementation of multiple entry
1044 // points). If this doesn't occur, the linker can safely perform dead code
1045 // stripping. Since LLVM never generates code that does this, it is always
1046 // safe to set.
1047 OutStreamer->emitSubsectionsViaSymbols();
1048 } else if (TT.isOSBinFormatCOFF()) {
1049 // If import call optimization is enabled, emit the appropriate section.
1050 // We do this whether or not we recorded any items.
1051 if (EnableImportCallOptimization) {
1052 OutStreamer->switchSection(getObjFileLowering().getImportCallSection());
1053
1054 // Section always starts with some magic.
1055 constexpr char ImpCallMagic[12] = "RetpolineV1";
1056 OutStreamer->emitBytes(StringRef{ImpCallMagic, sizeof(ImpCallMagic)});
1057
1058 // Layout of this section is:
1059 // Per section that contains an item to record:
1060 // uint32_t SectionSize: Size in bytes for information in this section.
1061 // uint32_t Section Number
1062 // Per call to imported function in section:
1063 // uint32_t Kind: the kind of item.
1064 // uint32_t InstOffset: the offset of the instr in its parent section.
1065 for (auto &[Section, CallsToImportedFuncs] :
1066 SectionToImportedFunctionCalls) {
1067 unsigned SectionSize =
1068 sizeof(uint32_t) * (2 + 2 * CallsToImportedFuncs.size());
1069 OutStreamer->emitInt32(SectionSize);
1070 OutStreamer->emitCOFFSecNumber(Section->getBeginSymbol());
1071 for (auto &[CallsiteSymbol, Kind] : CallsToImportedFuncs) {
1072 OutStreamer->emitInt32(Kind);
1073 OutStreamer->emitCOFFSecOffset(CallsiteSymbol);
1074 }
1075 }
1076 }
1077
1078 if (usesMSVCFloatingPoint(TT, M)) {
1079 // In Windows' libcmt.lib, there is a file which is linked in only if the
1080 // symbol _fltused is referenced. Linking this in causes some
1081 // side-effects:
1082 //
1083 // 1. For x86-32, it will set the x87 rounding mode to 53-bit instead of
1084 // 64-bit mantissas at program start.
1085 //
1086 // 2. It links in support routines for floating-point in scanf and printf.
1087 //
1088 // MSVC emits an undefined reference to _fltused when there are any
1089 // floating point operations in the program (including calls). A program
1090 // that only has: `scanf("%f", &global_float);` may fail to trigger this,
1091 // but oh well...that's a documented issue.
1092 StringRef SymbolName =
1093 (TT.getArch() == Triple::x86) ? "__fltused" : "_fltused";
1094 MCSymbol *S = MMI->getContext().getOrCreateSymbol(SymbolName);
1095 OutStreamer->emitSymbolAttribute(S, MCSA_Global);
1096 return;
1097 }
1098 } else if (TT.isOSBinFormatELF()) {
1099 FM.serializeToFaultMapSection();
1100 }
1101
1102 // Emit __morestack address if needed for indirect calls.
1103 if (TT.isX86_64() && TM.getCodeModel() == CodeModel::Large) {
1104 if (MCSymbol *AddrSymbol = OutContext.lookupSymbol("__morestack_addr")) {
1105 Align Alignment(1);
1108 /*C=*/nullptr, Alignment);
1109 OutStreamer->switchSection(ReadOnlySection);
1110 OutStreamer->emitLabel(AddrSymbol);
1111
1112 unsigned PtrSize = MAI->getCodePointerSize();
1113 OutStreamer->emitSymbolValue(GetExternalSymbolSymbol("__morestack"),
1114 PtrSize);
1115 }
1116 }
1117}
1118
1119char X86AsmPrinter::ID = 0;
1120
1121INITIALIZE_PASS(X86AsmPrinter, "x86-asm-printer", "X86 Assembly Printer", false,
1122 false)
1123
1124//===----------------------------------------------------------------------===//
1125// Target Registry Stuff
1126//===----------------------------------------------------------------------===//
1127
1128// Force static initialization.
1129extern "C" LLVM_C_ABI void LLVMInitializeX86AsmPrinter() {
1132}
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
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define P(N)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:487
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
#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)
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
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
void emitNops(unsigned N)
Emit N NOP instructions.
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
TargetMachine & TM
Target machine description.
Definition AsmPrinter.h:94
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:97
MachineFunction * MF
The current machine function.
Definition AsmPrinter.h:109
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.
AsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer, char &ID=AsmPrinter::ID)
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.
MCSymbol * CurrentFnSym
The symbol for the current function.
Definition AsmPrinter.h:128
MachineModuleInfo * MMI
This is a pointer to the current MachineModuleInfo.
Definition AsmPrinter.h:112
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:101
const StaticDataProfileInfo * SDPI
Provides the profile information for constants.
Definition AsmPrinter.h:147
virtual const MCSubtargetInfo * getIFuncMCSubtargetInfo() const
getSubtargetInfo() cannot be used where this is needed because we don't have a MachineFunction when w...
Definition AsmPrinter.h:661
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition AsmPrinter.h:106
const ProfileSummaryInfo * PSI
The profile summary information.
Definition AsmPrinter.h:150
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.
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.
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.
This is the shared class of boolean and integer constants.
Definition Constants.h:87
const Constant * getResolver() const
Definition GlobalIFunc.h:73
bool hasInternalLinkage() const
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.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
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:517
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())
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
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.
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:1080
Representation of each machine instruction.
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.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
AnalysisType * getAnalysisIfAvailable() const
getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to get analysis information tha...
IntType getInt() const
PointerTy getPointer() const
Wrapper class representing virtual and physical registers.
Definition Register.h:20
static SectionKind getMetadata()
static SectionKind getReadOnly()
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:143
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition StringRef.h:637
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.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
bool isX86_64() const
Tests whether the target is x86 (64-bit).
Definition Triple.h:1146
bool isOSWindows() const
Tests whether the OS is Windows.
Definition Triple.h:700
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...
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
@ NT_GNU_PROPERTY_TYPE_0
Definition ELF.h:1810
@ SHF_ALLOC
Definition ELF.h:1248
@ SHT_NOTE
Definition ELF.h:1153
@ GNU_PROPERTY_X86_FEATURE_1_AND
Definition ELF.h:1845
@ GNU_PROPERTY_X86_FEATURE_1_SHSTK
Definition ELF.h:1892
@ GNU_PROPERTY_X86_FEATURE_1_IBT
Definition ELF.h:1891
@ S_NON_LAZY_SYMBOL_POINTERS
S_NON_LAZY_SYMBOL_POINTERS - Section with non-lazy symbol pointers.
Definition MachO.h:139
@ MO_TLSLD
MO_TLSLD - On a symbol operand this indicates that the immediate is the offset of the GOT entry with ...
@ MO_GOTPCREL_NORELAX
MO_GOTPCREL_NORELAX - Same as MO_GOTPCREL except that R_X86_64_GOTPCREL relocations are guaranteed to...
@ MO_GOTOFF
MO_GOTOFF - On a symbol operand this indicates that the immediate is the offset to the location of th...
@ MO_DARWIN_NONLAZY_PIC_BASE
MO_DARWIN_NONLAZY_PIC_BASE - On a symbol operand "FOO", this indicates that the reference is actually...
@ MO_GOT_ABSOLUTE_ADDRESS
MO_GOT_ABSOLUTE_ADDRESS - On a symbol operand, this represents a relocation of: SYMBOL_LABEL + [.
@ MO_COFFSTUB
MO_COFFSTUB - On a symbol operand "FOO", this indicates that the reference is actually to the "....
@ MO_NTPOFF
MO_NTPOFF - On a symbol operand this indicates that the immediate is the negative thread-pointer offs...
@ MO_DARWIN_NONLAZY
MO_DARWIN_NONLAZY - On a symbol operand "FOO", this indicates that the reference is actually to the "...
@ MO_INDNTPOFF
MO_INDNTPOFF - On a symbol operand this indicates that the immediate is the absolute address of the G...
@ MO_GOTNTPOFF
MO_GOTNTPOFF - On a symbol operand this indicates that the immediate is the offset of the GOT entry w...
@ MO_TPOFF
MO_TPOFF - On a symbol operand this indicates that the immediate is the thread-pointer offset for the...
@ MO_TLVP_PIC_BASE
MO_TLVP_PIC_BASE - On a symbol operand this indicates that the immediate is some TLS offset from the ...
@ MO_GOT
MO_GOT - On a symbol operand this indicates that the immediate is the offset to the GOT entry for the...
@ MO_PLT
MO_PLT - On a symbol operand this indicates that the immediate is offset to the PLT entry of symbol n...
@ MO_TLSGD
MO_TLSGD - On a symbol operand this indicates that the immediate is the offset of the GOT entry with ...
@ MO_NO_FLAG
MO_NO_FLAG - No flag for the operand.
@ MO_TLVP
MO_TLVP - On a symbol operand this indicates that the immediate is some TLS offset.
@ MO_DLLIMPORT
MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the reference is actually to the "__imp...
@ MO_GOTTPOFF
MO_GOTTPOFF - On a symbol operand this indicates that the immediate is the offset of the GOT entry wi...
@ MO_SECREL
MO_SECREL - On a symbol operand this indicates that the immediate is the offset from beginning of sec...
@ MO_DTPOFF
MO_DTPOFF - On a symbol operand this indicates that the immediate is the offset of the GOT entry with...
@ MO_PIC_BASE_OFFSET
MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the immediate should get the value of th...
@ MO_TLSLDM
MO_TLSLDM - On a symbol operand this indicates that the immediate is the offset of the GOT entry with...
@ MO_GOTPCREL
MO_GOTPCREL - On a symbol operand this indicates that the immediate is offset to the GOT entry for th...
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
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 Types.h:26
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
static bool isMem(const MachineInstr &MI, unsigned Op)
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:186
DWARFExpression::Operation Op
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:1915
Target & getTheX86_64Target()
@ MCSA_IndirectSymbol
.indirect_symbol (MachO)
@ MCSA_Global
.type _foo, @gnu_unique_object
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#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,...