LLVM  16.0.0git
AArch64AsmPrinter.cpp
Go to the documentation of this file.
1 //===- AArch64AsmPrinter.cpp - AArch64 LLVM assembly writer ---------------===//
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 the AArch64 assembly language.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "AArch64.h"
15 #include "AArch64MCInstLower.h"
17 #include "AArch64RegisterInfo.h"
18 #include "AArch64Subtarget.h"
26 #include "Utils/AArch64BaseInfo.h"
27 #include "llvm/ADT/SmallString.h"
28 #include "llvm/ADT/SmallVector.h"
29 #include "llvm/ADT/StringRef.h"
30 #include "llvm/ADT/Triple.h"
31 #include "llvm/ADT/Twine.h"
32 #include "llvm/BinaryFormat/COFF.h"
33 #include "llvm/BinaryFormat/ELF.h"
35 #include "llvm/CodeGen/FaultMaps.h"
42 #include "llvm/CodeGen/StackMaps.h"
44 #include "llvm/IR/DataLayout.h"
46 #include "llvm/MC/MCAsmInfo.h"
47 #include "llvm/MC/MCContext.h"
48 #include "llvm/MC/MCInst.h"
49 #include "llvm/MC/MCInstBuilder.h"
50 #include "llvm/MC/MCSectionELF.h"
51 #include "llvm/MC/MCStreamer.h"
52 #include "llvm/MC/MCSymbol.h"
53 #include "llvm/MC/TargetRegistry.h"
54 #include "llvm/Support/Casting.h"
59 #include <algorithm>
60 #include <cassert>
61 #include <cstdint>
62 #include <map>
63 #include <memory>
64 
65 using namespace llvm;
66 
67 #define DEBUG_TYPE "asm-printer"
68 
69 namespace {
70 
71 class AArch64AsmPrinter : public AsmPrinter {
72  AArch64MCInstLower MCInstLowering;
73  FaultMaps FM;
74  const AArch64Subtarget *STI;
75  bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = false;
76 
77 public:
78  AArch64AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
79  : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(OutContext, *this),
80  FM(*this) {}
81 
82  StringRef getPassName() const override { return "AArch64 Assembly Printer"; }
83 
84  /// Wrapper for MCInstLowering.lowerOperand() for the
85  /// tblgen'erated pseudo lowering.
86  bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const {
87  return MCInstLowering.lowerOperand(MO, MCOp);
88  }
89 
90  void emitStartOfAsmFile(Module &M) override;
91  void emitJumpTableInfo() override;
92 
93  void emitFunctionEntryLabel() override;
94 
95  void LowerJumpTableDest(MCStreamer &OutStreamer, const MachineInstr &MI);
96 
97  void LowerMOPS(MCStreamer &OutStreamer, const MachineInstr &MI);
98 
99  void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
100  const MachineInstr &MI);
101  void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
102  const MachineInstr &MI);
103  void LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
104  const MachineInstr &MI);
105  void LowerFAULTING_OP(const MachineInstr &MI);
106 
107  void LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI);
108  void LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI);
109  void LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI);
110 
111  typedef std::tuple<unsigned, bool, uint32_t> HwasanMemaccessTuple;
112  std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
113  void LowerKCFI_CHECK(const MachineInstr &MI);
114  void LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI);
115  void emitHwasanMemaccessSymbols(Module &M);
116 
117  void emitSled(const MachineInstr &MI, SledKind Kind);
118 
119  /// tblgen'erated driver function for lowering simple MI->MC
120  /// pseudo instructions.
121  bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
122  const MachineInstr *MI);
123 
124  void emitInstruction(const MachineInstr *MI) override;
125 
126  void emitFunctionHeaderComment() override;
127 
128  void getAnalysisUsage(AnalysisUsage &AU) const override {
130  AU.setPreservesAll();
131  }
132 
133  bool runOnMachineFunction(MachineFunction &MF) override {
134  AArch64FI = MF.getInfo<AArch64FunctionInfo>();
135  STI = &MF.getSubtarget<AArch64Subtarget>();
136 
137  SetupMachineFunction(MF);
138 
139  if (STI->isTargetCOFF()) {
140  bool Internal = MF.getFunction().hasInternalLinkage();
143  int Type =
145 
146  OutStreamer->beginCOFFSymbolDef(CurrentFnSym);
147  OutStreamer->emitCOFFSymbolStorageClass(Scl);
148  OutStreamer->emitCOFFSymbolType(Type);
149  OutStreamer->endCOFFSymbolDef();
150  }
151 
152  // Emit the rest of the function body.
153  emitFunctionBody();
154 
155  // Emit the XRay table for this function.
156  emitXRayTable();
157 
158  // We didn't modify anything.
159  return false;
160  }
161 
162 private:
163  void printOperand(const MachineInstr *MI, unsigned OpNum, raw_ostream &O);
164  bool printAsmMRegister(const MachineOperand &MO, char Mode, raw_ostream &O);
165  bool printAsmRegInClass(const MachineOperand &MO,
166  const TargetRegisterClass *RC, unsigned AltName,
167  raw_ostream &O);
168 
169  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
170  const char *ExtraCode, raw_ostream &O) override;
171  bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
172  const char *ExtraCode, raw_ostream &O) override;
173 
174  void PrintDebugValueComment(const MachineInstr *MI, raw_ostream &OS);
175 
176  void emitFunctionBodyEnd() override;
177 
178  MCSymbol *GetCPISymbol(unsigned CPID) const override;
179  void emitEndOfAsmFile(Module &M) override;
180 
181  AArch64FunctionInfo *AArch64FI = nullptr;
182 
183  /// Emit the LOHs contained in AArch64FI.
184  void emitLOHs();
185 
186  /// Emit instruction to set float register to zero.
187  void emitFMov0(const MachineInstr &MI);
188 
189  using MInstToMCSymbol = std::map<const MachineInstr *, MCSymbol *>;
190 
191  MInstToMCSymbol LOHInstToLabel;
192 
193  bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const override {
194  return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags;
195  }
196 };
197 
198 } // end anonymous namespace
199 
200 void AArch64AsmPrinter::emitStartOfAsmFile(Module &M) {
201  const Triple &TT = TM.getTargetTriple();
202 
203  if (TT.isOSBinFormatCOFF()) {
204  // Emit an absolute @feat.00 symbol
205  MCSymbol *S = MMI->getContext().getOrCreateSymbol(StringRef("@feat.00"));
206  OutStreamer->beginCOFFSymbolDef(S);
207  OutStreamer->emitCOFFSymbolStorageClass(COFF::IMAGE_SYM_CLASS_STATIC);
208  OutStreamer->emitCOFFSymbolType(COFF::IMAGE_SYM_DTYPE_NULL);
209  OutStreamer->endCOFFSymbolDef();
210  int64_t Feat00Value = 0;
211 
212  if (M.getModuleFlag("cfguard")) {
213  // Object is CFG-aware.
214  Feat00Value |= COFF::Feat00Flags::GuardCF;
215  }
216 
217  if (M.getModuleFlag("ehcontguard")) {
218  // Object also has EHCont.
219  Feat00Value |= COFF::Feat00Flags::GuardEHCont;
220  }
221 
222  if (M.getModuleFlag("ms-kernel")) {
223  // Object is compiled with /kernel.
224  Feat00Value |= COFF::Feat00Flags::Kernel;
225  }
226 
227  OutStreamer->emitSymbolAttribute(S, MCSA_Global);
228  OutStreamer->emitAssignment(
229  S, MCConstantExpr::create(Feat00Value, MMI->getContext()));
230  }
231 
232  if (!TT.isOSBinFormatELF())
233  return;
234 
235  // Assemble feature flags that may require creation of a note section.
236  unsigned Flags = 0;
237  if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
238  M.getModuleFlag("branch-target-enforcement")))
239  if (BTE->getZExtValue())
241 
242  if (const auto *Sign = mdconst::extract_or_null<ConstantInt>(
243  M.getModuleFlag("sign-return-address")))
244  if (Sign->getZExtValue())
246 
247  if (Flags == 0)
248  return;
249 
250  // Emit a .note.gnu.property section with the flags.
251  auto *TS =
252  static_cast<AArch64TargetStreamer *>(OutStreamer->getTargetStreamer());
253  TS->emitNoteSection(Flags);
254 }
255 
256 void AArch64AsmPrinter::emitFunctionHeaderComment() {
257  const AArch64FunctionInfo *FI = MF->getInfo<AArch64FunctionInfo>();
258  std::optional<std::string> OutlinerString = FI->getOutliningStyle();
259  if (OutlinerString != std::nullopt)
260  OutStreamer->getCommentOS() << ' ' << OutlinerString;
261 }
262 
263 void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(const MachineInstr &MI)
264 {
265  const Function &F = MF->getFunction();
266  if (F.hasFnAttribute("patchable-function-entry")) {
267  unsigned Num;
268  if (F.getFnAttribute("patchable-function-entry")
269  .getValueAsString()
270  .getAsInteger(10, Num))
271  return;
272  emitNops(Num);
273  return;
274  }
275 
276  emitSled(MI, SledKind::FUNCTION_ENTER);
277 }
278 
279 void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(const MachineInstr &MI) {
280  emitSled(MI, SledKind::FUNCTION_EXIT);
281 }
282 
283 void AArch64AsmPrinter::LowerPATCHABLE_TAIL_CALL(const MachineInstr &MI) {
284  emitSled(MI, SledKind::TAIL_CALL);
285 }
286 
287 void AArch64AsmPrinter::emitSled(const MachineInstr &MI, SledKind Kind) {
288  static const int8_t NoopsInSledCount = 7;
289  // We want to emit the following pattern:
290  //
291  // .Lxray_sled_N:
292  // ALIGN
293  // B #32
294  // ; 7 NOP instructions (28 bytes)
295  // .tmpN
296  //
297  // We need the 28 bytes (7 instructions) because at runtime, we'd be patching
298  // over the full 32 bytes (8 instructions) with the following pattern:
299  //
300  // STP X0, X30, [SP, #-16]! ; push X0 and the link register to the stack
301  // LDR W0, #12 ; W0 := function ID
302  // LDR X16,#12 ; X16 := addr of __xray_FunctionEntry or __xray_FunctionExit
303  // BLR X16 ; call the tracing trampoline
304  // ;DATA: 32 bits of function ID
305  // ;DATA: lower 32 bits of the address of the trampoline
306  // ;DATA: higher 32 bits of the address of the trampoline
307  // LDP X0, X30, [SP], #16 ; pop X0 and the link register from the stack
308  //
309  OutStreamer->emitCodeAlignment(Align(4), &getSubtargetInfo());
310  auto CurSled = OutContext.createTempSymbol("xray_sled_", true);
311  OutStreamer->emitLabel(CurSled);
312  auto Target = OutContext.createTempSymbol();
313 
314  // Emit "B #32" instruction, which jumps over the next 28 bytes.
315  // The operand has to be the number of 4-byte instructions to jump over,
316  // including the current instruction.
317  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::B).addImm(8));
318 
319  for (int8_t I = 0; I < NoopsInSledCount; I++)
320  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
321 
322  OutStreamer->emitLabel(Target);
323  recordSled(CurSled, MI, Kind, 2);
324 }
325 
326 void AArch64AsmPrinter::LowerKCFI_CHECK(const MachineInstr &MI) {
327  Register AddrReg = MI.getOperand(0).getReg();
328  assert(std::next(MI.getIterator())->isCall() &&
329  "KCFI_CHECK not followed by a call instruction");
330  assert(std::next(MI.getIterator())->getOperand(0).getReg() == AddrReg &&
331  "KCFI_CHECK call target doesn't match call operand");
332 
333  // Default to using the intra-procedure-call temporary registers for
334  // comparing the hashes.
335  unsigned ScratchRegs[] = {AArch64::W16, AArch64::W17};
336  if (AddrReg == AArch64::XZR) {
337  // Checking XZR makes no sense. Instead of emitting a load, zero
338  // ScratchRegs[0] and use it for the ESR AddrIndex below.
339  AddrReg = getXRegFromWReg(ScratchRegs[0]);
340  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ORRXrs)
341  .addReg(AddrReg)
342  .addReg(AArch64::XZR)
343  .addReg(AArch64::XZR)
344  .addImm(0));
345  } else {
346  // If one of the scratch registers is used for the call target (e.g.
347  // with AArch64::TCRETURNriBTI), we can clobber another caller-saved
348  // temporary register instead (in this case, AArch64::W9) as the check
349  // is immediately followed by the call instruction.
350  for (auto &Reg : ScratchRegs) {
351  if (Reg == getWRegFromXReg(AddrReg)) {
352  Reg = AArch64::W9;
353  break;
354  }
355  }
356  assert(ScratchRegs[0] != AddrReg && ScratchRegs[1] != AddrReg &&
357  "Invalid scratch registers for KCFI_CHECK");
358 
359  // Adjust the offset for patchable-function-prefix. This assumes that
360  // patchable-function-prefix is the same for all functions.
361  int64_t PrefixNops = 0;
362  (void)MI.getMF()
363  ->getFunction()
364  .getFnAttribute("patchable-function-prefix")
365  .getValueAsString()
366  .getAsInteger(10, PrefixNops);
367 
368  // Load the target function type hash.
369  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDURWi)
370  .addReg(ScratchRegs[0])
371  .addReg(AddrReg)
372  .addImm(-(PrefixNops * 4 + 4)));
373  }
374 
375  // Load the expected type hash.
376  const int64_t Type = MI.getOperand(1).getImm();
377  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::MOVKWi)
378  .addReg(ScratchRegs[1])
379  .addReg(ScratchRegs[1])
380  .addImm(Type & 0xFFFF)
381  .addImm(0));
382  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::MOVKWi)
383  .addReg(ScratchRegs[1])
384  .addReg(ScratchRegs[1])
385  .addImm((Type >> 16) & 0xFFFF)
386  .addImm(16));
387 
388  // Compare the hashes and trap if there's a mismatch.
389  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::SUBSWrs)
390  .addReg(AArch64::WZR)
391  .addReg(ScratchRegs[0])
392  .addReg(ScratchRegs[1])
393  .addImm(0));
394 
395  MCSymbol *Pass = OutContext.createTempSymbol();
396  EmitToStreamer(*OutStreamer,
397  MCInstBuilder(AArch64::Bcc)
398  .addImm(AArch64CC::EQ)
399  .addExpr(MCSymbolRefExpr::create(Pass, OutContext)));
400 
401  // The base ESR is 0x8000 and the register information is encoded in bits
402  // 0-9 as follows:
403  // - 0-4: n, where the register Xn contains the target address
404  // - 5-9: m, where the register Wm contains the expected type hash
405  // Where n, m are in [0, 30].
406  unsigned TypeIndex = ScratchRegs[1] - AArch64::W0;
407  unsigned AddrIndex;
408  switch (AddrReg) {
409  default:
410  AddrIndex = AddrReg - AArch64::X0;
411  break;
412  case AArch64::FP:
413  AddrIndex = 29;
414  break;
415  case AArch64::LR:
416  AddrIndex = 30;
417  break;
418  }
419 
420  assert(AddrIndex < 31 && TypeIndex < 31);
421 
422  unsigned ESR = 0x8000 | ((TypeIndex & 31) << 5) | (AddrIndex & 31);
423  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::BRK).addImm(ESR));
424  OutStreamer->emitLabel(Pass);
425 }
426 
427 void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(const MachineInstr &MI) {
428  Register Reg = MI.getOperand(0).getReg();
429  bool IsShort =
430  MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES;
431  uint32_t AccessInfo = MI.getOperand(1).getImm();
432  MCSymbol *&Sym =
433  HwasanMemaccessSymbols[HwasanMemaccessTuple(Reg, IsShort, AccessInfo)];
434  if (!Sym) {
435  // FIXME: Make this work on non-ELF.
436  if (!TM.getTargetTriple().isOSBinFormatELF())
437  report_fatal_error("llvm.hwasan.check.memaccess only supported on ELF");
438 
439  std::string SymName = "__hwasan_check_x" + utostr(Reg - AArch64::X0) + "_" +
440  utostr(AccessInfo);
441  if (IsShort)
442  SymName += "_short_v2";
443  Sym = OutContext.getOrCreateSymbol(SymName);
444  }
445 
446  EmitToStreamer(*OutStreamer,
448  .addExpr(MCSymbolRefExpr::create(Sym, OutContext)));
449 }
450 
451 void AArch64AsmPrinter::emitHwasanMemaccessSymbols(Module &M) {
452  if (HwasanMemaccessSymbols.empty())
453  return;
454 
455  const Triple &TT = TM.getTargetTriple();
456  assert(TT.isOSBinFormatELF());
457  std::unique_ptr<MCSubtargetInfo> STI(
458  TM.getTarget().createMCSubtargetInfo(TT.str(), "", ""));
459  assert(STI && "Unable to create subtarget info");
460 
461  MCSymbol *HwasanTagMismatchV1Sym =
462  OutContext.getOrCreateSymbol("__hwasan_tag_mismatch");
463  MCSymbol *HwasanTagMismatchV2Sym =
464  OutContext.getOrCreateSymbol("__hwasan_tag_mismatch_v2");
465 
466  const MCSymbolRefExpr *HwasanTagMismatchV1Ref =
467  MCSymbolRefExpr::create(HwasanTagMismatchV1Sym, OutContext);
468  const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
469  MCSymbolRefExpr::create(HwasanTagMismatchV2Sym, OutContext);
470 
471  for (auto &P : HwasanMemaccessSymbols) {
472  unsigned Reg = std::get<0>(P.first);
473  bool IsShort = std::get<1>(P.first);
474  uint32_t AccessInfo = std::get<2>(P.first);
475  const MCSymbolRefExpr *HwasanTagMismatchRef =
476  IsShort ? HwasanTagMismatchV2Ref : HwasanTagMismatchV1Ref;
477  MCSymbol *Sym = P.second;
478 
479  bool HasMatchAllTag =
480  (AccessInfo >> HWASanAccessInfo::HasMatchAllShift) & 1;
481  uint8_t MatchAllTag =
482  (AccessInfo >> HWASanAccessInfo::MatchAllShift) & 0xff;
483  unsigned Size =
484  1 << ((AccessInfo >> HWASanAccessInfo::AccessSizeShift) & 0xf);
485  bool CompileKernel =
486  (AccessInfo >> HWASanAccessInfo::CompileKernelShift) & 1;
487 
488  OutStreamer->switchSection(OutContext.getELFSection(
489  ".text.hot", ELF::SHT_PROGBITS,
491  /*IsComdat=*/true));
492 
493  OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);
494  OutStreamer->emitSymbolAttribute(Sym, MCSA_Weak);
495  OutStreamer->emitSymbolAttribute(Sym, MCSA_Hidden);
496  OutStreamer->emitLabel(Sym);
497 
498  OutStreamer->emitInstruction(MCInstBuilder(AArch64::SBFMXri)
499  .addReg(AArch64::X16)
500  .addReg(Reg)
501  .addImm(4)
502  .addImm(55),
503  *STI);
504  OutStreamer->emitInstruction(
505  MCInstBuilder(AArch64::LDRBBroX)
506  .addReg(AArch64::W16)
507  .addReg(IsShort ? AArch64::X20 : AArch64::X9)
508  .addReg(AArch64::X16)
509  .addImm(0)
510  .addImm(0),
511  *STI);
512  OutStreamer->emitInstruction(
513  MCInstBuilder(AArch64::SUBSXrs)
514  .addReg(AArch64::XZR)
515  .addReg(AArch64::X16)
516  .addReg(Reg)
518  *STI);
519  MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
520  OutStreamer->emitInstruction(
521  MCInstBuilder(AArch64::Bcc)
523  .addExpr(MCSymbolRefExpr::create(HandleMismatchOrPartialSym,
524  OutContext)),
525  *STI);
526  MCSymbol *ReturnSym = OutContext.createTempSymbol();
527  OutStreamer->emitLabel(ReturnSym);
528  OutStreamer->emitInstruction(
529  MCInstBuilder(AArch64::RET).addReg(AArch64::LR), *STI);
530  OutStreamer->emitLabel(HandleMismatchOrPartialSym);
531 
532  if (HasMatchAllTag) {
533  OutStreamer->emitInstruction(MCInstBuilder(AArch64::UBFMXri)
534  .addReg(AArch64::X16)
535  .addReg(Reg)
536  .addImm(56)
537  .addImm(63),
538  *STI);
539  OutStreamer->emitInstruction(MCInstBuilder(AArch64::SUBSXri)
540  .addReg(AArch64::XZR)
541  .addReg(AArch64::X16)
542  .addImm(MatchAllTag)
543  .addImm(0),
544  *STI);
545  OutStreamer->emitInstruction(
546  MCInstBuilder(AArch64::Bcc)
548  .addExpr(MCSymbolRefExpr::create(ReturnSym, OutContext)),
549  *STI);
550  }
551 
552  if (IsShort) {
553  OutStreamer->emitInstruction(MCInstBuilder(AArch64::SUBSWri)
554  .addReg(AArch64::WZR)
555  .addReg(AArch64::W16)
556  .addImm(15)
557  .addImm(0),
558  *STI);
559  MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
560  OutStreamer->emitInstruction(
561  MCInstBuilder(AArch64::Bcc)
563  .addExpr(MCSymbolRefExpr::create(HandleMismatchSym, OutContext)),
564  *STI);
565 
566  OutStreamer->emitInstruction(
567  MCInstBuilder(AArch64::ANDXri)
568  .addReg(AArch64::X17)
569  .addReg(Reg)
571  *STI);
572  if (Size != 1)
573  OutStreamer->emitInstruction(MCInstBuilder(AArch64::ADDXri)
574  .addReg(AArch64::X17)
575  .addReg(AArch64::X17)
576  .addImm(Size - 1)
577  .addImm(0),
578  *STI);
579  OutStreamer->emitInstruction(MCInstBuilder(AArch64::SUBSWrs)
580  .addReg(AArch64::WZR)
581  .addReg(AArch64::W16)
582  .addReg(AArch64::W17)
583  .addImm(0),
584  *STI);
585  OutStreamer->emitInstruction(
586  MCInstBuilder(AArch64::Bcc)
588  .addExpr(MCSymbolRefExpr::create(HandleMismatchSym, OutContext)),
589  *STI);
590 
591  OutStreamer->emitInstruction(
592  MCInstBuilder(AArch64::ORRXri)
593  .addReg(AArch64::X16)
594  .addReg(Reg)
596  *STI);
597  OutStreamer->emitInstruction(MCInstBuilder(AArch64::LDRBBui)
598  .addReg(AArch64::W16)
599  .addReg(AArch64::X16)
600  .addImm(0),
601  *STI);
602  OutStreamer->emitInstruction(
603  MCInstBuilder(AArch64::SUBSXrs)
604  .addReg(AArch64::XZR)
605  .addReg(AArch64::X16)
606  .addReg(Reg)
608  *STI);
609  OutStreamer->emitInstruction(
610  MCInstBuilder(AArch64::Bcc)
612  .addExpr(MCSymbolRefExpr::create(ReturnSym, OutContext)),
613  *STI);
614 
615  OutStreamer->emitLabel(HandleMismatchSym);
616  }
617 
618  OutStreamer->emitInstruction(MCInstBuilder(AArch64::STPXpre)
619  .addReg(AArch64::SP)
620  .addReg(AArch64::X0)
621  .addReg(AArch64::X1)
622  .addReg(AArch64::SP)
623  .addImm(-32),
624  *STI);
625  OutStreamer->emitInstruction(MCInstBuilder(AArch64::STPXi)
626  .addReg(AArch64::FP)
627  .addReg(AArch64::LR)
628  .addReg(AArch64::SP)
629  .addImm(29),
630  *STI);
631 
632  if (Reg != AArch64::X0)
633  OutStreamer->emitInstruction(MCInstBuilder(AArch64::ORRXrs)
634  .addReg(AArch64::X0)
635  .addReg(AArch64::XZR)
636  .addReg(Reg)
637  .addImm(0),
638  *STI);
639  OutStreamer->emitInstruction(
640  MCInstBuilder(AArch64::MOVZXi)
641  .addReg(AArch64::X1)
643  .addImm(0),
644  *STI);
645 
646  if (CompileKernel) {
647  // The Linux kernel's dynamic loader doesn't support GOT relative
648  // relocations, but it doesn't support late binding either, so just call
649  // the function directly.
650  OutStreamer->emitInstruction(
651  MCInstBuilder(AArch64::B).addExpr(HwasanTagMismatchRef), *STI);
652  } else {
653  // Intentionally load the GOT entry and branch to it, rather than possibly
654  // late binding the function, which may clobber the registers before we
655  // have a chance to save them.
656  OutStreamer->emitInstruction(
658  .addReg(AArch64::X16)
660  HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_PAGE,
661  OutContext)),
662  *STI);
663  OutStreamer->emitInstruction(
664  MCInstBuilder(AArch64::LDRXui)
665  .addReg(AArch64::X16)
666  .addReg(AArch64::X16)
668  HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_LO12,
669  OutContext)),
670  *STI);
671  OutStreamer->emitInstruction(
672  MCInstBuilder(AArch64::BR).addReg(AArch64::X16), *STI);
673  }
674  }
675 }
676 
677 void AArch64AsmPrinter::emitEndOfAsmFile(Module &M) {
678  emitHwasanMemaccessSymbols(M);
679 
680  const Triple &TT = TM.getTargetTriple();
681  if (TT.isOSBinFormatMachO()) {
682  // Funny Darwin hack: This flag tells the linker that no global symbols
683  // contain code that falls through to other global symbols (e.g. the obvious
684  // implementation of multiple entry points). If this doesn't occur, the
685  // linker can safely perform dead code stripping. Since LLVM never
686  // generates code that does this, it is always safe to set.
687  OutStreamer->emitAssemblerFlag(MCAF_SubsectionsViaSymbols);
688  }
689 
690  // Emit stack and fault map information.
691  FM.serializeToFaultMapSection();
692 
693 }
694 
695 void AArch64AsmPrinter::emitLOHs() {
697 
698  for (const auto &D : AArch64FI->getLOHContainer()) {
699  for (const MachineInstr *MI : D.getArgs()) {
700  MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(MI);
701  assert(LabelIt != LOHInstToLabel.end() &&
702  "Label hasn't been inserted for LOH related instruction");
703  MCArgs.push_back(LabelIt->second);
704  }
705  OutStreamer->emitLOHDirective(D.getKind(), MCArgs);
706  MCArgs.clear();
707  }
708 }
709 
710 void AArch64AsmPrinter::emitFunctionBodyEnd() {
711  if (!AArch64FI->getLOHRelated().empty())
712  emitLOHs();
713 }
714 
715 /// GetCPISymbol - Return the symbol for the specified constant pool entry.
716 MCSymbol *AArch64AsmPrinter::GetCPISymbol(unsigned CPID) const {
717  // Darwin uses a linker-private symbol name for constant-pools (to
718  // avoid addends on the relocation?), ELF has no such concept and
719  // uses a normal private symbol.
720  if (!getDataLayout().getLinkerPrivateGlobalPrefix().empty())
721  return OutContext.getOrCreateSymbol(
722  Twine(getDataLayout().getLinkerPrivateGlobalPrefix()) + "CPI" +
723  Twine(getFunctionNumber()) + "_" + Twine(CPID));
724 
725  return AsmPrinter::GetCPISymbol(CPID);
726 }
727 
728 void AArch64AsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNum,
729  raw_ostream &O) {
730  const MachineOperand &MO = MI->getOperand(OpNum);
731  switch (MO.getType()) {
732  default:
733  llvm_unreachable("<unknown operand type>");
735  Register Reg = MO.getReg();
737  assert(!MO.getSubReg() && "Subregs should be eliminated!");
739  break;
740  }
742  O << MO.getImm();
743  break;
744  }
746  PrintSymbolOperand(MO, O);
747  break;
748  }
750  MCSymbol *Sym = GetBlockAddressSymbol(MO.getBlockAddress());
751  Sym->print(O, MAI);
752  break;
753  }
754  }
755 }
756 
758  raw_ostream &O) {
759  Register Reg = MO.getReg();
760  switch (Mode) {
761  default:
762  return true; // Unknown mode.
763  case 'w':
765  break;
766  case 'x':
768  break;
769  case 't':
771  break;
772  }
773 
775  return false;
776 }
777 
778 // Prints the register in MO using class RC using the offset in the
779 // new register class. This should not be used for cross class
780 // printing.
781 bool AArch64AsmPrinter::printAsmRegInClass(const MachineOperand &MO,
782  const TargetRegisterClass *RC,
783  unsigned AltName, raw_ostream &O) {
784  assert(MO.isReg() && "Should only get here with a register!");
785  const TargetRegisterInfo *RI = STI->getRegisterInfo();
786  Register Reg = MO.getReg();
787  unsigned RegToPrint = RC->getRegister(RI->getEncodingValue(Reg));
788  if (!RI->regsOverlap(RegToPrint, Reg))
789  return true;
790  O << AArch64InstPrinter::getRegisterName(RegToPrint, AltName);
791  return false;
792 }
793 
794 bool AArch64AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
795  const char *ExtraCode, raw_ostream &O) {
796  const MachineOperand &MO = MI->getOperand(OpNum);
797 
798  // First try the generic code, which knows about modifiers like 'c' and 'n'.
799  if (!AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O))
800  return false;
801 
802  // Does this asm operand have a single letter operand modifier?
803  if (ExtraCode && ExtraCode[0]) {
804  if (ExtraCode[1] != 0)
805  return true; // Unknown modifier.
806 
807  switch (ExtraCode[0]) {
808  default:
809  return true; // Unknown modifier.
810  case 'w': // Print W register
811  case 'x': // Print X register
812  if (MO.isReg())
813  return printAsmMRegister(MO, ExtraCode[0], O);
814  if (MO.isImm() && MO.getImm() == 0) {
815  unsigned Reg = ExtraCode[0] == 'w' ? AArch64::WZR : AArch64::XZR;
817  return false;
818  }
819  printOperand(MI, OpNum, O);
820  return false;
821  case 'b': // Print B register.
822  case 'h': // Print H register.
823  case 's': // Print S register.
824  case 'd': // Print D register.
825  case 'q': // Print Q register.
826  case 'z': // Print Z register.
827  if (MO.isReg()) {
828  const TargetRegisterClass *RC;
829  switch (ExtraCode[0]) {
830  case 'b':
831  RC = &AArch64::FPR8RegClass;
832  break;
833  case 'h':
834  RC = &AArch64::FPR16RegClass;
835  break;
836  case 's':
837  RC = &AArch64::FPR32RegClass;
838  break;
839  case 'd':
840  RC = &AArch64::FPR64RegClass;
841  break;
842  case 'q':
843  RC = &AArch64::FPR128RegClass;
844  break;
845  case 'z':
846  RC = &AArch64::ZPRRegClass;
847  break;
848  default:
849  return true;
850  }
851  return printAsmRegInClass(MO, RC, AArch64::NoRegAltName, O);
852  }
853  printOperand(MI, OpNum, O);
854  return false;
855  }
856  }
857 
858  // According to ARM, we should emit x and v registers unless we have a
859  // modifier.
860  if (MO.isReg()) {
861  Register Reg = MO.getReg();
862 
863  // If this is a w or x register, print an x register.
864  if (AArch64::GPR32allRegClass.contains(Reg) ||
865  AArch64::GPR64allRegClass.contains(Reg))
866  return printAsmMRegister(MO, 'x', O);
867 
868  // If this is an x register tuple, print an x register.
869  if (AArch64::GPR64x8ClassRegClass.contains(Reg))
870  return printAsmMRegister(MO, 't', O);
871 
872  unsigned AltName = AArch64::NoRegAltName;
873  const TargetRegisterClass *RegClass;
874  if (AArch64::ZPRRegClass.contains(Reg)) {
875  RegClass = &AArch64::ZPRRegClass;
876  } else if (AArch64::PPRRegClass.contains(Reg)) {
877  RegClass = &AArch64::PPRRegClass;
878  } else {
879  RegClass = &AArch64::FPR128RegClass;
880  AltName = AArch64::vreg;
881  }
882 
883  // If this is a b, h, s, d, or q register, print it as a v register.
884  return printAsmRegInClass(MO, RegClass, AltName, O);
885  }
886 
887  printOperand(MI, OpNum, O);
888  return false;
889 }
890 
891 bool AArch64AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
892  unsigned OpNum,
893  const char *ExtraCode,
894  raw_ostream &O) {
895  if (ExtraCode && ExtraCode[0] && ExtraCode[0] != 'a')
896  return true; // Unknown modifier.
897 
898  const MachineOperand &MO = MI->getOperand(OpNum);
899  assert(MO.isReg() && "unexpected inline asm memory operand");
900  O << "[" << AArch64InstPrinter::getRegisterName(MO.getReg()) << "]";
901  return false;
902 }
903 
904 void AArch64AsmPrinter::PrintDebugValueComment(const MachineInstr *MI,
905  raw_ostream &OS) {
906  unsigned NOps = MI->getNumOperands();
907  assert(NOps == 4);
908  OS << '\t' << MAI->getCommentString() << "DEBUG_VALUE: ";
909  // cast away const; DIetc do not take const operands for some reason.
910  OS << MI->getDebugVariable()->getName();
911  OS << " <- ";
912  // Frame address. Currently handles register +- offset only.
913  assert(MI->isIndirectDebugValue());
914  OS << '[';
915  for (unsigned I = 0, E = std::distance(MI->debug_operands().begin(),
916  MI->debug_operands().end());
917  I < E; ++I) {
918  if (I != 0)
919  OS << ", ";
920  printOperand(MI, I, OS);
921  }
922  OS << ']';
923  OS << "+";
924  printOperand(MI, NOps - 2, OS);
925 }
926 
927 void AArch64AsmPrinter::emitJumpTableInfo() {
928  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
929  if (!MJTI) return;
930 
931  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
932  if (JT.empty()) return;
933 
934  const TargetLoweringObjectFile &TLOF = getObjFileLowering();
935  MCSection *ReadOnlySec = TLOF.getSectionForJumpTable(MF->getFunction(), TM);
936  OutStreamer->switchSection(ReadOnlySec);
937 
938  auto AFI = MF->getInfo<AArch64FunctionInfo>();
939  for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) {
940  const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
941 
942  // If this jump table was deleted, ignore it.
943  if (JTBBs.empty()) continue;
944 
945  unsigned Size = AFI->getJumpTableEntrySize(JTI);
946  emitAlignment(Align(Size));
947  OutStreamer->emitLabel(GetJTISymbol(JTI));
948 
949  const MCSymbol *BaseSym = AArch64FI->getJumpTableEntryPCRelSymbol(JTI);
950  const MCExpr *Base = MCSymbolRefExpr::create(BaseSym, OutContext);
951 
952  for (auto *JTBB : JTBBs) {
953  const MCExpr *Value =
954  MCSymbolRefExpr::create(JTBB->getSymbol(), OutContext);
955 
956  // Each entry is:
957  // .byte/.hword (LBB - Lbase)>>2
958  // or plain:
959  // .word LBB - Lbase
960  Value = MCBinaryExpr::createSub(Value, Base, OutContext);
961  if (Size != 4)
963  Value, MCConstantExpr::create(2, OutContext), OutContext);
964 
965  OutStreamer->emitValue(Value, Size);
966  }
967  }
968 }
969 
970 void AArch64AsmPrinter::emitFunctionEntryLabel() {
971  if (MF->getFunction().getCallingConv() == CallingConv::AArch64_VectorCall ||
972  MF->getFunction().getCallingConv() ==
974  MF->getInfo<AArch64FunctionInfo>()->isSVECC()) {
975  auto *TS =
976  static_cast<AArch64TargetStreamer *>(OutStreamer->getTargetStreamer());
977  TS->emitDirectiveVariantPCS(CurrentFnSym);
978  }
979 
981 }
982 
983 /// Small jump tables contain an unsigned byte or half, representing the offset
984 /// from the lowest-addressed possible destination to the desired basic
985 /// block. Since all instructions are 4-byte aligned, this is further compressed
986 /// by counting in instructions rather than bytes (i.e. divided by 4). So, to
987 /// materialize the correct destination we need:
988 ///
989 /// adr xDest, .LBB0_0
990 /// ldrb wScratch, [xTable, xEntry] (with "lsl #1" for ldrh).
991 /// add xDest, xDest, xScratch (with "lsl #2" for smaller entries)
992 void AArch64AsmPrinter::LowerJumpTableDest(llvm::MCStreamer &OutStreamer,
993  const llvm::MachineInstr &MI) {
994  Register DestReg = MI.getOperand(0).getReg();
995  Register ScratchReg = MI.getOperand(1).getReg();
996  Register ScratchRegW =
997  STI->getRegisterInfo()->getSubReg(ScratchReg, AArch64::sub_32);
998  Register TableReg = MI.getOperand(2).getReg();
999  Register EntryReg = MI.getOperand(3).getReg();
1000  int JTIdx = MI.getOperand(4).getIndex();
1001  int Size = AArch64FI->getJumpTableEntrySize(JTIdx);
1002 
1003  // This has to be first because the compression pass based its reachability
1004  // calculations on the start of the JumpTableDest instruction.
1005  auto Label =
1006  MF->getInfo<AArch64FunctionInfo>()->getJumpTableEntryPCRelSymbol(JTIdx);
1007 
1008  // If we don't already have a symbol to use as the base, use the ADR
1009  // instruction itself.
1010  if (!Label) {
1011  Label = MF->getContext().createTempSymbol();
1012  AArch64FI->setJumpTableEntryInfo(JTIdx, Size, Label);
1013  OutStreamer.emitLabel(Label);
1014  }
1015 
1016  auto LabelExpr = MCSymbolRefExpr::create(Label, MF->getContext());
1017  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::ADR)
1018  .addReg(DestReg)
1019  .addExpr(LabelExpr));
1020 
1021  // Load the number of instruction-steps to offset from the label.
1022  unsigned LdrOpcode;
1023  switch (Size) {
1024  case 1: LdrOpcode = AArch64::LDRBBroX; break;
1025  case 2: LdrOpcode = AArch64::LDRHHroX; break;
1026  case 4: LdrOpcode = AArch64::LDRSWroX; break;
1027  default:
1028  llvm_unreachable("Unknown jump table size");
1029  }
1030 
1031  EmitToStreamer(OutStreamer, MCInstBuilder(LdrOpcode)
1032  .addReg(Size == 4 ? ScratchReg : ScratchRegW)
1033  .addReg(TableReg)
1034  .addReg(EntryReg)
1035  .addImm(0)
1036  .addImm(Size == 1 ? 0 : 1));
1037 
1038  // Add to the already materialized base label address, multiplying by 4 if
1039  // compressed.
1040  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::ADDXrs)
1041  .addReg(DestReg)
1042  .addReg(DestReg)
1043  .addReg(ScratchReg)
1044  .addImm(Size == 4 ? 0 : 2));
1045 }
1046 
1047 void AArch64AsmPrinter::LowerMOPS(llvm::MCStreamer &OutStreamer,
1048  const llvm::MachineInstr &MI) {
1049  unsigned Opcode = MI.getOpcode();
1050  assert(STI->hasMOPS());
1051  assert(STI->hasMTE() || Opcode != AArch64::MOPSMemorySetTaggingPseudo);
1052 
1053  const auto Ops = [Opcode]() -> std::array<unsigned, 3> {
1054  if (Opcode == AArch64::MOPSMemoryCopyPseudo)
1055  return {AArch64::CPYFP, AArch64::CPYFM, AArch64::CPYFE};
1056  if (Opcode == AArch64::MOPSMemoryMovePseudo)
1057  return {AArch64::CPYP, AArch64::CPYM, AArch64::CPYE};
1058  if (Opcode == AArch64::MOPSMemorySetPseudo)
1059  return {AArch64::SETP, AArch64::SETM, AArch64::SETE};
1060  if (Opcode == AArch64::MOPSMemorySetTaggingPseudo)
1061  return {AArch64::SETGP, AArch64::SETGM, AArch64::MOPSSETGE};
1062  llvm_unreachable("Unhandled memory operation pseudo");
1063  }();
1064  const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
1065  Opcode == AArch64::MOPSMemorySetTaggingPseudo;
1066 
1067  for (auto Op : Ops) {
1068  int i = 0;
1069  auto MCIB = MCInstBuilder(Op);
1070  // Destination registers
1071  MCIB.addReg(MI.getOperand(i++).getReg());
1072  MCIB.addReg(MI.getOperand(i++).getReg());
1073  if (!IsSet)
1074  MCIB.addReg(MI.getOperand(i++).getReg());
1075  // Input registers
1076  MCIB.addReg(MI.getOperand(i++).getReg());
1077  MCIB.addReg(MI.getOperand(i++).getReg());
1078  MCIB.addReg(MI.getOperand(i++).getReg());
1079 
1080  EmitToStreamer(OutStreamer, MCIB);
1081  }
1082 }
1083 
1084 void AArch64AsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
1085  const MachineInstr &MI) {
1086  unsigned NumNOPBytes = StackMapOpers(&MI).getNumPatchBytes();
1087 
1088  auto &Ctx = OutStreamer.getContext();
1089  MCSymbol *MILabel = Ctx.createTempSymbol();
1090  OutStreamer.emitLabel(MILabel);
1091 
1092  SM.recordStackMap(*MILabel, MI);
1093  assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
1094 
1095  // Scan ahead to trim the shadow.
1096  const MachineBasicBlock &MBB = *MI.getParent();
1098  ++MII;
1099  while (NumNOPBytes > 0) {
1100  if (MII == MBB.end() || MII->isCall() ||
1101  MII->getOpcode() == AArch64::DBG_VALUE ||
1102  MII->getOpcode() == TargetOpcode::PATCHPOINT ||
1103  MII->getOpcode() == TargetOpcode::STACKMAP)
1104  break;
1105  ++MII;
1106  NumNOPBytes -= 4;
1107  }
1108 
1109  // Emit nops.
1110  for (unsigned i = 0; i < NumNOPBytes; i += 4)
1111  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
1112 }
1113 
1114 // Lower a patchpoint of the form:
1115 // [<def>], <id>, <numBytes>, <target>, <numArgs>
1116 void AArch64AsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
1117  const MachineInstr &MI) {
1118  auto &Ctx = OutStreamer.getContext();
1119  MCSymbol *MILabel = Ctx.createTempSymbol();
1120  OutStreamer.emitLabel(MILabel);
1121  SM.recordPatchPoint(*MILabel, MI);
1122 
1123  PatchPointOpers Opers(&MI);
1124 
1125  int64_t CallTarget = Opers.getCallTarget().getImm();
1126  unsigned EncodedBytes = 0;
1127  if (CallTarget) {
1128  assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
1129  "High 16 bits of call target should be zero.");
1130  Register ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
1131  EncodedBytes = 16;
1132  // Materialize the jump address:
1133  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::MOVZXi)
1134  .addReg(ScratchReg)
1135  .addImm((CallTarget >> 32) & 0xFFFF)
1136  .addImm(32));
1137  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::MOVKXi)
1138  .addReg(ScratchReg)
1139  .addReg(ScratchReg)
1140  .addImm((CallTarget >> 16) & 0xFFFF)
1141  .addImm(16));
1142  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::MOVKXi)
1143  .addReg(ScratchReg)
1144  .addReg(ScratchReg)
1145  .addImm(CallTarget & 0xFFFF)
1146  .addImm(0));
1147  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::BLR).addReg(ScratchReg));
1148  }
1149  // Emit padding.
1150  unsigned NumBytes = Opers.getNumPatchBytes();
1151  assert(NumBytes >= EncodedBytes &&
1152  "Patchpoint can't request size less than the length of a call.");
1153  assert((NumBytes - EncodedBytes) % 4 == 0 &&
1154  "Invalid number of NOP bytes requested!");
1155  for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
1156  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
1157 }
1158 
1159 void AArch64AsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
1160  const MachineInstr &MI) {
1161  StatepointOpers SOpers(&MI);
1162  if (unsigned PatchBytes = SOpers.getNumPatchBytes()) {
1163  assert(PatchBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
1164  for (unsigned i = 0; i < PatchBytes; i += 4)
1165  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
1166  } else {
1167  // Lower call target and choose correct opcode
1168  const MachineOperand &CallTarget = SOpers.getCallTarget();
1169  MCOperand CallTargetMCOp;
1170  unsigned CallOpcode;
1171  switch (CallTarget.getType()) {
1174  MCInstLowering.lowerOperand(CallTarget, CallTargetMCOp);
1175  CallOpcode = AArch64::BL;
1176  break;
1178  CallTargetMCOp = MCOperand::createImm(CallTarget.getImm());
1179  CallOpcode = AArch64::BL;
1180  break;
1182  CallTargetMCOp = MCOperand::createReg(CallTarget.getReg());
1183  CallOpcode = AArch64::BLR;
1184  break;
1185  default:
1186  llvm_unreachable("Unsupported operand type in statepoint call target");
1187  break;
1188  }
1189 
1190  EmitToStreamer(OutStreamer,
1191  MCInstBuilder(CallOpcode).addOperand(CallTargetMCOp));
1192  }
1193 
1194  auto &Ctx = OutStreamer.getContext();
1195  MCSymbol *MILabel = Ctx.createTempSymbol();
1196  OutStreamer.emitLabel(MILabel);
1197  SM.recordStatepoint(*MILabel, MI);
1198 }
1199 
1200 void AArch64AsmPrinter::LowerFAULTING_OP(const MachineInstr &FaultingMI) {
1201  // FAULTING_LOAD_OP <def>, <faltinf type>, <MBB handler>,
1202  // <opcode>, <operands>
1203 
1204  Register DefRegister = FaultingMI.getOperand(0).getReg();
1206  static_cast<FaultMaps::FaultKind>(FaultingMI.getOperand(1).getImm());
1207  MCSymbol *HandlerLabel = FaultingMI.getOperand(2).getMBB()->getSymbol();
1208  unsigned Opcode = FaultingMI.getOperand(3).getImm();
1209  unsigned OperandsBeginIdx = 4;
1210 
1211  auto &Ctx = OutStreamer->getContext();
1212  MCSymbol *FaultingLabel = Ctx.createTempSymbol();
1213  OutStreamer->emitLabel(FaultingLabel);
1214 
1215  assert(FK < FaultMaps::FaultKindMax && "Invalid Faulting Kind!");
1216  FM.recordFaultingOp(FK, FaultingLabel, HandlerLabel);
1217 
1218  MCInst MI;
1219  MI.setOpcode(Opcode);
1220 
1221  if (DefRegister != (Register)0)
1222  MI.addOperand(MCOperand::createReg(DefRegister));
1223 
1224  for (const MachineOperand &MO :
1225  llvm::drop_begin(FaultingMI.operands(), OperandsBeginIdx)) {
1226  MCOperand Dest;
1227  lowerOperand(MO, Dest);
1228  MI.addOperand(Dest);
1229  }
1230 
1231  OutStreamer->AddComment("on-fault: " + HandlerLabel->getName());
1232  OutStreamer->emitInstruction(MI, getSubtargetInfo());
1233 }
1234 
1235 void AArch64AsmPrinter::emitFMov0(const MachineInstr &MI) {
1236  Register DestReg = MI.getOperand(0).getReg();
1237  if (STI->hasZeroCycleZeroingFP() && !STI->hasZeroCycleZeroingFPWorkaround() &&
1238  STI->hasNEON()) {
1239  // Convert H/S register to corresponding D register
1240  if (AArch64::H0 <= DestReg && DestReg <= AArch64::H31)
1241  DestReg = AArch64::D0 + (DestReg - AArch64::H0);
1242  else if (AArch64::S0 <= DestReg && DestReg <= AArch64::S31)
1243  DestReg = AArch64::D0 + (DestReg - AArch64::S0);
1244  else
1245  assert(AArch64::D0 <= DestReg && DestReg <= AArch64::D31);
1246 
1247  MCInst MOVI;
1248  MOVI.setOpcode(AArch64::MOVID);
1249  MOVI.addOperand(MCOperand::createReg(DestReg));
1250  MOVI.addOperand(MCOperand::createImm(0));
1251  EmitToStreamer(*OutStreamer, MOVI);
1252  } else {
1253  MCInst FMov;
1254  switch (MI.getOpcode()) {
1255  default: llvm_unreachable("Unexpected opcode");
1256  case AArch64::FMOVH0:
1257  FMov.setOpcode(AArch64::FMOVWHr);
1258  FMov.addOperand(MCOperand::createReg(DestReg));
1259  FMov.addOperand(MCOperand::createReg(AArch64::WZR));
1260  break;
1261  case AArch64::FMOVS0:
1262  FMov.setOpcode(AArch64::FMOVWSr);
1263  FMov.addOperand(MCOperand::createReg(DestReg));
1264  FMov.addOperand(MCOperand::createReg(AArch64::WZR));
1265  break;
1266  case AArch64::FMOVD0:
1267  FMov.setOpcode(AArch64::FMOVXDr);
1268  FMov.addOperand(MCOperand::createReg(DestReg));
1269  FMov.addOperand(MCOperand::createReg(AArch64::XZR));
1270  break;
1271  }
1272  EmitToStreamer(*OutStreamer, FMov);
1273  }
1274 }
1275 
1276 // Simple pseudo-instructions have their lowering (with expansion to real
1277 // instructions) auto-generated.
1278 #include "AArch64GenMCPseudoLowering.inc"
1279 
1280 void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
1281  AArch64_MC::verifyInstructionPredicates(MI->getOpcode(), STI->getFeatureBits());
1282 
1283  // Do any auto-generated pseudo lowerings.
1284  if (emitPseudoExpansionLowering(*OutStreamer, MI))
1285  return;
1286 
1287  if (MI->getOpcode() == AArch64::ADRP) {
1288  for (auto &Opd : MI->operands()) {
1289  if (Opd.isSymbol() && StringRef(Opd.getSymbolName()) ==
1290  "swift_async_extendedFramePointerFlags") {
1291  ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = true;
1292  }
1293  }
1294  }
1295 
1296  if (AArch64FI->getLOHRelated().count(MI)) {
1297  // Generate a label for LOH related instruction
1298  MCSymbol *LOHLabel = createTempSymbol("loh");
1299  // Associate the instruction with the label
1300  LOHInstToLabel[MI] = LOHLabel;
1301  OutStreamer->emitLabel(LOHLabel);
1302  }
1303 
1304  AArch64TargetStreamer *TS =
1305  static_cast<AArch64TargetStreamer *>(OutStreamer->getTargetStreamer());
1306  // Do any manual lowerings.
1307  switch (MI->getOpcode()) {
1308  default:
1309  break;
1310  case AArch64::HINT: {
1311  // CurrentPatchableFunctionEntrySym can be CurrentFnBegin only for
1312  // -fpatchable-function-entry=N,0. The entry MBB is guaranteed to be
1313  // non-empty. If MI is the initial BTI, place the
1314  // __patchable_function_entries label after BTI.
1315  if (CurrentPatchableFunctionEntrySym &&
1316  CurrentPatchableFunctionEntrySym == CurrentFnBegin &&
1317  MI == &MF->front().front()) {
1318  int64_t Imm = MI->getOperand(0).getImm();
1319  if ((Imm & 32) && (Imm & 6)) {
1320  MCInst Inst;
1321  MCInstLowering.Lower(MI, Inst);
1322  EmitToStreamer(*OutStreamer, Inst);
1323  CurrentPatchableFunctionEntrySym = createTempSymbol("patch");
1324  OutStreamer->emitLabel(CurrentPatchableFunctionEntrySym);
1325  return;
1326  }
1327  }
1328  break;
1329  }
1330  case AArch64::MOVMCSym: {
1331  Register DestReg = MI->getOperand(0).getReg();
1332  const MachineOperand &MO_Sym = MI->getOperand(1);
1333  MachineOperand Hi_MOSym(MO_Sym), Lo_MOSym(MO_Sym);
1334  MCOperand Hi_MCSym, Lo_MCSym;
1335 
1336  Hi_MOSym.setTargetFlags(AArch64II::MO_G1 | AArch64II::MO_S);
1337  Lo_MOSym.setTargetFlags(AArch64II::MO_G0 | AArch64II::MO_NC);
1338 
1339  MCInstLowering.lowerOperand(Hi_MOSym, Hi_MCSym);
1340  MCInstLowering.lowerOperand(Lo_MOSym, Lo_MCSym);
1341 
1342  MCInst MovZ;
1343  MovZ.setOpcode(AArch64::MOVZXi);
1344  MovZ.addOperand(MCOperand::createReg(DestReg));
1345  MovZ.addOperand(Hi_MCSym);
1346  MovZ.addOperand(MCOperand::createImm(16));
1347  EmitToStreamer(*OutStreamer, MovZ);
1348 
1349  MCInst MovK;
1350  MovK.setOpcode(AArch64::MOVKXi);
1351  MovK.addOperand(MCOperand::createReg(DestReg));
1352  MovK.addOperand(MCOperand::createReg(DestReg));
1353  MovK.addOperand(Lo_MCSym);
1355  EmitToStreamer(*OutStreamer, MovK);
1356  return;
1357  }
1358  case AArch64::MOVIv2d_ns:
1359  // If the target has <rdar://problem/16473581>, lower this
1360  // instruction to movi.16b instead.
1361  if (STI->hasZeroCycleZeroingFPWorkaround() &&
1362  MI->getOperand(1).getImm() == 0) {
1363  MCInst TmpInst;
1364  TmpInst.setOpcode(AArch64::MOVIv16b_ns);
1365  TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1366  TmpInst.addOperand(MCOperand::createImm(MI->getOperand(1).getImm()));
1367  EmitToStreamer(*OutStreamer, TmpInst);
1368  return;
1369  }
1370  break;
1371 
1372  case AArch64::DBG_VALUE:
1373  case AArch64::DBG_VALUE_LIST:
1374  if (isVerbose() && OutStreamer->hasRawTextSupport()) {
1375  SmallString<128> TmpStr;
1376  raw_svector_ostream OS(TmpStr);
1377  PrintDebugValueComment(MI, OS);
1378  OutStreamer->emitRawText(StringRef(OS.str()));
1379  }
1380  return;
1381 
1382  case AArch64::EMITBKEY: {
1383  ExceptionHandling ExceptionHandlingType = MAI->getExceptionHandlingType();
1384  if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
1385  ExceptionHandlingType != ExceptionHandling::ARM)
1386  return;
1387 
1388  if (getFunctionCFISectionType(*MF) == CFISection::None)
1389  return;
1390 
1391  OutStreamer->emitCFIBKeyFrame();
1392  return;
1393  }
1394 
1395  case AArch64::EMITMTETAGGED: {
1396  ExceptionHandling ExceptionHandlingType = MAI->getExceptionHandlingType();
1397  if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
1398  ExceptionHandlingType != ExceptionHandling::ARM)
1399  return;
1400 
1401  if (getFunctionCFISectionType(*MF) != CFISection::None)
1402  OutStreamer->emitCFIMTETaggedFrame();
1403  return;
1404  }
1405 
1406  // Tail calls use pseudo instructions so they have the proper code-gen
1407  // attributes (isCall, isReturn, etc.). We lower them to the real
1408  // instruction here.
1409  case AArch64::TCRETURNri:
1410  case AArch64::TCRETURNriBTI:
1411  case AArch64::TCRETURNriALL: {
1412  MCInst TmpInst;
1413  TmpInst.setOpcode(AArch64::BR);
1414  TmpInst.addOperand(MCOperand::createReg(MI->getOperand(0).getReg()));
1415  EmitToStreamer(*OutStreamer, TmpInst);
1416  return;
1417  }
1418  case AArch64::TCRETURNdi: {
1419  MCOperand Dest;
1420  MCInstLowering.lowerOperand(MI->getOperand(0), Dest);
1421  MCInst TmpInst;
1422  TmpInst.setOpcode(AArch64::B);
1423  TmpInst.addOperand(Dest);
1424  EmitToStreamer(*OutStreamer, TmpInst);
1425  return;
1426  }
1427  case AArch64::SpeculationBarrierISBDSBEndBB: {
1428  // Print DSB SYS + ISB
1429  MCInst TmpInstDSB;
1430  TmpInstDSB.setOpcode(AArch64::DSB);
1431  TmpInstDSB.addOperand(MCOperand::createImm(0xf));
1432  EmitToStreamer(*OutStreamer, TmpInstDSB);
1433  MCInst TmpInstISB;
1434  TmpInstISB.setOpcode(AArch64::ISB);
1435  TmpInstISB.addOperand(MCOperand::createImm(0xf));
1436  EmitToStreamer(*OutStreamer, TmpInstISB);
1437  return;
1438  }
1439  case AArch64::SpeculationBarrierSBEndBB: {
1440  // Print SB
1441  MCInst TmpInstSB;
1442  TmpInstSB.setOpcode(AArch64::SB);
1443  EmitToStreamer(*OutStreamer, TmpInstSB);
1444  return;
1445  }
1446  case AArch64::TLSDESC_CALLSEQ: {
1447  /// lower this to:
1448  /// adrp x0, :tlsdesc:var
1449  /// ldr x1, [x0, #:tlsdesc_lo12:var]
1450  /// add x0, x0, #:tlsdesc_lo12:var
1451  /// .tlsdesccall var
1452  /// blr x1
1453  /// (TPIDR_EL0 offset now in x0)
1454  const MachineOperand &MO_Sym = MI->getOperand(0);
1455  MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym);
1456  MCOperand Sym, SymTLSDescLo12, SymTLSDesc;
1457  MO_TLSDESC_LO12.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGEOFF);
1458  MO_TLSDESC.setTargetFlags(AArch64II::MO_TLS | AArch64II::MO_PAGE);
1459  MCInstLowering.lowerOperand(MO_Sym, Sym);
1460  MCInstLowering.lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
1461  MCInstLowering.lowerOperand(MO_TLSDESC, SymTLSDesc);
1462 
1463  MCInst Adrp;
1464  Adrp.setOpcode(AArch64::ADRP);
1465  Adrp.addOperand(MCOperand::createReg(AArch64::X0));
1466  Adrp.addOperand(SymTLSDesc);
1467  EmitToStreamer(*OutStreamer, Adrp);
1468 
1469  MCInst Ldr;
1470  if (STI->isTargetILP32()) {
1471  Ldr.setOpcode(AArch64::LDRWui);
1472  Ldr.addOperand(MCOperand::createReg(AArch64::W1));
1473  } else {
1474  Ldr.setOpcode(AArch64::LDRXui);
1475  Ldr.addOperand(MCOperand::createReg(AArch64::X1));
1476  }
1477  Ldr.addOperand(MCOperand::createReg(AArch64::X0));
1478  Ldr.addOperand(SymTLSDescLo12);
1480  EmitToStreamer(*OutStreamer, Ldr);
1481 
1482  MCInst Add;
1483  if (STI->isTargetILP32()) {
1484  Add.setOpcode(AArch64::ADDWri);
1485  Add.addOperand(MCOperand::createReg(AArch64::W0));
1486  Add.addOperand(MCOperand::createReg(AArch64::W0));
1487  } else {
1488  Add.setOpcode(AArch64::ADDXri);
1489  Add.addOperand(MCOperand::createReg(AArch64::X0));
1490  Add.addOperand(MCOperand::createReg(AArch64::X0));
1491  }
1492  Add.addOperand(SymTLSDescLo12);
1494  EmitToStreamer(*OutStreamer, Add);
1495 
1496  // Emit a relocation-annotation. This expands to no code, but requests
1497  // the following instruction gets an R_AARCH64_TLSDESC_CALL.
1498  MCInst TLSDescCall;
1499  TLSDescCall.setOpcode(AArch64::TLSDESCCALL);
1500  TLSDescCall.addOperand(Sym);
1501  EmitToStreamer(*OutStreamer, TLSDescCall);
1502 
1503  MCInst Blr;
1504  Blr.setOpcode(AArch64::BLR);
1505  Blr.addOperand(MCOperand::createReg(AArch64::X1));
1506  EmitToStreamer(*OutStreamer, Blr);
1507 
1508  return;
1509  }
1510 
1511  case AArch64::JumpTableDest32:
1512  case AArch64::JumpTableDest16:
1513  case AArch64::JumpTableDest8:
1514  LowerJumpTableDest(*OutStreamer, *MI);
1515  return;
1516 
1517  case AArch64::FMOVH0:
1518  case AArch64::FMOVS0:
1519  case AArch64::FMOVD0:
1520  emitFMov0(*MI);
1521  return;
1522 
1523  case AArch64::MOPSMemoryCopyPseudo:
1524  case AArch64::MOPSMemoryMovePseudo:
1525  case AArch64::MOPSMemorySetPseudo:
1526  case AArch64::MOPSMemorySetTaggingPseudo:
1527  LowerMOPS(*OutStreamer, *MI);
1528  return;
1529 
1531  return LowerSTACKMAP(*OutStreamer, SM, *MI);
1532 
1534  return LowerPATCHPOINT(*OutStreamer, SM, *MI);
1535 
1536  case TargetOpcode::STATEPOINT:
1537  return LowerSTATEPOINT(*OutStreamer, SM, *MI);
1538 
1539  case TargetOpcode::FAULTING_OP:
1540  return LowerFAULTING_OP(*MI);
1541 
1542  case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
1543  LowerPATCHABLE_FUNCTION_ENTER(*MI);
1544  return;
1545 
1546  case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1547  LowerPATCHABLE_FUNCTION_EXIT(*MI);
1548  return;
1549 
1550  case TargetOpcode::PATCHABLE_TAIL_CALL:
1551  LowerPATCHABLE_TAIL_CALL(*MI);
1552  return;
1553 
1554  case AArch64::KCFI_CHECK:
1555  LowerKCFI_CHECK(*MI);
1556  return;
1557 
1558  case AArch64::HWASAN_CHECK_MEMACCESS:
1559  case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
1560  LowerHWASAN_CHECK_MEMACCESS(*MI);
1561  return;
1562 
1563  case AArch64::SEH_StackAlloc:
1564  TS->emitARM64WinCFIAllocStack(MI->getOperand(0).getImm());
1565  return;
1566 
1567  case AArch64::SEH_SaveFPLR:
1568  TS->emitARM64WinCFISaveFPLR(MI->getOperand(0).getImm());
1569  return;
1570 
1571  case AArch64::SEH_SaveFPLR_X:
1572  assert(MI->getOperand(0).getImm() < 0 &&
1573  "Pre increment SEH opcode must have a negative offset");
1574  TS->emitARM64WinCFISaveFPLRX(-MI->getOperand(0).getImm());
1575  return;
1576 
1577  case AArch64::SEH_SaveReg:
1578  TS->emitARM64WinCFISaveReg(MI->getOperand(0).getImm(),
1579  MI->getOperand(1).getImm());
1580  return;
1581 
1582  case AArch64::SEH_SaveReg_X:
1583  assert(MI->getOperand(1).getImm() < 0 &&
1584  "Pre increment SEH opcode must have a negative offset");
1585  TS->emitARM64WinCFISaveRegX(MI->getOperand(0).getImm(),
1586  -MI->getOperand(1).getImm());
1587  return;
1588 
1589  case AArch64::SEH_SaveRegP:
1590  if (MI->getOperand(1).getImm() == 30 && MI->getOperand(0).getImm() >= 19 &&
1591  MI->getOperand(0).getImm() <= 28) {
1592  assert((MI->getOperand(0).getImm() - 19) % 2 == 0 &&
1593  "Register paired with LR must be odd");
1594  TS->emitARM64WinCFISaveLRPair(MI->getOperand(0).getImm(),
1595  MI->getOperand(2).getImm());
1596  return;
1597  }
1598  assert((MI->getOperand(1).getImm() - MI->getOperand(0).getImm() == 1) &&
1599  "Non-consecutive registers not allowed for save_regp");
1600  TS->emitARM64WinCFISaveRegP(MI->getOperand(0).getImm(),
1601  MI->getOperand(2).getImm());
1602  return;
1603 
1604  case AArch64::SEH_SaveRegP_X:
1605  assert((MI->getOperand(1).getImm() - MI->getOperand(0).getImm() == 1) &&
1606  "Non-consecutive registers not allowed for save_regp_x");
1607  assert(MI->getOperand(2).getImm() < 0 &&
1608  "Pre increment SEH opcode must have a negative offset");
1609  TS->emitARM64WinCFISaveRegPX(MI->getOperand(0).getImm(),
1610  -MI->getOperand(2).getImm());
1611  return;
1612 
1613  case AArch64::SEH_SaveFReg:
1614  TS->emitARM64WinCFISaveFReg(MI->getOperand(0).getImm(),
1615  MI->getOperand(1).getImm());
1616  return;
1617 
1618  case AArch64::SEH_SaveFReg_X:
1619  assert(MI->getOperand(1).getImm() < 0 &&
1620  "Pre increment SEH opcode must have a negative offset");
1621  TS->emitARM64WinCFISaveFRegX(MI->getOperand(0).getImm(),
1622  -MI->getOperand(1).getImm());
1623  return;
1624 
1625  case AArch64::SEH_SaveFRegP:
1626  assert((MI->getOperand(1).getImm() - MI->getOperand(0).getImm() == 1) &&
1627  "Non-consecutive registers not allowed for save_regp");
1628  TS->emitARM64WinCFISaveFRegP(MI->getOperand(0).getImm(),
1629  MI->getOperand(2).getImm());
1630  return;
1631 
1632  case AArch64::SEH_SaveFRegP_X:
1633  assert((MI->getOperand(1).getImm() - MI->getOperand(0).getImm() == 1) &&
1634  "Non-consecutive registers not allowed for save_regp_x");
1635  assert(MI->getOperand(2).getImm() < 0 &&
1636  "Pre increment SEH opcode must have a negative offset");
1637  TS->emitARM64WinCFISaveFRegPX(MI->getOperand(0).getImm(),
1638  -MI->getOperand(2).getImm());
1639  return;
1640 
1641  case AArch64::SEH_SetFP:
1642  TS->emitARM64WinCFISetFP();
1643  return;
1644 
1645  case AArch64::SEH_AddFP:
1646  TS->emitARM64WinCFIAddFP(MI->getOperand(0).getImm());
1647  return;
1648 
1649  case AArch64::SEH_Nop:
1650  TS->emitARM64WinCFINop();
1651  return;
1652 
1653  case AArch64::SEH_PrologEnd:
1655  return;
1656 
1657  case AArch64::SEH_EpilogStart:
1659  return;
1660 
1661  case AArch64::SEH_EpilogEnd:
1663  return;
1664 
1665  case AArch64::SEH_PACSignLR:
1667  return;
1668  }
1669 
1670  // Finally, do the automated lowerings for everything else.
1671  MCInst TmpInst;
1672  MCInstLowering.Lower(MI, TmpInst);
1673  EmitToStreamer(*OutStreamer, TmpInst);
1674 }
1675 
1676 // Force static initialization.
1683 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
i
i
Definition: README.txt:29
AsmPrinter.h
llvm::AArch64MCExpr::create
static const AArch64MCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
Definition: AArch64MCExpr.cpp:27
llvm::MachineOperand::MO_BlockAddress
@ MO_BlockAddress
Address of a basic block.
Definition: MachineOperand.h:62
AArch64RegisterInfo.h
MachineModuleInfoImpls.h
llvm::AArch64MCInstLower::lowerOperand
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const
Definition: AArch64MCInstLower.cpp:282
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:109
llvm::AArch64CC::HI
@ HI
Definition: AArch64BaseInfo.h:263
MachineInstr.h
llvm::MachineOperand::MO_Immediate
@ MO_Immediate
Immediate operand.
Definition: MachineOperand.h:52
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::StackMapOpers
MI-level stackmap operands.
Definition: StackMaps.h:35
AArch64MachineFunctionInfo.h
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::ELF::SHF_EXECINSTR
@ SHF_EXECINSTR
Definition: ELF.h:1071
llvm::ISD::PATCHPOINT
@ PATCHPOINT
Definition: ISDOpcodes.h:1299
AArch64.h
llvm::drop_begin
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:387
llvm::StackMaps::recordStatepoint
void recordStatepoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a statepoint instruction.
Definition: StackMaps.cpp:555
llvm::AArch64CC::NE
@ NE
Definition: AArch64BaseInfo.h:256
llvm::ARM::PredBlockMask::TT
@ TT
llvm::AArch64II::MO_G1
@ MO_G1
MO_G1 - A symbol operand with this flag (granule 1) represents the bits 16-31 of a 64-bit address,...
Definition: AArch64BaseInfo.h:751
LLVMInitializeAArch64AsmPrinter
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmPrinter()
Definition: AArch64AsmPrinter.cpp:1677
llvm::COFF::IMAGE_SYM_CLASS_STATIC
@ IMAGE_SYM_CLASS_STATIC
Static.
Definition: COFF.h:210
DebugInfoMetadata.h
llvm::AArch64TargetStreamer::emitARM64WinCFISaveRegPX
virtual void emitARM64WinCFISaveRegPX(unsigned Reg, int Offset)
Definition: AArch64TargetStreamer.h:53
llvm::HexagonISD::JT
@ JT
Definition: HexagonISelLowering.h:52
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
llvm::Function
Definition: Function.h:60
StringRef.h
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::AArch64TargetStreamer::emitNoteSection
void emitNoteSection(unsigned Flags)
Callback used to implement the .note.gnu.property section.
Definition: AArch64TargetStreamer.cpp:62
llvm::MCConstantExpr::create
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
contains
return AArch64::GPR64RegClass contains(Reg)
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:149
llvm::MCStreamer::hasRawTextSupport
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText.
Definition: MCStreamer.h:336
llvm::AArch64TargetStreamer::emitARM64WinCFISaveFPLRX
virtual void emitARM64WinCFISaveFPLRX(int Offset)
Definition: AArch64TargetStreamer.h:49
MCSectionELF.h
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
llvm::RISCVFenceField::W
@ W
Definition: RISCVBaseInfo.h:266
llvm::MachineOperand::getBlockAddress
const BlockAddress * getBlockAddress() const
Definition: MachineOperand.h:577
llvm::MCStreamer::emitCOFFSymbolStorageClass
virtual void emitCOFFSymbolStorageClass(int StorageClass)
Emit the storage class of the symbol.
Definition: MCStreamer.cpp:1163
AArch64MCExpr.h
llvm::COFF::IMAGE_SYM_CLASS_EXTERNAL
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
Definition: COFF.h:209
ErrorHandling.h
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::FaultMaps
Definition: FaultMaps.h:21
llvm::AArch64InstPrinter::getRegisterName
static const char * getRegisterName(unsigned RegNo, unsigned AltIdx=AArch64::NoRegAltName)
AArch64BaseInfo.h
llvm::getTheAArch64_32Target
Target & getTheAArch64_32Target()
Definition: AArch64TargetInfo.cpp:21
MCInstBuilder.h
llvm::COFF::SCT_COMPLEX_TYPE_SHIFT
@ SCT_COMPLEX_TYPE_SHIFT
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
Definition: COFF.h:265
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
MachineBasicBlock.h
llvm::MCStreamer::emitCOFFSymbolType
virtual void emitCOFFSymbolType(int Type)
Emit the type of the symbol.
Definition: MCStreamer.cpp:1166
COFF.h
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:236
llvm::MCRegisterInfo::getEncodingValue
uint16_t getEncodingValue(MCRegister RegNo) const
Returns the encoding for RegNo.
Definition: MCRegisterInfo.h:553
llvm::AArch64FunctionInfo::isSVECC
bool isSVECC() const
Definition: AArch64MachineFunctionInfo.h:205
MachineJumpTableInfo.h
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::AArch64TargetStreamer::emitARM64WinCFIPACSignLR
virtual void emitARM64WinCFIPACSignLR()
Definition: AArch64TargetStreamer.h:70
printOperand
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
Definition: SelectionDAGDumper.cpp:958
llvm::AArch64TargetStreamer::emitARM64WinCFISetFP
virtual void emitARM64WinCFISetFP()
Definition: AArch64TargetStreamer.h:59
llvm::ExceptionHandling::ARM
@ ARM
ARM EHABI.
llvm::ELF::SHT_PROGBITS
@ SHT_PROGBITS
Definition: ELF.h:980
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::AArch64TargetStreamer::emitARM64WinCFISaveRegP
virtual void emitARM64WinCFISaveRegP(unsigned Reg, int Offset)
Definition: AArch64TargetStreamer.h:52
llvm::AArch64ISD::TLSDESC_CALLSEQ
@ TLSDESC_CALLSEQ
Definition: AArch64ISelLowering.h:74
llvm::PatchPointOpers
MI-level patchpoint operands.
Definition: StackMaps.h:76
llvm::StackMaps
Definition: StackMaps.h:251
llvm::ARCISD::BL
@ BL
Definition: ARCISelLowering.h:34
llvm::MachineOperand::MO_Register
@ MO_Register
Register operand.
Definition: MachineOperand.h:51
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::AArch64II::MO_TLS
@ MO_TLS
MO_TLS - Indicates that the operand being accessed is some kind of thread-local symbol.
Definition: AArch64BaseInfo.h:781
llvm::StackMaps::recordStackMap
void recordStackMap(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
Definition: StackMaps.cpp:524
llvm::COFF::SymbolStorageClass
SymbolStorageClass
Storage class tells where and what the symbol represents.
Definition: COFF.h:203
llvm::MCInst::setOpcode
void setOpcode(unsigned Op)
Definition: MCInst.h:197
llvm::AArch64FunctionInfo::getOutliningStyle
std::optional< std::string > getOutliningStyle() const
Definition: AArch64MachineFunctionInfo.h:254
llvm::TargetLoweringObjectFile
Definition: TargetLoweringObjectFile.h:45
llvm::AArch64TargetStreamer::emitARM64WinCFISaveReg
virtual void emitARM64WinCFISaveReg(unsigned Reg, int Offset)
Definition: AArch64TargetStreamer.h:50
llvm::MachineBasicBlock::getSymbol
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Definition: MachineBasicBlock.cpp:59
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:212
llvm::AArch64TargetStreamer::emitARM64WinCFIAddFP
virtual void emitARM64WinCFIAddFP(unsigned Size)
Definition: AArch64TargetStreamer.h:60
llvm::AArch64II::MO_G0
@ MO_G0
MO_G0 - A symbol operand with this flag (granule 0) represents the bits 0-15 of a 64-bit address,...
Definition: AArch64BaseInfo.h:755
ELF.h
TargetMachine.h
llvm::StackMapOpers::getNumPatchBytes
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
Definition: StackMaps.h:50
llvm::AArch64MCInstLower
AArch64MCInstLower - This class is used to lower an MachineInstr into an MCInst.
Definition: AArch64MCInstLower.h:26
HWAddressSanitizer.h
SmallString.h
llvm::MachineOperand::MO_GlobalAddress
@ MO_GlobalAddress
Address of a global value.
Definition: MachineOperand.h:61
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:546
llvm::getTheAArch64leTarget
Target & getTheAArch64leTarget()
Definition: AArch64TargetInfo.cpp:13
llvm::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition: MachineFunction.h:758
llvm::ExceptionHandling
ExceptionHandling
Definition: MCTargetOptions.h:19
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:526
Twine.h
MCContext.h
Y
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
llvm::Register::isPhysicalRegister
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:65
llvm::MCStreamer::emitLabel
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:421
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:45
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition: PassAnalysisSupport.h:47
llvm::AArch64TargetStreamer::emitARM64WinCFISaveFPLR
virtual void emitARM64WinCFISaveFPLR(int Offset)
Definition: AArch64TargetStreamer.h:48
llvm::AsmPrinter::emitFunctionEntryLabel
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
Definition: AsmPrinter.cpp:1043
MCSymbol.h
llvm::AArch64TargetStreamer::emitARM64WinCFISaveRegX
virtual void emitARM64WinCFISaveRegX(unsigned Reg, int Offset)
Definition: AArch64TargetStreamer.h:51
MCInst.h
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:48
llvm::AArch64_AM::LSR
@ LSR
Definition: AArch64AddressingModes.h:36
llvm::AArch64_AM::getShifterImm
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
Definition: AArch64AddressingModes.h:99
AArch64TargetObjectFile.h
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::AArch64_AM::getShiftValue
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
Definition: AArch64AddressingModes.h:86
llvm::ELF::GNU_PROPERTY_AARCH64_FEATURE_1_BTI
@ GNU_PROPERTY_AARCH64_FEATURE_1_BTI
Definition: ELF.h:1656
llvm::MCSA_Hidden
@ MCSA_Hidden
.hidden (ELF)
Definition: MCDirectives.h:33
llvm::GlobalValue::hasInternalLinkage
bool hasInternalLinkage() const
Definition: GlobalValue.h:521
llvm::MCSymbol::getName
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:198
Align
uint64_t Align
Definition: ELFObjHandler.cpp:82
llvm::AArch64TargetStreamer::emitDirectiveVariantPCS
virtual void emitDirectiveVariantPCS(MCSymbol *Symbol)
Callback used to implement the .variant_pcs directive.
Definition: AArch64TargetStreamer.h:44
llvm::AArch64TargetStreamer::emitARM64WinCFIEpilogEnd
virtual void emitARM64WinCFIEpilogEnd()
Definition: AArch64TargetStreamer.h:65
llvm::HWASanAccessInfo::RuntimeMask
@ RuntimeMask
Definition: HWAddressSanitizer.h:66
llvm::TargetLoweringObjectFile::getSectionForJumpTable
virtual MCSection * getSectionForJumpTable(const Function &F, const TargetMachine &TM) const
Definition: TargetLoweringObjectFile.cpp:355
llvm::MCSymbol::print
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:58
X
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
llvm::SmallString< 128 >
AArch64AddressingModes.h
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:660
llvm::AArch64II::MO_S
@ MO_S
MO_S - Indicates that the bits of the symbol operand represented by MO_G0 etc are signed.
Definition: AArch64BaseInfo.h:790
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:264
llvm::MachineJumpTableInfo::getJumpTables
const std::vector< MachineJumpTableEntry > & getJumpTables() const
Definition: MachineJumpTableInfo.h:99
llvm::AArch64TargetStreamer::emitARM64WinCFISaveFReg
virtual void emitARM64WinCFISaveFReg(unsigned Reg, int Offset)
Definition: AArch64TargetStreamer.h:55
llvm::TargetRegisterInfo::regsOverlap
bool regsOverlap(Register RegA, Register RegB) const
Returns true if the two registers are equal or alias each other.
Definition: TargetRegisterInfo.h:421
llvm::MCStreamer::beginCOFFSymbolDef
virtual void beginCOFFSymbolDef(const MCSymbol *Symbol)
Start emitting COFF symbol definition.
Definition: MCStreamer.cpp:1153
llvm::MCAF_SubsectionsViaSymbols
@ MCAF_SubsectionsViaSymbols
.subsections_via_symbols (MachO)
Definition: MCDirectives.h:54
llvm::AsmPrinter::GetCPISymbol
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
Definition: AsmPrinter.cpp:3557
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:320
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
llvm::omp::Kernel
Function * Kernel
Summary of a kernel (=entry point for target offloading).
Definition: OpenMPOpt.h:21
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:127
llvm::M68kISD::TAIL_CALL
@ TAIL_CALL
Definition: M68kISelLowering.h:37
llvm::MCStreamer::emitCFIBKeyFrame
virtual void emitCFIBKeyFrame()
Definition: MCStreamer.cpp:246
llvm::MCStreamer::emitRawText
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:991
llvm::AArch64II::MO_NC
@ MO_NC
MO_NC - Indicates whether the linker is expected to check the symbol reference for overflow.
Definition: AArch64BaseInfo.h:775
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:53
llvm::AArch64II::MO_PAGEOFF
@ MO_PAGEOFF
MO_PAGEOFF - A symbol operand with this flag represents the offset of that symbol within a 4K page.
Definition: AArch64BaseInfo.h:739
llvm::MCStreamer::emitInstruction
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:1094
llvm::AArch64TargetStreamer::emitARM64WinCFINop
virtual void emitARM64WinCFINop()
Definition: AArch64TargetStreamer.h:61
llvm::AArch64FunctionInfo
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
Definition: AArch64MachineFunctionInfo.h:38
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::MCInstBuilder
Definition: MCInstBuilder.h:21
llvm::MCStreamer::endCOFFSymbolDef
virtual void endCOFFSymbolDef()
Marks the end of the symbol definition.
Definition: MCStreamer.cpp:1156
llvm::MachineOperand::getType
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Definition: MachineOperand.h:218
llvm::ELF::SHF_ALLOC
@ SHF_ALLOC
Definition: ELF.h:1068
llvm::AArch64TargetStreamer::emitARM64WinCFISaveFRegPX
virtual void emitARM64WinCFISaveFRegPX(unsigned Reg, int Offset)
Definition: AArch64TargetStreamer.h:58
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:76
addOperand
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
Definition: AMDGPUDisassembler.cpp:59
llvm::AArch64TargetStreamer
Definition: AArch64TargetStreamer.h:20
llvm::ISD::STACKMAP
@ STACKMAP
Definition: ISDOpcodes.h:1293
llvm::MCBinaryExpr::createSub
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:610
llvm::ELF::GNU_PROPERTY_AARCH64_FEATURE_1_PAC
@ GNU_PROPERTY_AARCH64_FEATURE_1_PAC
Definition: ELF.h:1657
Mode
SI Whole Quad Mode
Definition: SIWholeQuadMode.cpp:264
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:359
llvm::MCBinaryExpr::createLShr
static const MCBinaryExpr * createLShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:605
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::MCSymbolRefExpr
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
llvm::MachineFunction
Definition: MachineFunction.h:257
Triple.h
llvm::getTheARM64_32Target
Target & getTheARM64_32Target()
Definition: AArch64TargetInfo.cpp:29
llvm::COFF::GuardCF
@ GuardCF
Definition: COFF.h:785
llvm::AArch64_AM::encodeLogicalImmediate
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
Definition: AArch64AddressingModes.h:283
llvm::AArch64TargetStreamer::emitARM64WinCFISaveLRPair
virtual void emitARM64WinCFISaveLRPair(unsigned Reg, int Offset)
Definition: AArch64TargetStreamer.h:54
llvm::MachineOperand::getMBB
MachineBasicBlock * getMBB() const
Definition: MachineOperand.h:561
MCAsmInfo.h
AArch64InstPrinter.h
DataLayout.h
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::AsmPrinter::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
Record analysis usage.
Definition: AsmPrinter.cpp:425
llvm::MCInstBuilder::addImm
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:37
llvm::AArch64TargetStreamer::emitARM64WinCFIAllocStack
virtual void emitARM64WinCFIAllocStack(unsigned Size)
Definition: AArch64TargetStreamer.h:46
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::MCOperand::createReg
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
uint32_t
llvm::AArch64ISD::MOVI
@ MOVI
Definition: AArch64ISelLowering.h:176
llvm::AArch64ISD::ADR
@ ADR
Definition: AArch64ISelLowering.h:76
llvm::COFF::GuardEHCont
@ GuardEHCont
Definition: COFF.h:787
llvm::MCSection
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::FaultMaps::FaultKindMax
@ FaultKindMax
Definition: FaultMaps.h:27
llvm::MCInstBuilder::addExpr
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Definition: MCInstBuilder.h:55
printAsmMRegister
static bool printAsmMRegister(const X86AsmPrinter &P, const MachineOperand &MO, char Mode, raw_ostream &O)
Definition: X86AsmPrinter.cpp:531
llvm::AArch64CC::EQ
@ EQ
Definition: AArch64BaseInfo.h:255
llvm::AArch64TargetStreamer::emitARM64WinCFISaveFRegP
virtual void emitARM64WinCFISaveFRegP(unsigned Reg, int Offset)
Definition: AArch64TargetStreamer.h:57
llvm::AArch64TargetStreamer::emitARM64WinCFIPrologEnd
virtual void emitARM64WinCFIPrologEnd()
Definition: AArch64TargetStreamer.h:63
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MachineOperand::getSubReg
unsigned getSubReg() const
Definition: MachineOperand.h:364
llvm::getXRegFromXRegTuple
static unsigned getXRegFromXRegTuple(unsigned RegTuple)
Definition: AArch64BaseInfo.h:109
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::getXRegFromWReg
static unsigned getXRegFromWReg(unsigned Reg)
Definition: AArch64BaseInfo.h:69
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
llvm::StatepointOpers
MI-level Statepoint operands.
Definition: StackMaps.h:158
llvm::pdb::PDB_SymType::Label
@ Label
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:626
llvm::None
constexpr std::nullopt_t None
Definition: None.h:27
llvm::AnalysisUsage::setPreservesAll
void setPreservesAll()
Set by analyses that do not transform their input at all.
Definition: PassAnalysisSupport.h:130
llvm::HWASanAccessInfo::CompileKernelShift
@ CompileKernelShift
Definition: HWAddressSanitizer.h:63
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:351
llvm::ISD::BR
@ BR
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:982
llvm::TargetRegisterClass::getRegister
MCRegister getRegister(unsigned i) const
Return the specified register in the class.
Definition: TargetRegisterInfo.h:90
llvm::ARCISD::RET
@ RET
Definition: ARCISelLowering.h:52
llvm::MachineOperand::MO_ExternalSymbol
@ MO_ExternalSymbol
Name of external global symbol.
Definition: MachineOperand.h:60
llvm::AArch64CC::LS
@ LS
Definition: AArch64BaseInfo.h:264
Casting.h
llvm::AArch64TargetStreamer::emitARM64WinCFISaveFRegX
virtual void emitARM64WinCFISaveFRegX(unsigned Reg, int Offset)
Definition: AArch64TargetStreamer.h:56
llvm::StackMaps::recordPatchPoint
void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
Definition: StackMaps.cpp:534
llvm::getTheAArch64beTarget
Target & getTheAArch64beTarget()
Definition: AArch64TargetInfo.cpp:17
llvm::ARCCC::Z
@ Z
Definition: ARCInfo.h:41
StackMaps.h
llvm::AsmPrinter
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:84
AArch64MCTargetDesc.h
llvm::MCSymbolRefExpr::create
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:386
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:614
llvm::MCID::Add
@ Add
Definition: MCInstrDesc.h:185
AArch64TargetStreamer.h
llvm::MCSA_Global
@ MCSA_Global
.type _foo, @gnu_unique_object
Definition: MCDirectives.h:30
llvm::MachineOperand::isImm
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Definition: MachineOperand.h:322
llvm::AArch64ISD::ADRP
@ ADRP
Definition: AArch64ISelLowering.h:75
llvm::MCSA_ELF_TypeFunction
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Definition: MCDirectives.h:23
llvm::HWASanAccessInfo::AccessSizeShift
@ AccessSizeShift
Definition: HWAddressSanitizer.h:58
llvm::RISCVMatInt::Imm
@ Imm
Definition: RISCVMatInt.h:23
llvm::FaultMaps::FaultKind
FaultKind
Definition: FaultMaps.h:23
llvm::MCSA_Weak
@ MCSA_Weak
.weak
Definition: MCDirectives.h:45
llvm::Pass
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
llvm::getWRegFromXReg
static unsigned getWRegFromXReg(unsigned Reg)
Definition: AArch64BaseInfo.h:29
AArch64Subtarget.h
llvm::MCStreamer::getContext
MCContext & getContext() const
Definition: MCStreamer.h:293
SmallVector.h
llvm::MCStreamer::getTargetStreamer
MCTargetStreamer * getTargetStreamer()
Definition: MCStreamer.h:300
llvm::HWASanAccessInfo::MatchAllShift
@ MatchAllShift
Definition: HWAddressSanitizer.h:61
llvm::COFF::IMAGE_SYM_DTYPE_NULL
@ IMAGE_SYM_DTYPE_NULL
No complex type; simple scalar variable.
Definition: COFF.h:259
llvm::getTheARM64Target
Target & getTheARM64Target()
Definition: AArch64TargetInfo.cpp:25
MCStreamer.h
llvm::raw_svector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:659
llvm::ELF::SHF_GROUP
@ SHF_GROUP
Definition: ELF.h:1090
llvm::MCInstBuilder::addReg
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
Definition: MCInstBuilder.h:31
MachineOperand.h
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::omp::RTLDependInfoFields::Flags
@ Flags
FaultMaps.h
llvm::RegisterAsmPrinter
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...
Definition: TargetRegistry.h:1419
llvm::AArch64TargetStreamer::emitARM64WinCFIEpilogStart
virtual void emitARM64WinCFIEpilogStart()
Definition: AArch64TargetStreamer.h:64
llvm::MachineJumpTableInfo
Definition: MachineJumpTableInfo.h:42
llvm::AArch64Subtarget
Definition: AArch64Subtarget.h:38
raw_ostream.h
MachineFunction.h
llvm::COFF::IMAGE_SYM_DTYPE_FUNCTION
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
Definition: COFF.h:261
llvm::CallingConv::AArch64_SVE_VectorCall
@ AArch64_SVE_VectorCall
Used between AArch64 SVE functions.
Definition: CallingConv.h:225
llvm::MachineInstrBundleIterator< const MachineInstr >
TargetRegistry.h
llvm::HWASanAccessInfo::HasMatchAllShift
@ HasMatchAllShift
Definition: HWAddressSanitizer.h:62
llvm::ExceptionHandling::DwarfCFI
@ DwarfCFI
DWARF-like instruction based exceptions.
llvm::MachineInstr::operands
iterator_range< mop_iterator > operands()
Definition: MachineInstr.h:641
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
TargetRegisterInfo.h
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
llvm::CallingConv::AArch64_VectorCall
@ AArch64_VectorCall
Used between AArch64 Advanced SIMD functions.
Definition: CallingConv.h:222
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:311
llvm::AsmPrinter::PrintAsmOperand
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.
Definition: AsmPrinterInlineAsm.cpp:467
llvm::MCStreamer::AddComment
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
Definition: MCStreamer.h:355
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::AArch64II::MO_PAGE
@ MO_PAGE
MO_PAGE - A symbol operand with this flag represents the pc-relative offset of the 4K page containing...
Definition: AArch64BaseInfo.h:734
AArch64TargetInfo.h
AArch64MCInstLower.h
llvm::MCStreamer::emitCFIMTETaggedFrame
virtual void emitCFIMTETaggedFrame()
Definition: MCStreamer.cpp:253