LLVM  13.0.0git
AArch64AsmBackend.cpp
Go to the documentation of this file.
1 //===-- AArch64AsmBackend.cpp - AArch64 Assembler Backend -----------------===//
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 
12 #include "Utils/AArch64BaseInfo.h"
13 #include "llvm/ADT/Triple.h"
15 #include "llvm/MC/MCAsmBackend.h"
16 #include "llvm/MC/MCAssembler.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCDirectives.h"
21 #include "llvm/MC/MCObjectWriter.h"
22 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/MC/MCSectionELF.h"
24 #include "llvm/MC/MCSectionMachO.h"
26 #include "llvm/MC/MCValue.h"
30 using namespace llvm;
31 
32 namespace {
33 
34 class AArch64AsmBackend : public MCAsmBackend {
35  static const unsigned PCRelFlagVal =
37 protected:
38  Triple TheTriple;
39 
40 public:
41  AArch64AsmBackend(const Target &T, const Triple &TT, bool IsLittleEndian)
42  : MCAsmBackend(IsLittleEndian ? support::little : support::big),
43  TheTriple(TT) {}
44 
45  unsigned getNumFixupKinds() const override {
47  }
48 
49  Optional<MCFixupKind> getFixupKind(StringRef Name) const override;
50 
51  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
52  const static MCFixupKindInfo Infos[AArch64::NumTargetFixupKinds] = {
53  // This table *must* be in the order that the fixup_* kinds are defined
54  // in AArch64FixupKinds.h.
55  //
56  // Name Offset (bits) Size (bits) Flags
57  {"fixup_aarch64_pcrel_adr_imm21", 0, 32, PCRelFlagVal},
58  {"fixup_aarch64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal},
59  {"fixup_aarch64_add_imm12", 10, 12, 0},
60  {"fixup_aarch64_ldst_imm12_scale1", 10, 12, 0},
61  {"fixup_aarch64_ldst_imm12_scale2", 10, 12, 0},
62  {"fixup_aarch64_ldst_imm12_scale4", 10, 12, 0},
63  {"fixup_aarch64_ldst_imm12_scale8", 10, 12, 0},
64  {"fixup_aarch64_ldst_imm12_scale16", 10, 12, 0},
65  {"fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal},
66  {"fixup_aarch64_movw", 5, 16, 0},
67  {"fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal},
68  {"fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal},
69  {"fixup_aarch64_pcrel_branch26", 0, 26, PCRelFlagVal},
70  {"fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal},
71  {"fixup_aarch64_tlsdesc_call", 0, 0, 0}};
72 
73  // Fixup kinds from .reloc directive are like R_AARCH64_NONE. They do not
74  // require any extra processing.
77 
80 
81  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
82  "Invalid kind!");
83  return Infos[Kind - FirstTargetFixupKind];
84  }
85 
86  void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
88  uint64_t Value, bool IsResolved,
89  const MCSubtargetInfo *STI) const override;
90 
91  bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
92  const MCRelaxableFragment *DF,
93  const MCAsmLayout &Layout) const override;
94  void relaxInstruction(MCInst &Inst,
95  const MCSubtargetInfo &STI) const override;
96  bool writeNopData(raw_ostream &OS, uint64_t Count) const override;
97 
98  void HandleAssemblerFlag(MCAssemblerFlag Flag) {}
99 
100  unsigned getPointerSize() const { return 8; }
101 
102  unsigned getFixupKindContainereSizeInBytes(unsigned Kind) const;
103 
104  bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
105  const MCValue &Target) override;
106 };
107 
108 } // end anonymous namespace
109 
110 /// The number of bytes the fixup may change.
111 static unsigned getFixupKindNumBytes(unsigned Kind) {
112  switch (Kind) {
113  default:
114  llvm_unreachable("Unknown fixup kind!");
115 
117  return 0;
118 
119  case FK_Data_1:
120  return 1;
121 
122  case FK_Data_2:
123  case FK_SecRel_2:
124  return 2;
125 
136  return 3;
137 
142  case FK_Data_4:
143  case FK_SecRel_4:
144  return 4;
145 
146  case FK_Data_8:
147  return 8;
148  }
149 }
150 
151 static unsigned AdrImmBits(unsigned Value) {
152  unsigned lo2 = Value & 0x3;
153  unsigned hi19 = (Value & 0x1ffffc) >> 2;
154  return (hi19 << 5) | (lo2 << 29);
155 }
156 
157 static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
158  uint64_t Value, MCContext &Ctx,
159  const Triple &TheTriple, bool IsResolved) {
160  int64_t SignedValue = static_cast<int64_t>(Value);
161  switch (Fixup.getTargetKind()) {
162  default:
163  llvm_unreachable("Unknown fixup kind!");
165  if (SignedValue > 2097151 || SignedValue < -2097152)
166  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
167  return AdrImmBits(Value & 0x1fffffULL);
169  assert(!IsResolved);
170  if (TheTriple.isOSBinFormatCOFF())
171  return AdrImmBits(Value & 0x1fffffULL);
172  return AdrImmBits((Value & 0x1fffff000ULL) >> 12);
175  // Signed 21-bit immediate
176  if (SignedValue > 2097151 || SignedValue < -2097152)
177  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
178  if (Value & 0x3)
179  Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
180  // Low two bits are not encoded.
181  return (Value >> 2) & 0x7ffff;
184  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
185  Value &= 0xfff;
186  // Unsigned 12-bit immediate
187  if (Value >= 0x1000)
188  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
189  return Value;
191  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
192  Value &= 0xfff;
193  // Unsigned 12-bit immediate which gets multiplied by 2
194  if (Value >= 0x2000)
195  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
196  if (Value & 0x1)
197  Ctx.reportError(Fixup.getLoc(), "fixup must be 2-byte aligned");
198  return Value >> 1;
200  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
201  Value &= 0xfff;
202  // Unsigned 12-bit immediate which gets multiplied by 4
203  if (Value >= 0x4000)
204  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
205  if (Value & 0x3)
206  Ctx.reportError(Fixup.getLoc(), "fixup must be 4-byte aligned");
207  return Value >> 2;
209  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
210  Value &= 0xfff;
211  // Unsigned 12-bit immediate which gets multiplied by 8
212  if (Value >= 0x8000)
213  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
214  if (Value & 0x7)
215  Ctx.reportError(Fixup.getLoc(), "fixup must be 8-byte aligned");
216  return Value >> 3;
218  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
219  Value &= 0xfff;
220  // Unsigned 12-bit immediate which gets multiplied by 16
221  if (Value >= 0x10000)
222  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
223  if (Value & 0xf)
224  Ctx.reportError(Fixup.getLoc(), "fixup must be 16-byte aligned");
225  return Value >> 4;
228  static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
231  if (!RefKind) {
232  // The fixup is an expression
233  if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
234  Ctx.reportError(Fixup.getLoc(),
235  "fixup value out of range [-0xFFFF, 0xFFFF]");
236 
237  // Invert the negative immediate because it will feed into a MOVN.
238  if (SignedValue < 0)
239  SignedValue = ~SignedValue;
240  Value = static_cast<uint64_t>(SignedValue);
241  } else
242  // VK_GOTTPREL, VK_TPREL, VK_DTPREL are movw fixups, but they can't
243  // ever be resolved in the assembler.
244  Ctx.reportError(Fixup.getLoc(),
245  "relocation for a thread-local variable points to an "
246  "absolute symbol");
247  return Value;
248  }
249 
250  if (!IsResolved) {
251  // FIXME: Figure out when this can actually happen, and verify our
252  // behavior.
253  Ctx.reportError(Fixup.getLoc(), "unresolved movw fixup not yet "
254  "implemented");
255  return Value;
256  }
257 
259  switch (AArch64MCExpr::getAddressFrag(RefKind)) {
261  break;
263  SignedValue = SignedValue >> 16;
264  break;
266  SignedValue = SignedValue >> 32;
267  break;
269  SignedValue = SignedValue >> 48;
270  break;
271  default:
272  llvm_unreachable("Variant kind doesn't correspond to fixup");
273  }
274 
275  } else {
276  switch (AArch64MCExpr::getAddressFrag(RefKind)) {
278  break;
280  Value = Value >> 16;
281  break;
283  Value = Value >> 32;
284  break;
286  Value = Value >> 48;
287  break;
288  default:
289  llvm_unreachable("Variant kind doesn't correspond to fixup");
290  }
291  }
292 
293  if (RefKind & AArch64MCExpr::VK_NC) {
294  Value &= 0xFFFF;
295  }
297  if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
298  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
299 
300  // Invert the negative immediate because it will feed into a MOVN.
301  if (SignedValue < 0)
302  SignedValue = ~SignedValue;
303  Value = static_cast<uint64_t>(SignedValue);
304  }
305  else if (Value > 0xFFFF) {
306  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
307  }
308  return Value;
309  }
311  // Signed 16-bit immediate
312  if (SignedValue > 32767 || SignedValue < -32768)
313  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
314  // Low two bits are not encoded (4-byte alignment assumed).
315  if (Value & 0x3)
316  Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
317  return (Value >> 2) & 0x3fff;
320  // Signed 28-bit immediate
321  if (SignedValue > 134217727 || SignedValue < -134217728)
322  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
323  // Low two bits are not encoded (4-byte alignment assumed).
324  if (Value & 0x3)
325  Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
326  return (Value >> 2) & 0x3ffffff;
327  case FK_Data_1:
328  case FK_Data_2:
329  case FK_Data_4:
330  case FK_Data_8:
331  case FK_SecRel_2:
332  case FK_SecRel_4:
333  return Value;
334  }
335 }
336 
337 Optional<MCFixupKind> AArch64AsmBackend::getFixupKind(StringRef Name) const {
338  if (!TheTriple.isOSBinFormatELF())
339  return None;
340 
342 #define ELF_RELOC(X, Y) .Case(#X, Y)
343 #include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
344 #undef ELF_RELOC
345  .Case("BFD_RELOC_NONE", ELF::R_AARCH64_NONE)
346  .Case("BFD_RELOC_16", ELF::R_AARCH64_ABS16)
347  .Case("BFD_RELOC_32", ELF::R_AARCH64_ABS32)
348  .Case("BFD_RELOC_64", ELF::R_AARCH64_ABS64)
349  .Default(-1u);
350  if (Type == -1u)
351  return None;
352  return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
353 }
354 
355 /// getFixupKindContainereSizeInBytes - The number of bytes of the
356 /// container involved in big endian or 0 if the item is little endian
357 unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(unsigned Kind) const {
358  if (Endian == support::little)
359  return 0;
360 
361  switch (Kind) {
362  default:
363  llvm_unreachable("Unknown fixup kind!");
364 
365  case FK_Data_1:
366  return 1;
367  case FK_Data_2:
368  return 2;
369  case FK_Data_4:
370  return 4;
371  case FK_Data_8:
372  return 8;
373 
389  // Instructions are always little endian
390  return 0;
391  }
392 }
393 
394 void AArch64AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
395  const MCValue &Target,
396  MutableArrayRef<char> Data, uint64_t Value,
397  bool IsResolved,
398  const MCSubtargetInfo *STI) const {
399  if (!Value)
400  return; // Doesn't change encoding.
401  unsigned Kind = Fixup.getKind();
403  return;
404  unsigned NumBytes = getFixupKindNumBytes(Kind);
405  MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
406  MCContext &Ctx = Asm.getContext();
407  int64_t SignedValue = static_cast<int64_t>(Value);
408  // Apply any target-specific value adjustments.
409  Value = adjustFixupValue(Fixup, Target, Value, Ctx, TheTriple, IsResolved);
410 
411  // Shift the value into position.
412  Value <<= Info.TargetOffset;
413 
414  unsigned Offset = Fixup.getOffset();
415  assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
416 
417  // Used to point to big endian bytes.
418  unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(Fixup.getKind());
419 
420  // For each byte of the fragment that the fixup touches, mask in the
421  // bits from the fixup value.
422  if (FulleSizeInBytes == 0) {
423  // Handle as little-endian
424  for (unsigned i = 0; i != NumBytes; ++i) {
425  Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
426  }
427  } else {
428  // Handle as big-endian
429  assert((Offset + FulleSizeInBytes) <= Data.size() && "Invalid fixup size!");
430  assert(NumBytes <= FulleSizeInBytes && "Invalid fixup size!");
431  for (unsigned i = 0; i != NumBytes; ++i) {
432  unsigned Idx = FulleSizeInBytes - 1 - i;
433  Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
434  }
435  }
436 
437  // FIXME: getFixupKindInfo() and getFixupKindNumBytes() could be fixed to
438  // handle this more cleanly. This may affect the output of -show-mc-encoding.
440  static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
442  (!RefKind && Fixup.getTargetKind() == AArch64::fixup_aarch64_movw)) {
443  // If the immediate is negative, generate MOVN else MOVZ.
444  // (Bit 30 = 0) ==> MOVN, (Bit 30 = 1) ==> MOVZ.
445  if (SignedValue < 0)
446  Data[Offset + 3] &= ~(1 << 6);
447  else
448  Data[Offset + 3] |= (1 << 6);
449  }
450 }
451 
452 bool AArch64AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
453  uint64_t Value,
454  const MCRelaxableFragment *DF,
455  const MCAsmLayout &Layout) const {
456  // FIXME: This isn't correct for AArch64. Just moving the "generic" logic
457  // into the targets for now.
458  //
459  // Relax if the value is too big for a (signed) i8.
460  return int64_t(Value) != int64_t(int8_t(Value));
461 }
462 
463 void AArch64AsmBackend::relaxInstruction(MCInst &Inst,
464  const MCSubtargetInfo &STI) const {
465  llvm_unreachable("AArch64AsmBackend::relaxInstruction() unimplemented");
466 }
467 
468 bool AArch64AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
469  // If the count is not 4-byte aligned, we must be writing data into the text
470  // section (otherwise we have unaligned instructions, and thus have far
471  // bigger problems), so just write zeros instead.
472  OS.write_zeros(Count % 4);
473 
474  // We are properly aligned, so write NOPs as requested.
475  Count /= 4;
476  for (uint64_t i = 0; i != Count; ++i)
477  support::endian::write<uint32_t>(OS, 0xd503201f, Endian);
478  return true;
479 }
480 
481 bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
482  const MCFixup &Fixup,
483  const MCValue &Target) {
484  unsigned Kind = Fixup.getKind();
486  return true;
487 
488  // The ADRP instruction adds some multiple of 0x1000 to the current PC &
489  // ~0xfff. This means that the required offset to reach a symbol can vary by
490  // up to one step depending on where the ADRP is in memory. For example:
491  //
492  // ADRP x0, there
493  // there:
494  //
495  // If the ADRP occurs at address 0xffc then "there" will be at 0x1000 and
496  // we'll need that as an offset. At any other address "there" will be in the
497  // same page as the ADRP and the instruction should encode 0x0. Assuming the
498  // section isn't 0x1000-aligned, we therefore need to delegate this decision
499  // to the linker -- a relocation!
501  return true;
502 
504  static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
506  // LDR GOT relocations need a relocation
508  SymLoc == AArch64MCExpr::VK_GOT)
509  return true;
510  return false;
511 }
512 
513 namespace {
514 
515 namespace CU {
516 
517 /// Compact unwind encoding values.
519  /// A "frameless" leaf function, where no non-volatile registers are
520  /// saved. The return remains in LR throughout the function.
521  UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
522 
523  /// No compact unwind encoding available. Instead the low 23-bits of
524  /// the compact unwind encoding is the offset of the DWARF FDE in the
525  /// __eh_frame section. This mode is never used in object files. It is only
526  /// generated by the linker in final linked images, which have only DWARF info
527  /// for a function.
528  UNWIND_ARM64_MODE_DWARF = 0x03000000,
529 
530  /// This is a standard arm64 prologue where FP/LR are immediately
531  /// pushed on the stack, then SP is copied to FP. If there are any
532  /// non-volatile register saved, they are copied into the stack fame in pairs
533  /// in a contiguous ranger right below the saved FP/LR pair. Any subset of the
534  /// five X pairs and four D pairs can be saved, but the memory layout must be
535  /// in register number order.
536  UNWIND_ARM64_MODE_FRAME = 0x04000000,
537 
538  /// Frame register pair encodings.
539  UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
540  UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
541  UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
542  UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
543  UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
544  UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
545  UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
546  UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
547  UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
548 };
549 
550 } // end CU namespace
551 
552 // FIXME: This should be in a separate file.
553 class DarwinAArch64AsmBackend : public AArch64AsmBackend {
554  const MCRegisterInfo &MRI;
555 
556  /// Encode compact unwind stack adjustment for frameless functions.
557  /// See UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK in compact_unwind_encoding.h.
558  /// The stack size always needs to be 16 byte aligned.
559  uint32_t encodeStackAdjustment(uint32_t StackSize) const {
560  return (StackSize / 16) << 12;
561  }
562 
563 public:
564  DarwinAArch64AsmBackend(const Target &T, const Triple &TT,
565  const MCRegisterInfo &MRI)
566  : AArch64AsmBackend(T, TT, /*IsLittleEndian*/ true), MRI(MRI) {}
567 
568  std::unique_ptr<MCObjectTargetWriter>
569  createObjectTargetWriter() const override {
571  uint32_t CPUSubType = cantFail(MachO::getCPUSubType(TheTriple));
572  return createAArch64MachObjectWriter(CPUType, CPUSubType,
573  TheTriple.isArch32Bit());
574  }
575 
576  /// Generate the compact unwind encoding from the CFI directives.
577  uint32_t generateCompactUnwindEncoding(
578  ArrayRef<MCCFIInstruction> Instrs) const override {
579  if (Instrs.empty())
580  return CU::UNWIND_ARM64_MODE_FRAMELESS;
581 
582  bool HasFP = false;
583  unsigned StackSize = 0;
584 
585  uint32_t CompactUnwindEncoding = 0;
586  for (size_t i = 0, e = Instrs.size(); i != e; ++i) {
587  const MCCFIInstruction &Inst = Instrs[i];
588 
589  switch (Inst.getOperation()) {
590  default:
591  // Cannot handle this directive: bail out.
592  return CU::UNWIND_ARM64_MODE_DWARF;
594  // Defines a frame pointer.
595  unsigned XReg =
596  getXRegFromWReg(*MRI.getLLVMRegNum(Inst.getRegister(), true));
597 
598  // Other CFA registers than FP are not supported by compact unwind.
599  // Fallback on DWARF.
600  // FIXME: When opt-remarks are supported in MC, add a remark to notify
601  // the user.
602  if (XReg != AArch64::FP)
603  return CU::UNWIND_ARM64_MODE_DWARF;
604 
605  assert(XReg == AArch64::FP && "Invalid frame pointer!");
606  assert(i + 2 < e && "Insufficient CFI instructions to define a frame!");
607 
608  const MCCFIInstruction &LRPush = Instrs[++i];
610  "Link register not pushed!");
611  const MCCFIInstruction &FPPush = Instrs[++i];
613  "Frame pointer not pushed!");
614 
615  unsigned LRReg = *MRI.getLLVMRegNum(LRPush.getRegister(), true);
616  unsigned FPReg = *MRI.getLLVMRegNum(FPPush.getRegister(), true);
617 
618  LRReg = getXRegFromWReg(LRReg);
619  FPReg = getXRegFromWReg(FPReg);
620 
621  assert(LRReg == AArch64::LR && FPReg == AArch64::FP &&
622  "Pushing invalid registers for frame!");
623 
624  // Indicate that the function has a frame.
625  CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
626  HasFP = true;
627  break;
628  }
630  assert(StackSize == 0 && "We already have the CFA offset!");
631  StackSize = std::abs(Inst.getOffset());
632  break;
633  }
635  // Registers are saved in pairs. We expect there to be two consecutive
636  // `.cfi_offset' instructions with the appropriate registers specified.
637  unsigned Reg1 = *MRI.getLLVMRegNum(Inst.getRegister(), true);
638  if (i + 1 == e)
639  return CU::UNWIND_ARM64_MODE_DWARF;
640 
641  const MCCFIInstruction &Inst2 = Instrs[++i];
643  return CU::UNWIND_ARM64_MODE_DWARF;
644  unsigned Reg2 = *MRI.getLLVMRegNum(Inst2.getRegister(), true);
645 
646  // N.B. The encodings must be in register number order, and the X
647  // registers before the D registers.
648 
649  // X19/X20 pair = 0x00000001,
650  // X21/X22 pair = 0x00000002,
651  // X23/X24 pair = 0x00000004,
652  // X25/X26 pair = 0x00000008,
653  // X27/X28 pair = 0x00000010
654  Reg1 = getXRegFromWReg(Reg1);
655  Reg2 = getXRegFromWReg(Reg2);
656 
657  if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
658  (CompactUnwindEncoding & 0xF1E) == 0)
659  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
660  else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
661  (CompactUnwindEncoding & 0xF1C) == 0)
662  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
663  else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
664  (CompactUnwindEncoding & 0xF18) == 0)
665  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
666  else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
667  (CompactUnwindEncoding & 0xF10) == 0)
668  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
669  else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
670  (CompactUnwindEncoding & 0xF00) == 0)
671  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
672  else {
673  Reg1 = getDRegFromBReg(Reg1);
674  Reg2 = getDRegFromBReg(Reg2);
675 
676  // D8/D9 pair = 0x00000100,
677  // D10/D11 pair = 0x00000200,
678  // D12/D13 pair = 0x00000400,
679  // D14/D15 pair = 0x00000800
680  if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
681  (CompactUnwindEncoding & 0xE00) == 0)
682  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
683  else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
684  (CompactUnwindEncoding & 0xC00) == 0)
685  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
686  else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
687  (CompactUnwindEncoding & 0x800) == 0)
688  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
689  else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
690  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
691  else
692  // A pair was pushed which we cannot handle.
693  return CU::UNWIND_ARM64_MODE_DWARF;
694  }
695 
696  break;
697  }
698  }
699  }
700 
701  if (!HasFP) {
702  // With compact unwind info we can only represent stack adjustments of up
703  // to 65520 bytes.
704  if (StackSize > 65520)
705  return CU::UNWIND_ARM64_MODE_DWARF;
706 
707  CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
708  CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
709  }
710 
711  return CompactUnwindEncoding;
712  }
713 };
714 
715 } // end anonymous namespace
716 
717 namespace {
718 
719 class ELFAArch64AsmBackend : public AArch64AsmBackend {
720 public:
721  uint8_t OSABI;
722  bool IsILP32;
723 
724  ELFAArch64AsmBackend(const Target &T, const Triple &TT, uint8_t OSABI,
725  bool IsLittleEndian, bool IsILP32)
726  : AArch64AsmBackend(T, TT, IsLittleEndian), OSABI(OSABI),
727  IsILP32(IsILP32) {}
728 
729  std::unique_ptr<MCObjectTargetWriter>
730  createObjectTargetWriter() const override {
731  return createAArch64ELFObjectWriter(OSABI, IsILP32);
732  }
733 };
734 
735 }
736 
737 namespace {
738 class COFFAArch64AsmBackend : public AArch64AsmBackend {
739 public:
740  COFFAArch64AsmBackend(const Target &T, const Triple &TheTriple)
741  : AArch64AsmBackend(T, TheTriple, /*IsLittleEndian*/ true) {}
742 
743  std::unique_ptr<MCObjectTargetWriter>
744  createObjectTargetWriter() const override {
746  }
747 };
748 }
749 
751  const MCSubtargetInfo &STI,
752  const MCRegisterInfo &MRI,
753  const MCTargetOptions &Options) {
754  const Triple &TheTriple = STI.getTargetTriple();
755  if (TheTriple.isOSBinFormatMachO()) {
756  return new DarwinAArch64AsmBackend(T, TheTriple, MRI);
757  }
758 
759  if (TheTriple.isOSBinFormatCOFF())
760  return new COFFAArch64AsmBackend(T, TheTriple);
761 
762  assert(TheTriple.isOSBinFormatELF() && "Invalid target");
763 
764  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
765  bool IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
766  return new ELFAArch64AsmBackend(T, TheTriple, OSABI, /*IsLittleEndian=*/true,
767  IsILP32);
768 }
769 
771  const MCSubtargetInfo &STI,
772  const MCRegisterInfo &MRI,
773  const MCTargetOptions &Options) {
774  const Triple &TheTriple = STI.getTargetTriple();
775  assert(TheTriple.isOSBinFormatELF() &&
776  "Big endian is only supported for ELF targets!");
777  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
778  bool IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
779  return new ELFAArch64AsmBackend(T, TheTriple, OSABI, /*IsLittleEndian=*/false,
780  IsILP32);
781 }
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:67
i
i
Definition: README.txt:29
llvm::EngineKind::Kind
Kind
Definition: ExecutionEngine.h:524
getPointerSize
static uint64_t getPointerSize(const Value *V, const DataLayout &DL, const TargetLibraryInfo &TLI, const Function *F)
Definition: DeadStoreElimination.cpp:308
llvm
Definition: AllocatorList.h:23
llvm::MCRelaxableFragment
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
Definition: MCFragment.h:271
llvm::Triple::GNUILP32
@ GNUILP32
Definition: Triple.h:213
llvm::ARM::PredBlockMask::TT
@ TT
llvm::MCAsmBackend::getFixupKindInfo
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
Definition: MCAsmBackend.cpp:74
llvm::AArch64MCExpr::VK_ABS
@ VK_ABS
Definition: AArch64MCExpr.h:28
MCTargetOptions.h
llvm::Triple::isOSBinFormatCOFF
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Definition: Triple.h:637
llvm::raw_ostream::write_zeros
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
Definition: raw_ostream.cpp:502
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:71
llvm::AArch64::fixup_aarch64_pcrel_branch26
@ fixup_aarch64_pcrel_branch26
Definition: AArch64FixupKinds.h:52
llvm::AArch64::fixup_aarch64_add_imm12
@ fixup_aarch64_add_imm12
Definition: AArch64FixupKinds.h:26
llvm::MCCFIInstruction::OpOffset
@ OpOffset
Definition: MCDwarf.h:447
llvm::StringSwitch::Default
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:181
MCDirectives.h
llvm::AArch64::fixup_aarch64_ldr_pcrel_imm19
@ fixup_aarch64_ldr_pcrel_imm19
Definition: AArch64FixupKinds.h:38
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:124
MCSectionELF.h
llvm::FirstTargetFixupKind
@ FirstTargetFixupKind
Definition: MCFixup.h:55
llvm::AArch64::fixup_aarch64_ldst_imm12_scale2
@ fixup_aarch64_ldst_imm12_scale2
Definition: AArch64FixupKinds.h:30
AArch64MCExpr.h
ErrorHandling.h
llvm::AArch64MCExpr::VK_NC
@ VK_NC
Definition: AArch64MCExpr.h:57
AArch64BaseInfo.h
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
MCAssembler.h
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:46
llvm::MachO::CPUType
CPUType
Definition: MachO.h:1418
llvm::Optional
Definition: APInt.h:34
MCFixupKindInfo.h
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::AArch64::NumTargetFixupKinds
@ NumTargetFixupKinds
Definition: AArch64FixupKinds.h:63
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:183
llvm::MCAssemblerFlag
MCAssemblerFlag
Definition: MCDirectives.h:50
llvm::createAArch64WinCOFFObjectWriter
std::unique_ptr< MCObjectTargetWriter > createAArch64WinCOFFObjectWriter()
Definition: AArch64WinCOFFObjectWriter.cpp:158
llvm::MCFixupKindInfo::FKF_IsAlignedDownTo32Bits
@ FKF_IsAlignedDownTo32Bits
Should this fixup kind force a 4-byte aligned effective PC value?
Definition: MCFixupKindInfo.h:22
llvm::Data
@ Data
Definition: SIMachineScheduler.h:56
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:158
llvm::MachO::getCPUType
Expected< uint32_t > getCPUType(const Triple &T)
Definition: MachO.cpp:77
llvm::MCCFIInstruction::OpDefCfa
@ OpDefCfa
Definition: MCDwarf.h:450
llvm::FirstLiteralRelocationKind
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
Definition: MCFixup.h:60
x3
In x86 we generate this spiffy xmm0 xmm0 ret in x86 we generate this which could be xmm1 movss xmm1 xmm0 ret In sse4 we could use insertps to make both better Here s another testcase that could use x3
Definition: README-SSE.txt:547
llvm::FK_Data_4
@ FK_Data_4
A four-byte fixup.
Definition: MCFixup.h:25
llvm::Triple::isOSBinFormatELF
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:632
llvm::createAArch64ELFObjectWriter
std::unique_ptr< MCObjectTargetWriter > createAArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32)
Definition: AArch64ELFObjectWriter.cpp:459
llvm::createAArch64MachObjectWriter
std::unique_ptr< MCObjectTargetWriter > createAArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype, bool IsILP32)
Definition: AArch64MachObjectWriter.cpp:411
llvm::MCAsmBackend
Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:36
CompactUnwindEncodings
CompactUnwindEncodings
Compact unwind encoding values.
Definition: AArch64AsmBackend.cpp:518
MCAsmBackend.h
llvm::MutableArrayRef
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:305
llvm::FK_SecRel_4
@ FK_SecRel_4
A four-byte section relative fixup.
Definition: MCFixup.h:42
llvm::support::little
@ little
Definition: Endian.h:27
llvm::MCSubtargetInfo::getTargetTriple
const Triple & getTargetTriple() const
Definition: MCSubtargetInfo.h:107
MCContext.h
MCSectionMachO.h
llvm::MCCFIInstruction::getOffset
int getOffset() const
Definition: MCDwarf.h:602
llvm::FK_SecRel_2
@ FK_SecRel_2
A two-byte section relative fixup.
Definition: MCFixup.h:41
llvm::AArch64MCExpr::VK_G1
@ VK_G1
Definition: AArch64MCExpr.h:46
llvm::codeview::ProcSymFlags::HasFP
@ HasFP
llvm::Triple::isOSBinFormatMachO
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:645
AArch64FixupKinds.h
llvm::AArch64::fixup_aarch64_pcrel_branch19
@ fixup_aarch64_pcrel_branch19
Definition: AArch64FixupKinds.h:49
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:147
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:50
llvm::MCCFIInstruction::getOperation
OpType getOperation() const
Definition: MCDwarf.h:586
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:26
llvm::MachO::getCPUSubType
Expected< uint32_t > getCPUSubType(const Triple &T)
Definition: MachO.cpp:95
llvm::MCCFIInstruction::getRegister
unsigned getRegister() const
Definition: MCDwarf.h:589
llvm::None
const NoneType None
Definition: None.h:23
llvm::MCCFIInstruction
Definition: MCDwarf.h:441
DF
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
llvm::AArch64::fixup_aarch64_ldst_imm12_scale8
@ fixup_aarch64_ldst_imm12_scale8
Definition: AArch64FixupKinds.h:32
getFixupKindNumBytes
static unsigned getFixupKindNumBytes(unsigned Kind)
The number of bytes the fixup may change.
Definition: AArch64AsmBackend.cpp:111
llvm::MCAssembler
Definition: MCAssembler.h:60
llvm::MCCFIInstruction::OpDefCfaOffset
@ OpDefCfaOffset
Definition: MCDwarf.h:449
AdrImmBits
static unsigned AdrImmBits(unsigned Value)
Definition: AArch64AsmBackend.cpp:151
llvm::Triple::getOS
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:316
MCELFObjectWriter.h
llvm::Triple::isArch32Bit
bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition: Triple.cpp:1340
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
llvm::MCFixupKindInfo::FKF_IsPCRel
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
Definition: MCFixupKindInfo.h:19
adjustFixupValue
static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, uint64_t Value, MCContext &Ctx, const Triple &TheTriple, bool IsResolved)
Definition: AArch64AsmBackend.cpp:157
MCRegisterInfo.h
llvm::AArch64MCExpr::getAddressFrag
static VariantKind getAddressFrag(VariantKind Kind)
Definition: AArch64MCExpr.h:147
llvm::AArch64::fixup_aarch64_ldst_imm12_scale4
@ fixup_aarch64_ldst_imm12_scale4
Definition: AArch64FixupKinds.h:31
llvm::AArch64::fixup_aarch64_pcrel_call26
@ fixup_aarch64_pcrel_call26
Definition: AArch64FixupKinds.h:56
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MCFixupKindInfo
Target independent information on a fixup kind.
Definition: MCFixupKindInfo.h:15
llvm::MCContext::reportError
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:917
llvm::createAArch64beAsmBackend
MCAsmBackend * createAArch64beAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Definition: AArch64AsmBackend.cpp:770
llvm::AArch64::fixup_aarch64_tlsdesc_call
@ fixup_aarch64_tlsdesc_call
Definition: AArch64FixupKinds.h:59
llvm::FK_Data_1
@ FK_Data_1
A one-byte fixup.
Definition: MCFixup.h:23
llvm::MCTargetOptions
Definition: MCTargetOptions.h:36
llvm::FK_NONE
@ FK_NONE
A no-op fixup.
Definition: MCFixup.h:22
Triple.h
llvm::AArch64::fixup_aarch64_ldst_imm12_scale1
@ fixup_aarch64_ldst_imm12_scale1
Definition: AArch64FixupKinds.h:29
llvm::MCELFObjectTargetWriter::getOSABI
uint8_t getOSABI() const
Definition: MCELFObjectWriter.h:99
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:33
Fixup
PowerPC TLS Dynamic Call Fixup
Definition: PPCTLSDynamicCall.cpp:235
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:708
uint32_t
llvm::MCRegisterInfo
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Definition: MCRegisterInfo.h:135
llvm::AArch64::fixup_aarch64_pcrel_branch14
@ fixup_aarch64_pcrel_branch14
Definition: AArch64FixupKinds.h:44
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::getXRegFromWReg
static unsigned getXRegFromWReg(unsigned Reg)
Definition: AArch64BaseInfo.h:69
MCObjectWriter.h
llvm::AArch64::fixup_aarch64_movw
@ fixup_aarch64_movw
Definition: AArch64FixupKinds.h:41
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
EndianStream.h
llvm::MCAsmLayout
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
llvm::AArch64::fixup_aarch64_ldst_imm12_scale16
@ fixup_aarch64_ldst_imm12_scale16
Definition: AArch64FixupKinds.h:33
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::AArch64MCExpr::VK_G3
@ VK_G3
Definition: AArch64MCExpr.h:48
AArch64MCTargetDesc.h
MCValue.h
llvm::MCFixupKind
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
llvm::FK_Data_8
@ FK_Data_8
A eight-byte fixup.
Definition: MCFixup.h:26
llvm::AArch64MCExpr::VariantKind
VariantKind
Definition: AArch64MCExpr.h:24
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
support
Reimplement select in terms of SEL *We would really like to support but we need to prove that the add doesn t need to overflow between the two bit chunks *Implement pre post increment support(e.g. PR935) *Implement smarter const ant generation for binops with large immediates. A few ARMv6T2 ops should be pattern matched
Definition: README.txt:10
llvm::AArch64::fixup_aarch64_pcrel_adrp_imm21
@ fixup_aarch64_pcrel_adrp_imm21
Definition: AArch64FixupKinds.h:22
llvm::Triple::getEnvironment
EnvironmentType getEnvironment() const
getEnvironment - Get the parsed environment type of this triple.
Definition: Triple.h:325
llvm::getDRegFromBReg
static unsigned getDRegFromBReg(unsigned Reg)
Definition: AArch64BaseInfo.h:149
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
llvm::HexStyle::Asm
@ Asm
0ffh
Definition: MCInstPrinter.h:34
llvm::MCValue
This represents an "assembler immediate".
Definition: MCValue.h:37
MachO.h
llvm::AArch64MCExpr::getSymbolLoc
static VariantKind getSymbolLoc(VariantKind Kind)
Definition: AArch64MCExpr.h:143
llvm::FK_Data_2
@ FK_Data_2
A two-byte fixup.
Definition: MCFixup.h:24
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1789
TargetRegistry.h
llvm::abs
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition: APFloat.h:1272
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
CU
Definition: AArch64AsmBackend.cpp:515
llvm::MCFixup
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:81
llvm::AArch64MCExpr::VK_G2
@ VK_G2
Definition: AArch64MCExpr.h:47
llvm::createAArch64leAsmBackend
MCAsmBackend * createAArch64leAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Definition: AArch64AsmBackend.cpp:750
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::AArch64MCExpr::VK_G0
@ VK_G0
Definition: AArch64MCExpr.h:45
llvm::AArch64MCExpr::VK_SABS
@ VK_SABS
Definition: AArch64MCExpr.h:29
llvm::support::big
@ big
Definition: Endian.h:27
llvm::AArch64::fixup_aarch64_pcrel_adr_imm21
@ fixup_aarch64_pcrel_adr_imm21
Definition: AArch64FixupKinds.h:19
llvm::AArch64MCExpr::VK_GOT
@ VK_GOT
Definition: AArch64MCExpr.h:31