LLVM  3.7.0
AArch64AsmPrinter.cpp
Go to the documentation of this file.
1 //===-- AArch64AsmPrinter.cpp - AArch64 LLVM assembly writer --------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains a printer that converts from our internal representation
11 // of machine-dependent LLVM code to the AArch64 assembly language.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "AArch64.h"
17 #include "AArch64MCInstLower.h"
19 #include "AArch64RegisterInfo.h"
20 #include "AArch64Subtarget.h"
23 #include "llvm/ADT/SmallString.h"
24 #include "llvm/ADT/StringSwitch.h"
25 #include "llvm/ADT/Twine.h"
29 #include "llvm/CodeGen/StackMaps.h"
31 #include "llvm/IR/DataLayout.h"
32 #include "llvm/IR/DebugInfo.h"
33 #include "llvm/MC/MCAsmInfo.h"
34 #include "llvm/MC/MCContext.h"
35 #include "llvm/MC/MCInst.h"
36 #include "llvm/MC/MCInstBuilder.h"
38 #include "llvm/MC/MCStreamer.h"
39 #include "llvm/MC/MCSymbol.h"
40 #include "llvm/Support/Debug.h"
43 using namespace llvm;
44 
45 #define DEBUG_TYPE "asm-printer"
46 
47 namespace {
48 
49 class AArch64AsmPrinter : public AsmPrinter {
50  AArch64MCInstLower MCInstLowering;
51  StackMaps SM;
52 
53 public:
54  AArch64AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
55  : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(OutContext, *this),
56  SM(*this), AArch64FI(nullptr) {}
57 
58  const char *getPassName() const override {
59  return "AArch64 Assembly Printer";
60  }
61 
62  /// \brief Wrapper for MCInstLowering.lowerOperand() for the
63  /// tblgen'erated pseudo lowering.
64  bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const {
65  return MCInstLowering.lowerOperand(MO, MCOp);
66  }
67 
68  void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
69  const MachineInstr &MI);
70  void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
71  const MachineInstr &MI);
72  /// \brief tblgen'erated driver function for lowering simple MI->MC
73  /// pseudo instructions.
74  bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
75  const MachineInstr *MI);
76 
77  void EmitInstruction(const MachineInstr *MI) override;
78 
79  void getAnalysisUsage(AnalysisUsage &AU) const override {
81  AU.setPreservesAll();
82  }
83 
84  bool runOnMachineFunction(MachineFunction &F) override {
85  AArch64FI = F.getInfo<AArch64FunctionInfo>();
87  }
88 
89 private:
90  MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
91  void printOperand(const MachineInstr *MI, unsigned OpNum, raw_ostream &O);
92  bool printAsmMRegister(const MachineOperand &MO, char Mode, raw_ostream &O);
93  bool printAsmRegInClass(const MachineOperand &MO,
94  const TargetRegisterClass *RC, bool isVector,
95  raw_ostream &O);
96 
97  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
98  unsigned AsmVariant, const char *ExtraCode,
99  raw_ostream &O) override;
100  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
101  unsigned AsmVariant, const char *ExtraCode,
102  raw_ostream &O) override;
103 
104  void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
105 
106  void EmitFunctionBodyEnd() override;
107 
108  MCSymbol *GetCPISymbol(unsigned CPID) const override;
109  void EmitEndOfAsmFile(Module &M) override;
110  AArch64FunctionInfo *AArch64FI;
111 
112  /// \brief Emit the LOHs contained in AArch64FI.
113  void EmitLOHs();
114 
115  typedef std::map<const MachineInstr *, MCSymbol *> MInstToMCSymbol;
116  MInstToMCSymbol LOHInstToLabel;
117 };
118 
119 } // end of anonymous namespace
120 
121 //===----------------------------------------------------------------------===//
122 
123 void AArch64AsmPrinter::EmitEndOfAsmFile(Module &M) {
124  const Triple &TT = TM.getTargetTriple();
125  if (TT.isOSBinFormatMachO()) {
126  // Funny Darwin hack: This flag tells the linker that no global symbols
127  // contain code that falls through to other global symbols (e.g. the obvious
128  // implementation of multiple entry points). If this doesn't occur, the
129  // linker can safely perform dead code stripping. Since LLVM never
130  // generates code that does this, it is always safe to set.
131  OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
132  SM.serializeToStackMapSection();
133  }
134 }
135 
137 AArch64AsmPrinter::getDebugValueLocation(const MachineInstr *MI) const {
138  MachineLocation Location;
139  assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands!");
140  // Frame address. Currently handles register +- offset only.
141  if (MI->getOperand(0).isReg() && MI->getOperand(1).isImm())
142  Location.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
143  else {
144  DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n");
145  }
146  return Location;
147 }
148 
149 void AArch64AsmPrinter::EmitLOHs() {
151 
152  for (const auto &D : AArch64FI->getLOHContainer()) {
153  for (const MachineInstr *MI : D.getArgs()) {
154  MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(MI);
155  assert(LabelIt != LOHInstToLabel.end() &&
156  "Label hasn't been inserted for LOH related instruction");
157  MCArgs.push_back(LabelIt->second);
158  }
159  OutStreamer->EmitLOHDirective(D.getKind(), MCArgs);
160  MCArgs.clear();
161  }
162 }
163 
164 void AArch64AsmPrinter::EmitFunctionBodyEnd() {
165  if (!AArch64FI->getLOHRelated().empty())
166  EmitLOHs();
167 }
168 
169 /// GetCPISymbol - Return the symbol for the specified constant pool entry.
170 MCSymbol *AArch64AsmPrinter::GetCPISymbol(unsigned CPID) const {
171  // Darwin uses a linker-private symbol name for constant-pools (to
172  // avoid addends on the relocation?), ELF has no such concept and
173  // uses a normal private symbol.
174  if (getDataLayout().getLinkerPrivateGlobalPrefix()[0])
175  return OutContext.getOrCreateSymbol(
176  Twine(getDataLayout().getLinkerPrivateGlobalPrefix()) + "CPI" +
177  Twine(getFunctionNumber()) + "_" + Twine(CPID));
178 
179  return OutContext.getOrCreateSymbol(
180  Twine(getDataLayout().getPrivateGlobalPrefix()) + "CPI" +
181  Twine(getFunctionNumber()) + "_" + Twine(CPID));
182 }
183 
184 void AArch64AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNum,
185  raw_ostream &O) {
186  const MachineOperand &MO = MI->getOperand(OpNum);
187  switch (MO.getType()) {
188  default:
189  llvm_unreachable("<unknown operand type>");
191  unsigned Reg = MO.getReg();
193  assert(!MO.getSubReg() && "Subregs should be eliminated!");
195  break;
196  }
198  int64_t Imm = MO.getImm();
199  O << '#' << Imm;
200  break;
201  }
203  const GlobalValue *GV = MO.getGlobal();
204  MCSymbol *Sym = getSymbol(GV);
205 
206  // FIXME: Can we get anything other than a plain symbol here?
207  assert(!MO.getTargetFlags() && "Unknown operand target flag!");
208 
209  Sym->print(O, MAI);
210  printOffset(MO.getOffset(), O);
211  break;
212  }
213  }
214 }
215 
216 bool AArch64AsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode,
217  raw_ostream &O) {
218  unsigned Reg = MO.getReg();
219  switch (Mode) {
220  default:
221  return true; // Unknown mode.
222  case 'w':
223  Reg = getWRegFromXReg(Reg);
224  break;
225  case 'x':
226  Reg = getXRegFromWReg(Reg);
227  break;
228  }
229 
231  return false;
232 }
233 
234 // Prints the register in MO using class RC using the offset in the
235 // new register class. This should not be used for cross class
236 // printing.
237 bool AArch64AsmPrinter::printAsmRegInClass(const MachineOperand &MO,
238  const TargetRegisterClass *RC,
239  bool isVector, raw_ostream &O) {
240  assert(MO.isReg() && "Should only get here with a register!");
241  const AArch64RegisterInfo *RI =
242  MF->getSubtarget<AArch64Subtarget>().getRegisterInfo();
243  unsigned Reg = MO.getReg();
244  unsigned RegToPrint = RC->getRegister(RI->getEncodingValue(Reg));
245  assert(RI->regsOverlap(RegToPrint, Reg));
247  RegToPrint, isVector ? AArch64::vreg : AArch64::NoRegAltName);
248  return false;
249 }
250 
251 bool AArch64AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
252  unsigned AsmVariant,
253  const char *ExtraCode, raw_ostream &O) {
254  const MachineOperand &MO = MI->getOperand(OpNum);
255 
256  // First try the generic code, which knows about modifiers like 'c' and 'n'.
257  if (!AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O))
258  return false;
259 
260  // Does this asm operand have a single letter operand modifier?
261  if (ExtraCode && ExtraCode[0]) {
262  if (ExtraCode[1] != 0)
263  return true; // Unknown modifier.
264 
265  switch (ExtraCode[0]) {
266  default:
267  return true; // Unknown modifier.
268  case 'w': // Print W register
269  case 'x': // Print X register
270  if (MO.isReg())
271  return printAsmMRegister(MO, ExtraCode[0], O);
272  if (MO.isImm() && MO.getImm() == 0) {
273  unsigned Reg = ExtraCode[0] == 'w' ? AArch64::WZR : AArch64::XZR;
275  return false;
276  }
277  printOperand(MI, OpNum, O);
278  return false;
279  case 'b': // Print B register.
280  case 'h': // Print H register.
281  case 's': // Print S register.
282  case 'd': // Print D register.
283  case 'q': // Print Q register.
284  if (MO.isReg()) {
285  const TargetRegisterClass *RC;
286  switch (ExtraCode[0]) {
287  case 'b':
288  RC = &AArch64::FPR8RegClass;
289  break;
290  case 'h':
291  RC = &AArch64::FPR16RegClass;
292  break;
293  case 's':
294  RC = &AArch64::FPR32RegClass;
295  break;
296  case 'd':
297  RC = &AArch64::FPR64RegClass;
298  break;
299  case 'q':
300  RC = &AArch64::FPR128RegClass;
301  break;
302  default:
303  return true;
304  }
305  return printAsmRegInClass(MO, RC, false /* vector */, O);
306  }
307  printOperand(MI, OpNum, O);
308  return false;
309  }
310  }
311 
312  // According to ARM, we should emit x and v registers unless we have a
313  // modifier.
314  if (MO.isReg()) {
315  unsigned Reg = MO.getReg();
316 
317  // If this is a w or x register, print an x register.
318  if (AArch64::GPR32allRegClass.contains(Reg) ||
319  AArch64::GPR64allRegClass.contains(Reg))
320  return printAsmMRegister(MO, 'x', O);
321 
322  // If this is a b, h, s, d, or q register, print it as a v register.
323  return printAsmRegInClass(MO, &AArch64::FPR128RegClass, true /* vector */,
324  O);
325  }
326 
327  printOperand(MI, OpNum, O);
328  return false;
329 }
330 
331 bool AArch64AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
332  unsigned OpNum,
333  unsigned AsmVariant,
334  const char *ExtraCode,
335  raw_ostream &O) {
336  if (ExtraCode && ExtraCode[0])
337  return true; // Unknown modifier.
338 
339  const MachineOperand &MO = MI->getOperand(OpNum);
340  assert(MO.isReg() && "unexpected inline asm memory operand");
341  O << "[" << AArch64InstPrinter::getRegisterName(MO.getReg()) << "]";
342  return false;
343 }
344 
345 void AArch64AsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
346  raw_ostream &OS) {
347  unsigned NOps = MI->getNumOperands();
348  assert(NOps == 4);
349  OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
350  // cast away const; DIetc do not take const operands for some reason.
351  OS << cast<DILocalVariable>(MI->getOperand(NOps - 2).getMetadata())
352  ->getName();
353  OS << " <- ";
354  // Frame address. Currently handles register +- offset only.
355  assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm());
356  OS << '[';
357  printOperand(MI, 0, OS);
358  OS << '+';
359  printOperand(MI, 1, OS);
360  OS << ']';
361  OS << "+";
362  printOperand(MI, NOps - 2, OS);
363 }
364 
365 void AArch64AsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
366  const MachineInstr &MI) {
367  unsigned NumNOPBytes = MI.getOperand(1).getImm();
368 
369  SM.recordStackMap(MI);
370  assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
371 
372  // Scan ahead to trim the shadow.
373  const MachineBasicBlock &MBB = *MI.getParent();
375  ++MII;
376  while (NumNOPBytes > 0) {
377  if (MII == MBB.end() || MII->isCall() ||
378  MII->getOpcode() == AArch64::DBG_VALUE ||
379  MII->getOpcode() == TargetOpcode::PATCHPOINT ||
380  MII->getOpcode() == TargetOpcode::STACKMAP)
381  break;
382  ++MII;
383  NumNOPBytes -= 4;
384  }
385 
386  // Emit nops.
387  for (unsigned i = 0; i < NumNOPBytes; i += 4)
388  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
389 }
390 
391 // Lower a patchpoint of the form:
392 // [<def>], <id>, <numBytes>, <target>, <numArgs>
393 void AArch64AsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
394  const MachineInstr &MI) {
395  SM.recordPatchPoint(MI);
396 
397  PatchPointOpers Opers(&MI);
398 
399  int64_t CallTarget = Opers.getMetaOper(PatchPointOpers::TargetPos).getImm();
400  unsigned EncodedBytes = 0;
401  if (CallTarget) {
402  assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
403  "High 16 bits of call target should be zero.");
404  unsigned ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
405  EncodedBytes = 16;
406  // Materialize the jump address:
407  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::MOVZWi)
408  .addReg(ScratchReg)
409  .addImm((CallTarget >> 32) & 0xFFFF)
410  .addImm(32));
411  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::MOVKWi)
412  .addReg(ScratchReg)
413  .addReg(ScratchReg)
414  .addImm((CallTarget >> 16) & 0xFFFF)
415  .addImm(16));
416  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::MOVKWi)
417  .addReg(ScratchReg)
418  .addReg(ScratchReg)
419  .addImm(CallTarget & 0xFFFF)
420  .addImm(0));
421  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::BLR).addReg(ScratchReg));
422  }
423  // Emit padding.
424  unsigned NumBytes = Opers.getMetaOper(PatchPointOpers::NBytesPos).getImm();
425  assert(NumBytes >= EncodedBytes &&
426  "Patchpoint can't request size less than the length of a call.");
427  assert((NumBytes - EncodedBytes) % 4 == 0 &&
428  "Invalid number of NOP bytes requested!");
429  for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
430  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
431 }
432 
433 // Simple pseudo-instructions have their lowering (with expansion to real
434 // instructions) auto-generated.
435 #include "AArch64GenMCPseudoLowering.inc"
436 
437 void AArch64AsmPrinter::EmitInstruction(const MachineInstr *MI) {
438  // Do any auto-generated pseudo lowerings.
439  if (emitPseudoExpansionLowering(*OutStreamer, MI))
440  return;
441 
442  if (AArch64FI->getLOHRelated().count(MI)) {
443  // Generate a label for LOH related instruction
444  MCSymbol *LOHLabel = createTempSymbol("loh");
445  // Associate the instruction with the label
446  LOHInstToLabel[MI] = LOHLabel;
447  OutStreamer->EmitLabel(LOHLabel);
448  }
449 
450  // Do any manual lowerings.
451  switch (MI->getOpcode()) {
452  default:
453  break;
454  case AArch64::DBG_VALUE: {
455  if (isVerbose() && OutStreamer->hasRawTextSupport()) {
456  SmallString<128> TmpStr;
457  raw_svector_ostream OS(TmpStr);
458  PrintDebugValueComment(MI, OS);
459  OutStreamer->EmitRawText(StringRef(OS.str()));
460  }
461  return;
462  }
463 
464  // Tail calls use pseudo instructions so they have the proper code-gen
465  // attributes (isCall, isReturn, etc.). We lower them to the real
466  // instruction here.
467  case AArch64::TCRETURNri: {
468  MCInst TmpInst;
469  TmpInst.setOpcode(AArch64::BR);
471  EmitToStreamer(*OutStreamer, TmpInst);
472  return;
473  }
474  case AArch64::TCRETURNdi: {
475  MCOperand Dest;
476  MCInstLowering.lowerOperand(MI->getOperand(0), Dest);
477  MCInst TmpInst;
478  TmpInst.setOpcode(AArch64::B);
479  TmpInst.addOperand(Dest);
480  EmitToStreamer(*OutStreamer, TmpInst);
481  return;
482  }
484  /// lower this to:
485  /// adrp x0, :tlsdesc:var
486  /// ldr x1, [x0, #:tlsdesc_lo12:var]
487  /// add x0, x0, #:tlsdesc_lo12:var
488  /// .tlsdesccall var
489  /// blr x1
490  /// (TPIDR_EL0 offset now in x0)
491  const MachineOperand &MO_Sym = MI->getOperand(0);
492  MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym);
493  MCOperand Sym, SymTLSDescLo12, SymTLSDesc;
494  MO_TLSDESC_LO12.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGEOFF |
496  MO_TLSDESC.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGE);
497  MCInstLowering.lowerOperand(MO_Sym, Sym);
498  MCInstLowering.lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
499  MCInstLowering.lowerOperand(MO_TLSDESC, SymTLSDesc);
500 
501  MCInst Adrp;
502  Adrp.setOpcode(AArch64::ADRP);
503  Adrp.addOperand(MCOperand::createReg(AArch64::X0));
504  Adrp.addOperand(SymTLSDesc);
505  EmitToStreamer(*OutStreamer, Adrp);
506 
507  MCInst Ldr;
508  Ldr.setOpcode(AArch64::LDRXui);
509  Ldr.addOperand(MCOperand::createReg(AArch64::X1));
510  Ldr.addOperand(MCOperand::createReg(AArch64::X0));
511  Ldr.addOperand(SymTLSDescLo12);
513  EmitToStreamer(*OutStreamer, Ldr);
514 
515  MCInst Add;
516  Add.setOpcode(AArch64::ADDXri);
517  Add.addOperand(MCOperand::createReg(AArch64::X0));
518  Add.addOperand(MCOperand::createReg(AArch64::X0));
519  Add.addOperand(SymTLSDescLo12);
521  EmitToStreamer(*OutStreamer, Add);
522 
523  // Emit a relocation-annotation. This expands to no code, but requests
524  // the following instruction gets an R_AARCH64_TLSDESC_CALL.
525  MCInst TLSDescCall;
526  TLSDescCall.setOpcode(AArch64::TLSDESCCALL);
527  TLSDescCall.addOperand(Sym);
528  EmitToStreamer(*OutStreamer, TLSDescCall);
529 
530  MCInst Blr;
531  Blr.setOpcode(AArch64::BLR);
532  Blr.addOperand(MCOperand::createReg(AArch64::X1));
533  EmitToStreamer(*OutStreamer, Blr);
534 
535  return;
536  }
537 
539  return LowerSTACKMAP(*OutStreamer, SM, *MI);
540 
542  return LowerPATCHPOINT(*OutStreamer, SM, *MI);
543  }
544 
545  // Finally, do the automated lowerings for everything else.
546  MCInst TmpInst;
547  MCInstLowering.Lower(MI, TmpInst);
548  EmitToStreamer(*OutStreamer, TmpInst);
549 }
550 
551 // Force static initialization.
556 }
static bool printAsmMRegister(X86AsmPrinter &P, const MachineOperand &MO, char Mode, raw_ostream &O)
const GlobalValue * getGlobal() const
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:489
static const char * getRegisterName(unsigned RegNo, unsigned AltIdx=AArch64::NoRegAltName)
void EmitRawText(const Twine &String)
If this file is backed by a assembly streamer, this dumps the specified string in the output ...
Definition: MCStreamer.cpp:577
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:51
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the class.
MO_PAGE - A symbol operand with this flag represents the pc-relative offset of the 4K page containing...
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:114
A Stackmap instruction captures the location of live variables at its position in the instruction str...
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText...
Definition: MCStreamer.h:237
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:488
static unsigned getXRegFromWReg(unsigned Reg)
F(f)
const MDNode * getMetadata() const
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:79
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
void LLVMInitializeAArch64AsmPrinter()
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Reg
All possible values of the reg field in the ModR/M byte.
static StringRef getName(Value *V)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:317
unsigned getNumOperands() const
Access to explicit operands of the instruction.
Definition: MachineInstr.h:271
static void printOperand(raw_ostream &OS, uint8_t Opcode, unsigned OperandIdx, uint64_t Operand, uint64_t CodeAlignmentFactor, int64_t DataAlignmentFactor)
Print Opcode's operand number OperandIdx which has value Operand.
void getAnalysisUsage(AnalysisUsage &AU) const override
Record analysis usage.
Definition: AsmPrinter.cpp:163
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
Definition: AsmPrinter.h:201
int64_t getImm() const
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:267
static unsigned getWRegFromXReg(unsigned Reg)
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:120
DBG_VALUE - a mapping of the llvm.dbg.value intrinsic.
Definition: TargetOpcodes.h:69
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
Address of a global value.
unsigned getTargetFlags() const
Streaming machine code generation interface.
Definition: MCStreamer.h:157
Patchable call instruction - this instruction represents a call to a constant address, followed by a series of NOPs.
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:533
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:273
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant...
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:66
Represent the analysis usage information of a pass.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
.subsections_via_symbols (MachO)
Definition: MCDirectives.h:49
Target TheARM64Target
int64_t getOffset() const
Return the offset from the symbol in this operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:38
MI-level patchpoint operands.
Definition: StackMaps.h:40
unsigned getSubReg() const
MO_TLS - Indicates that the operand being accessed is some kind of thread-local symbol.
void recordPatchPoint(const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
Definition: StackMaps.cpp:350
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Target TheAArch64leTarget
void setOpcode(unsigned Op)
Definition: MCInst.h:158
Target TheAArch64beTarget
virtual void EmitLabel(MCSymbol *Symbol)
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:203
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:123
void recordStackMap(const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
Definition: StackMaps.cpp:342
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
void setPreservesAll()
Set by analyses that do not transform their input at all.
Representation of each machine instruction.
Definition: MachineInstr.h:51
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
bundle_iterator< const MachineInstr, const_instr_iterator > const_iterator
static bool isPhysicalRegister(unsigned Reg)
isPhysicalRegister - Return true if the specified register number is in the physical register namespa...
AArch64MCInstLower - This class is used to lower an MachineInstr into an MCInst.
MO_PAGEOFF - A symbol operand with this flag represents the offset of that symbol within a 4K page...
void set(unsigned R)
Make this location a direct register location.
unsigned getReg() const
getReg - Returns the register number.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer, for use in the target machine initialization function.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
#define DEBUG(X)
Definition: Debug.h:92
Primary interface to the complete machine description for the target machine.
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
MO_NC - Indicates whether the linker is expected to check the symbol reference for overflow...
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:33
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117