LLVM  14.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"
27 #include "llvm/MC/TargetRegistry.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 
72  // Fixup kinds from .reloc directive are like R_AARCH64_NONE. They do not
73  // require any extra processing.
76 
79 
80  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
81  "Invalid kind!");
82  return Infos[Kind - FirstTargetFixupKind];
83  }
84 
85  void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
87  uint64_t Value, bool IsResolved,
88  const MCSubtargetInfo *STI) const override;
89 
90  bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
91  const MCRelaxableFragment *DF,
92  const MCAsmLayout &Layout) const override;
93  void relaxInstruction(MCInst &Inst,
94  const MCSubtargetInfo &STI) const override;
95  bool writeNopData(raw_ostream &OS, uint64_t Count,
96  const MCSubtargetInfo *STI) const override;
97 
98  unsigned getFixupKindContainereSizeInBytes(unsigned Kind) const;
99 
100  bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
101  const MCValue &Target) override;
102 };
103 
104 } // end anonymous namespace
105 
106 /// The number of bytes the fixup may change.
107 static unsigned getFixupKindNumBytes(unsigned Kind) {
108  switch (Kind) {
109  default:
110  llvm_unreachable("Unknown fixup kind!");
111 
112  case FK_Data_1:
113  return 1;
114 
115  case FK_Data_2:
116  case FK_SecRel_2:
117  return 2;
118 
129  return 3;
130 
135  case FK_Data_4:
136  case FK_SecRel_4:
137  return 4;
138 
139  case FK_Data_8:
140  return 8;
141  }
142 }
143 
144 static unsigned AdrImmBits(unsigned Value) {
145  unsigned lo2 = Value & 0x3;
146  unsigned hi19 = (Value & 0x1ffffc) >> 2;
147  return (hi19 << 5) | (lo2 << 29);
148 }
149 
150 static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target,
151  uint64_t Value, MCContext &Ctx,
152  const Triple &TheTriple, bool IsResolved) {
153  int64_t SignedValue = static_cast<int64_t>(Value);
154  switch (Fixup.getTargetKind()) {
155  default:
156  llvm_unreachable("Unknown fixup kind!");
158  if (SignedValue > 2097151 || SignedValue < -2097152)
159  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
160  return AdrImmBits(Value & 0x1fffffULL);
162  assert(!IsResolved);
163  if (TheTriple.isOSBinFormatCOFF())
164  return AdrImmBits(Value & 0x1fffffULL);
165  return AdrImmBits((Value & 0x1fffff000ULL) >> 12);
168  // Signed 21-bit immediate
169  if (SignedValue > 2097151 || SignedValue < -2097152)
170  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
171  if (Value & 0x3)
172  Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
173  // Low two bits are not encoded.
174  return (Value >> 2) & 0x7ffff;
177  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
178  Value &= 0xfff;
179  // Unsigned 12-bit immediate
180  if (Value >= 0x1000)
181  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
182  return Value;
184  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
185  Value &= 0xfff;
186  // Unsigned 12-bit immediate which gets multiplied by 2
187  if (Value >= 0x2000)
188  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
189  if (Value & 0x1)
190  Ctx.reportError(Fixup.getLoc(), "fixup must be 2-byte aligned");
191  return Value >> 1;
193  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
194  Value &= 0xfff;
195  // Unsigned 12-bit immediate which gets multiplied by 4
196  if (Value >= 0x4000)
197  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
198  if (Value & 0x3)
199  Ctx.reportError(Fixup.getLoc(), "fixup must be 4-byte aligned");
200  return Value >> 2;
202  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
203  Value &= 0xfff;
204  // Unsigned 12-bit immediate which gets multiplied by 8
205  if (Value >= 0x8000)
206  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
207  if (Value & 0x7)
208  Ctx.reportError(Fixup.getLoc(), "fixup must be 8-byte aligned");
209  return Value >> 3;
211  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
212  Value &= 0xfff;
213  // Unsigned 12-bit immediate which gets multiplied by 16
214  if (Value >= 0x10000)
215  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
216  if (Value & 0xf)
217  Ctx.reportError(Fixup.getLoc(), "fixup must be 16-byte aligned");
218  return Value >> 4;
221  static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
224  if (!RefKind) {
225  // The fixup is an expression
226  if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
227  Ctx.reportError(Fixup.getLoc(),
228  "fixup value out of range [-0xFFFF, 0xFFFF]");
229 
230  // Invert the negative immediate because it will feed into a MOVN.
231  if (SignedValue < 0)
232  SignedValue = ~SignedValue;
233  Value = static_cast<uint64_t>(SignedValue);
234  } else
235  // VK_GOTTPREL, VK_TPREL, VK_DTPREL are movw fixups, but they can't
236  // ever be resolved in the assembler.
237  Ctx.reportError(Fixup.getLoc(),
238  "relocation for a thread-local variable points to an "
239  "absolute symbol");
240  return Value;
241  }
242 
243  if (!IsResolved) {
244  // FIXME: Figure out when this can actually happen, and verify our
245  // behavior.
246  Ctx.reportError(Fixup.getLoc(), "unresolved movw fixup not yet "
247  "implemented");
248  return Value;
249  }
250 
252  switch (AArch64MCExpr::getAddressFrag(RefKind)) {
254  break;
256  SignedValue = SignedValue >> 16;
257  break;
259  SignedValue = SignedValue >> 32;
260  break;
262  SignedValue = SignedValue >> 48;
263  break;
264  default:
265  llvm_unreachable("Variant kind doesn't correspond to fixup");
266  }
267 
268  } else {
269  switch (AArch64MCExpr::getAddressFrag(RefKind)) {
271  break;
273  Value = Value >> 16;
274  break;
276  Value = Value >> 32;
277  break;
279  Value = Value >> 48;
280  break;
281  default:
282  llvm_unreachable("Variant kind doesn't correspond to fixup");
283  }
284  }
285 
286  if (RefKind & AArch64MCExpr::VK_NC) {
287  Value &= 0xFFFF;
288  }
290  if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
291  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
292 
293  // Invert the negative immediate because it will feed into a MOVN.
294  if (SignedValue < 0)
295  SignedValue = ~SignedValue;
296  Value = static_cast<uint64_t>(SignedValue);
297  }
298  else if (Value > 0xFFFF) {
299  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
300  }
301  return Value;
302  }
304  // Signed 16-bit immediate
305  if (SignedValue > 32767 || SignedValue < -32768)
306  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
307  // Low two bits are not encoded (4-byte alignment assumed).
308  if (Value & 0x3)
309  Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
310  return (Value >> 2) & 0x3fff;
313  // Signed 28-bit immediate
314  if (SignedValue > 134217727 || SignedValue < -134217728)
315  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
316  // Low two bits are not encoded (4-byte alignment assumed).
317  if (Value & 0x3)
318  Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
319  return (Value >> 2) & 0x3ffffff;
320  case FK_Data_1:
321  case FK_Data_2:
322  case FK_Data_4:
323  case FK_Data_8:
324  case FK_SecRel_2:
325  case FK_SecRel_4:
326  return Value;
327  }
328 }
329 
330 Optional<MCFixupKind> AArch64AsmBackend::getFixupKind(StringRef Name) const {
331  if (!TheTriple.isOSBinFormatELF())
332  return None;
333 
335 #define ELF_RELOC(X, Y) .Case(#X, Y)
336 #include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
337 #undef ELF_RELOC
338  .Case("BFD_RELOC_NONE", ELF::R_AARCH64_NONE)
339  .Case("BFD_RELOC_16", ELF::R_AARCH64_ABS16)
340  .Case("BFD_RELOC_32", ELF::R_AARCH64_ABS32)
341  .Case("BFD_RELOC_64", ELF::R_AARCH64_ABS64)
342  .Default(-1u);
343  if (Type == -1u)
344  return None;
345  return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
346 }
347 
348 /// getFixupKindContainereSizeInBytes - The number of bytes of the
349 /// container involved in big endian or 0 if the item is little endian
350 unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(unsigned Kind) const {
351  if (Endian == support::little)
352  return 0;
353 
354  switch (Kind) {
355  default:
356  llvm_unreachable("Unknown fixup kind!");
357 
358  case FK_Data_1:
359  return 1;
360  case FK_Data_2:
361  return 2;
362  case FK_Data_4:
363  return 4;
364  case FK_Data_8:
365  return 8;
366 
381  // Instructions are always little endian
382  return 0;
383  }
384 }
385 
386 void AArch64AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
387  const MCValue &Target,
389  bool IsResolved,
390  const MCSubtargetInfo *STI) const {
391  if (!Value)
392  return; // Doesn't change encoding.
393  unsigned Kind = Fixup.getKind();
395  return;
396  unsigned NumBytes = getFixupKindNumBytes(Kind);
397  MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
398  MCContext &Ctx = Asm.getContext();
399  int64_t SignedValue = static_cast<int64_t>(Value);
400  // Apply any target-specific value adjustments.
401  Value = adjustFixupValue(Fixup, Target, Value, Ctx, TheTriple, IsResolved);
402 
403  // Shift the value into position.
404  Value <<= Info.TargetOffset;
405 
406  unsigned Offset = Fixup.getOffset();
407  assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
408 
409  // Used to point to big endian bytes.
410  unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(Fixup.getKind());
411 
412  // For each byte of the fragment that the fixup touches, mask in the
413  // bits from the fixup value.
414  if (FulleSizeInBytes == 0) {
415  // Handle as little-endian
416  for (unsigned i = 0; i != NumBytes; ++i) {
417  Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
418  }
419  } else {
420  // Handle as big-endian
421  assert((Offset + FulleSizeInBytes) <= Data.size() && "Invalid fixup size!");
422  assert(NumBytes <= FulleSizeInBytes && "Invalid fixup size!");
423  for (unsigned i = 0; i != NumBytes; ++i) {
424  unsigned Idx = FulleSizeInBytes - 1 - i;
425  Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
426  }
427  }
428 
429  // FIXME: getFixupKindInfo() and getFixupKindNumBytes() could be fixed to
430  // handle this more cleanly. This may affect the output of -show-mc-encoding.
432  static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
434  (!RefKind && Fixup.getTargetKind() == AArch64::fixup_aarch64_movw)) {
435  // If the immediate is negative, generate MOVN else MOVZ.
436  // (Bit 30 = 0) ==> MOVN, (Bit 30 = 1) ==> MOVZ.
437  if (SignedValue < 0)
438  Data[Offset + 3] &= ~(1 << 6);
439  else
440  Data[Offset + 3] |= (1 << 6);
441  }
442 }
443 
444 bool AArch64AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
445  uint64_t Value,
446  const MCRelaxableFragment *DF,
447  const MCAsmLayout &Layout) const {
448  // FIXME: This isn't correct for AArch64. Just moving the "generic" logic
449  // into the targets for now.
450  //
451  // Relax if the value is too big for a (signed) i8.
452  return int64_t(Value) != int64_t(int8_t(Value));
453 }
454 
455 void AArch64AsmBackend::relaxInstruction(MCInst &Inst,
456  const MCSubtargetInfo &STI) const {
457  llvm_unreachable("AArch64AsmBackend::relaxInstruction() unimplemented");
458 }
459 
460 bool AArch64AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
461  const MCSubtargetInfo *STI) const {
462  // If the count is not 4-byte aligned, we must be writing data into the text
463  // section (otherwise we have unaligned instructions, and thus have far
464  // bigger problems), so just write zeros instead.
465  OS.write_zeros(Count % 4);
466 
467  // We are properly aligned, so write NOPs as requested.
468  Count /= 4;
469  for (uint64_t i = 0; i != Count; ++i)
470  support::endian::write<uint32_t>(OS, 0xd503201f, Endian);
471  return true;
472 }
473 
474 bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
475  const MCFixup &Fixup,
476  const MCValue &Target) {
477  unsigned Kind = Fixup.getKind();
479  return true;
480 
481  // The ADRP instruction adds some multiple of 0x1000 to the current PC &
482  // ~0xfff. This means that the required offset to reach a symbol can vary by
483  // up to one step depending on where the ADRP is in memory. For example:
484  //
485  // ADRP x0, there
486  // there:
487  //
488  // If the ADRP occurs at address 0xffc then "there" will be at 0x1000 and
489  // we'll need that as an offset. At any other address "there" will be in the
490  // same page as the ADRP and the instruction should encode 0x0. Assuming the
491  // section isn't 0x1000-aligned, we therefore need to delegate this decision
492  // to the linker -- a relocation!
494  return true;
495 
496  return false;
497 }
498 
499 namespace {
500 
501 namespace CU {
502 
503 /// Compact unwind encoding values.
505  /// A "frameless" leaf function, where no non-volatile registers are
506  /// saved. The return remains in LR throughout the function.
507  UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
508 
509  /// No compact unwind encoding available. Instead the low 23-bits of
510  /// the compact unwind encoding is the offset of the DWARF FDE in the
511  /// __eh_frame section. This mode is never used in object files. It is only
512  /// generated by the linker in final linked images, which have only DWARF info
513  /// for a function.
514  UNWIND_ARM64_MODE_DWARF = 0x03000000,
515 
516  /// This is a standard arm64 prologue where FP/LR are immediately
517  /// pushed on the stack, then SP is copied to FP. If there are any
518  /// non-volatile register saved, they are copied into the stack fame in pairs
519  /// in a contiguous ranger right below the saved FP/LR pair. Any subset of the
520  /// five X pairs and four D pairs can be saved, but the memory layout must be
521  /// in register number order.
522  UNWIND_ARM64_MODE_FRAME = 0x04000000,
523 
524  /// Frame register pair encodings.
525  UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
526  UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
527  UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
528  UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
529  UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
530  UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
531  UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
532  UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
533  UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
534 };
535 
536 } // end CU namespace
537 
538 // FIXME: This should be in a separate file.
539 class DarwinAArch64AsmBackend : public AArch64AsmBackend {
540  const MCRegisterInfo &MRI;
541 
542  /// Encode compact unwind stack adjustment for frameless functions.
543  /// See UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK in compact_unwind_encoding.h.
544  /// The stack size always needs to be 16 byte aligned.
545  uint32_t encodeStackAdjustment(uint32_t StackSize) const {
546  return (StackSize / 16) << 12;
547  }
548 
549 public:
550  DarwinAArch64AsmBackend(const Target &T, const Triple &TT,
551  const MCRegisterInfo &MRI)
552  : AArch64AsmBackend(T, TT, /*IsLittleEndian*/ true), MRI(MRI) {}
553 
554  std::unique_ptr<MCObjectTargetWriter>
555  createObjectTargetWriter() const override {
557  uint32_t CPUSubType = cantFail(MachO::getCPUSubType(TheTriple));
558  return createAArch64MachObjectWriter(CPUType, CPUSubType,
559  TheTriple.isArch32Bit());
560  }
561 
562  /// Generate the compact unwind encoding from the CFI directives.
563  uint32_t generateCompactUnwindEncoding(
564  ArrayRef<MCCFIInstruction> Instrs) const override {
565  if (Instrs.empty())
566  return CU::UNWIND_ARM64_MODE_FRAMELESS;
567 
568  bool HasFP = false;
569  unsigned StackSize = 0;
570 
571  uint32_t CompactUnwindEncoding = 0;
572  int CurOffset = 0;
573  for (size_t i = 0, e = Instrs.size(); i != e; ++i) {
574  const MCCFIInstruction &Inst = Instrs[i];
575 
576  switch (Inst.getOperation()) {
577  default:
578  // Cannot handle this directive: bail out.
579  return CU::UNWIND_ARM64_MODE_DWARF;
581  // Defines a frame pointer.
582  unsigned XReg =
583  getXRegFromWReg(*MRI.getLLVMRegNum(Inst.getRegister(), true));
584 
585  // Other CFA registers than FP are not supported by compact unwind.
586  // Fallback on DWARF.
587  // FIXME: When opt-remarks are supported in MC, add a remark to notify
588  // the user.
589  if (XReg != AArch64::FP)
590  return CU::UNWIND_ARM64_MODE_DWARF;
591 
592  assert(XReg == AArch64::FP && "Invalid frame pointer!");
593  assert(i + 2 < e && "Insufficient CFI instructions to define a frame!");
594 
595  const MCCFIInstruction &LRPush = Instrs[++i];
597  "Link register not pushed!");
598  const MCCFIInstruction &FPPush = Instrs[++i];
600  "Frame pointer not pushed!");
601 
602  assert(FPPush.getOffset() + 8 == LRPush.getOffset());
603  CurOffset = FPPush.getOffset();
604 
605  unsigned LRReg = *MRI.getLLVMRegNum(LRPush.getRegister(), true);
606  unsigned FPReg = *MRI.getLLVMRegNum(FPPush.getRegister(), true);
607 
608  LRReg = getXRegFromWReg(LRReg);
609  FPReg = getXRegFromWReg(FPReg);
610 
611  assert(LRReg == AArch64::LR && FPReg == AArch64::FP &&
612  "Pushing invalid registers for frame!");
613 
614  // Indicate that the function has a frame.
615  CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
616  HasFP = true;
617  break;
618  }
620  assert(StackSize == 0 && "We already have the CFA offset!");
621  StackSize = std::abs(Inst.getOffset());
622  break;
623  }
625  // Registers are saved in pairs. We expect there to be two consecutive
626  // `.cfi_offset' instructions with the appropriate registers specified.
627  unsigned Reg1 = *MRI.getLLVMRegNum(Inst.getRegister(), true);
628  if (i + 1 == e)
629  return CU::UNWIND_ARM64_MODE_DWARF;
630 
631  if (CurOffset != 0 && Inst.getOffset() != CurOffset - 8)
632  return CU::UNWIND_ARM64_MODE_DWARF;
633  CurOffset = Inst.getOffset();
634 
635  const MCCFIInstruction &Inst2 = Instrs[++i];
637  return CU::UNWIND_ARM64_MODE_DWARF;
638  unsigned Reg2 = *MRI.getLLVMRegNum(Inst2.getRegister(), true);
639 
640  if (Inst2.getOffset() != CurOffset - 8)
641  return CU::UNWIND_ARM64_MODE_DWARF;
642  CurOffset = Inst2.getOffset();
643 
644  // N.B. The encodings must be in register number order, and the X
645  // registers before the D registers.
646 
647  // X19/X20 pair = 0x00000001,
648  // X21/X22 pair = 0x00000002,
649  // X23/X24 pair = 0x00000004,
650  // X25/X26 pair = 0x00000008,
651  // X27/X28 pair = 0x00000010
652  Reg1 = getXRegFromWReg(Reg1);
653  Reg2 = getXRegFromWReg(Reg2);
654 
655  if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
656  (CompactUnwindEncoding & 0xF1E) == 0)
657  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
658  else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
659  (CompactUnwindEncoding & 0xF1C) == 0)
660  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
661  else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
662  (CompactUnwindEncoding & 0xF18) == 0)
663  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
664  else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
665  (CompactUnwindEncoding & 0xF10) == 0)
666  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
667  else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
668  (CompactUnwindEncoding & 0xF00) == 0)
669  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
670  else {
671  Reg1 = getDRegFromBReg(Reg1);
672  Reg2 = getDRegFromBReg(Reg2);
673 
674  // D8/D9 pair = 0x00000100,
675  // D10/D11 pair = 0x00000200,
676  // D12/D13 pair = 0x00000400,
677  // D14/D15 pair = 0x00000800
678  if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
679  (CompactUnwindEncoding & 0xE00) == 0)
680  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
681  else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
682  (CompactUnwindEncoding & 0xC00) == 0)
683  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
684  else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
685  (CompactUnwindEncoding & 0x800) == 0)
686  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
687  else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
688  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
689  else
690  // A pair was pushed which we cannot handle.
691  return CU::UNWIND_ARM64_MODE_DWARF;
692  }
693 
694  break;
695  }
696  }
697  }
698 
699  if (!HasFP) {
700  // With compact unwind info we can only represent stack adjustments of up
701  // to 65520 bytes.
702  if (StackSize > 65520)
703  return CU::UNWIND_ARM64_MODE_DWARF;
704 
705  CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
706  CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
707  }
708 
709  return CompactUnwindEncoding;
710  }
711 };
712 
713 } // end anonymous namespace
714 
715 namespace {
716 
717 class ELFAArch64AsmBackend : public AArch64AsmBackend {
718 public:
719  uint8_t OSABI;
720  bool IsILP32;
721 
722  ELFAArch64AsmBackend(const Target &T, const Triple &TT, uint8_t OSABI,
723  bool IsLittleEndian, bool IsILP32)
724  : AArch64AsmBackend(T, TT, IsLittleEndian), OSABI(OSABI),
725  IsILP32(IsILP32) {}
726 
727  std::unique_ptr<MCObjectTargetWriter>
728  createObjectTargetWriter() const override {
729  return createAArch64ELFObjectWriter(OSABI, IsILP32);
730  }
731 };
732 
733 }
734 
735 namespace {
736 class COFFAArch64AsmBackend : public AArch64AsmBackend {
737 public:
738  COFFAArch64AsmBackend(const Target &T, const Triple &TheTriple)
739  : AArch64AsmBackend(T, TheTriple, /*IsLittleEndian*/ true) {}
740 
741  std::unique_ptr<MCObjectTargetWriter>
742  createObjectTargetWriter() const override {
744  }
745 };
746 }
747 
749  const MCSubtargetInfo &STI,
750  const MCRegisterInfo &MRI,
751  const MCTargetOptions &Options) {
752  const Triple &TheTriple = STI.getTargetTriple();
753  if (TheTriple.isOSBinFormatMachO()) {
754  return new DarwinAArch64AsmBackend(T, TheTriple, MRI);
755  }
756 
757  if (TheTriple.isOSBinFormatCOFF())
758  return new COFFAArch64AsmBackend(T, TheTriple);
759 
760  assert(TheTriple.isOSBinFormatELF() && "Invalid target");
761 
762  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
763  bool IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
764  return new ELFAArch64AsmBackend(T, TheTriple, OSABI, /*IsLittleEndian=*/true,
765  IsILP32);
766 }
767 
769  const MCSubtargetInfo &STI,
770  const MCRegisterInfo &MRI,
771  const MCTargetOptions &Options) {
772  const Triple &TheTriple = STI.getTargetTriple();
773  assert(TheTriple.isOSBinFormatELF() &&
774  "Big endian is only supported for ELF targets!");
775  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
776  bool IsILP32 = STI.getTargetTriple().getEnvironment() == Triple::GNUILP32;
777  return new ELFAArch64AsmBackend(T, TheTriple, OSABI, /*IsLittleEndian=*/false,
778  IsILP32);
779 }
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:67
i
i
Definition: README.txt:29
llvm
This file implements support for optimizing divisions by a constant.
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:216
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:640
T
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:72
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:463
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:137
MCSectionELF.h
llvm::FirstTargetFixupKind
@ FirstTargetFixupKind
Definition: MCFixup.h:45
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:45
llvm::MachO::CPUType
CPUType
Definition: MachO.h:1418
llvm::Optional
Definition: APInt.h:33
MCFixupKindInfo.h
llvm::AArch64::NumTargetFixupKinds
@ NumTargetFixupKinds
Definition: AArch64FixupKinds.h:60
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::createAArch64WinCOFFObjectWriter
std::unique_ptr< MCObjectTargetWriter > createAArch64WinCOFFObjectWriter()
Definition: AArch64WinCOFFObjectWriter.cpp:161
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:55
llvm::ArrayRef::empty
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:160
llvm::MachO::getCPUType
Expected< uint32_t > getCPUType(const Triple &T)
Definition: MachO.cpp:77
llvm::MCCFIInstruction::OpDefCfa
@ OpDefCfa
Definition: MCDwarf.h:467
llvm::FirstLiteralRelocationKind
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
Definition: MCFixup.h:50
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:635
llvm::createAArch64ELFObjectWriter
std::unique_ptr< MCObjectTargetWriter > createAArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32)
Definition: AArch64ELFObjectWriter.cpp:457
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:504
MCAsmBackend.h
llvm::MutableArrayRef< char >
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:642
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:648
AArch64FixupKinds.h
llvm::AArch64::fixup_aarch64_pcrel_branch19
@ fixup_aarch64_pcrel_branch19
Definition: AArch64FixupKinds.h:49
Options
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Definition: PassBuilderBindings.cpp:48
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::MCCFIInstruction::getOperation
OpType getOperation() const
Definition: MCDwarf.h:620
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::MachO::getCPUSubType
Expected< uint32_t > getCPUSubType(const Triple &T)
Definition: MachO.cpp:95
llvm::MCCFIInstruction::getRegister
unsigned getRegister() const
Definition: MCDwarf.h:623
llvm::None
const NoneType None
Definition: None.h:23
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
llvm::MCCFIInstruction
Definition: MCDwarf.h:457
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:107
llvm::MCAssembler
Definition: MCAssembler.h:60
llvm::MCCFIInstruction::OpDefCfaOffset
@ OpDefCfaOffset
Definition: MCDwarf.h:466
uint64_t
AdrImmBits
static unsigned AdrImmBits(unsigned Value)
Definition: AArch64AsmBackend.cpp:144
llvm::Triple::getOS
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:319
MCELFObjectWriter.h
llvm::Triple::isArch32Bit
bool isArch32Bit() const
Test whether the architecture is 32-bit.
Definition: Triple.cpp:1346
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:150
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:963
llvm::createAArch64beAsmBackend
MCAsmBackend * createAArch64beAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Definition: AArch64AsmBackend.cpp:768
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:101
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
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:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::cantFail
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition: Error.h:737
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:165
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:328
llvm::getDRegFromBReg
static unsigned getDRegFromBReg(unsigned Reg)
Definition: AArch64BaseInfo.h:168
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:1903
TargetRegistry.h
llvm::abs
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition: APFloat.h:1282
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
CU
Definition: AArch64AsmBackend.cpp:501
llvm::MCFixup
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
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:748
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