LLVM  6.0.0svn
AArch64AsmBackend.cpp
Go to the documentation of this file.
1 //===-- AArch64AsmBackend.cpp - AArch64 Assembler Backend -----------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "AArch64.h"
11 #include "AArch64RegisterInfo.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/MCSectionELF.h"
23 #include "llvm/MC/MCSectionMachO.h"
24 #include "llvm/MC/MCValue.h"
26 using namespace llvm;
27 
28 namespace {
29 
30 class AArch64AsmBackend : public MCAsmBackend {
31  static const unsigned PCRelFlagVal =
33  Triple TheTriple;
34 
35 public:
36  bool IsLittleEndian;
37 
38 public:
39  AArch64AsmBackend(const Target &T, const Triple &TT, bool IsLittleEndian)
40  : MCAsmBackend(), TheTriple(TT), IsLittleEndian(IsLittleEndian) {}
41 
42  unsigned getNumFixupKinds() const override {
44  }
45 
46  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
47  const static MCFixupKindInfo Infos[AArch64::NumTargetFixupKinds] = {
48  // This table *must* be in the order that the fixup_* kinds are defined
49  // in AArch64FixupKinds.h.
50  //
51  // Name Offset (bits) Size (bits) Flags
52  {"fixup_aarch64_pcrel_adr_imm21", 0, 32, PCRelFlagVal},
53  {"fixup_aarch64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal},
54  {"fixup_aarch64_add_imm12", 10, 12, 0},
55  {"fixup_aarch64_ldst_imm12_scale1", 10, 12, 0},
56  {"fixup_aarch64_ldst_imm12_scale2", 10, 12, 0},
57  {"fixup_aarch64_ldst_imm12_scale4", 10, 12, 0},
58  {"fixup_aarch64_ldst_imm12_scale8", 10, 12, 0},
59  {"fixup_aarch64_ldst_imm12_scale16", 10, 12, 0},
60  {"fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal},
61  {"fixup_aarch64_movw", 5, 16, 0},
62  {"fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal},
63  {"fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal},
64  {"fixup_aarch64_pcrel_branch26", 0, 26, PCRelFlagVal},
65  {"fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal},
66  {"fixup_aarch64_tlsdesc_call", 0, 0, 0}};
67 
68  if (Kind < FirstTargetFixupKind)
69  return MCAsmBackend::getFixupKindInfo(Kind);
70 
71  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
72  "Invalid kind!");
73  return Infos[Kind - FirstTargetFixupKind];
74  }
75 
76  void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
78  uint64_t Value, bool IsResolved) const override;
79 
80  bool mayNeedRelaxation(const MCInst &Inst) const override;
81  bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
82  const MCRelaxableFragment *DF,
83  const MCAsmLayout &Layout) const override;
84  void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
85  MCInst &Res) const override;
86  bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
87 
88  void HandleAssemblerFlag(MCAssemblerFlag Flag) {}
89 
90  unsigned getPointerSize() const { return 8; }
91 
92  unsigned getFixupKindContainereSizeInBytes(unsigned Kind) const;
93 
94  bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
95  const MCValue &Target) override;
96 };
97 
98 } // end anonymous namespace
99 
100 /// \brief The number of bytes the fixup may change.
101 static unsigned getFixupKindNumBytes(unsigned Kind) {
102  switch (Kind) {
103  default:
104  llvm_unreachable("Unknown fixup kind!");
105 
107  return 0;
108 
109  case FK_Data_1:
110  return 1;
111 
113  case FK_Data_2:
114  case FK_SecRel_2:
115  return 2;
116 
126  return 3;
127 
132  case FK_Data_4:
133  case FK_SecRel_4:
134  return 4;
135 
136  case FK_Data_8:
137  return 8;
138  }
139 }
140 
141 static unsigned AdrImmBits(unsigned Value) {
142  unsigned lo2 = Value & 0x3;
143  unsigned hi19 = (Value & 0x1ffffc) >> 2;
144  return (hi19 << 5) | (lo2 << 29);
145 }
146 
147 static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
148  MCContext &Ctx, const Triple &TheTriple,
149  bool IsResolved) {
150  unsigned Kind = Fixup.getKind();
151  int64_t SignedValue = static_cast<int64_t>(Value);
152  switch (Kind) {
153  default:
154  llvm_unreachable("Unknown fixup kind!");
156  if (SignedValue > 2097151 || SignedValue < -2097152)
157  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
158  return AdrImmBits(Value & 0x1fffffULL);
160  assert(!IsResolved);
161  if (TheTriple.isOSBinFormatCOFF())
162  return AdrImmBits(Value & 0x1fffffULL);
163  return AdrImmBits((Value & 0x1fffff000ULL) >> 12);
166  // Signed 21-bit immediate
167  if (SignedValue > 2097151 || SignedValue < -2097152)
168  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
169  if (Value & 0x3)
170  Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
171  // Low two bits are not encoded.
172  return (Value >> 2) & 0x7ffff;
175  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
176  Value &= 0xfff;
177  // Unsigned 12-bit immediate
178  if (Value >= 0x1000)
179  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
180  return Value;
182  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
183  Value &= 0xfff;
184  // Unsigned 12-bit immediate which gets multiplied by 2
185  if (Value >= 0x2000)
186  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
187  if (Value & 0x1)
188  Ctx.reportError(Fixup.getLoc(), "fixup must be 2-byte aligned");
189  return Value >> 1;
191  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
192  Value &= 0xfff;
193  // Unsigned 12-bit immediate which gets multiplied by 4
194  if (Value >= 0x4000)
195  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
196  if (Value & 0x3)
197  Ctx.reportError(Fixup.getLoc(), "fixup must be 4-byte aligned");
198  return Value >> 2;
200  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
201  Value &= 0xfff;
202  // Unsigned 12-bit immediate which gets multiplied by 8
203  if (Value >= 0x8000)
204  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
205  if (Value & 0x7)
206  Ctx.reportError(Fixup.getLoc(), "fixup must be 8-byte aligned");
207  return Value >> 3;
209  if (TheTriple.isOSBinFormatCOFF() && !IsResolved)
210  Value &= 0xfff;
211  // Unsigned 12-bit immediate which gets multiplied by 16
212  if (Value >= 0x10000)
213  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
214  if (Value & 0xf)
215  Ctx.reportError(Fixup.getLoc(), "fixup must be 16-byte aligned");
216  return Value >> 4;
218  Ctx.reportError(Fixup.getLoc(),
219  "no resolvable MOVZ/MOVK fixups supported yet");
220  return Value;
222  // Signed 16-bit immediate
223  if (SignedValue > 32767 || SignedValue < -32768)
224  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
225  // Low two bits are not encoded (4-byte alignment assumed).
226  if (Value & 0x3)
227  Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
228  return (Value >> 2) & 0x3fff;
231  // Signed 28-bit immediate
232  if (SignedValue > 134217727 || SignedValue < -134217728)
233  Ctx.reportError(Fixup.getLoc(), "fixup value out of range");
234  // Low two bits are not encoded (4-byte alignment assumed).
235  if (Value & 0x3)
236  Ctx.reportError(Fixup.getLoc(), "fixup not sufficiently aligned");
237  return (Value >> 2) & 0x3ffffff;
238  case FK_Data_1:
239  case FK_Data_2:
240  case FK_Data_4:
241  case FK_Data_8:
242  case FK_SecRel_2:
243  case FK_SecRel_4:
244  return Value;
245  }
246 }
247 
248 /// getFixupKindContainereSizeInBytes - The number of bytes of the
249 /// container involved in big endian or 0 if the item is little endian
250 unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(unsigned Kind) const {
251  if (IsLittleEndian)
252  return 0;
253 
254  switch (Kind) {
255  default:
256  llvm_unreachable("Unknown fixup kind!");
257 
258  case FK_Data_1:
259  return 1;
260  case FK_Data_2:
261  return 2;
262  case FK_Data_4:
263  return 4;
264  case FK_Data_8:
265  return 8;
266 
282  // Instructions are always little endian
283  return 0;
284  }
285 }
286 
287 void AArch64AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
288  const MCValue &Target,
289  MutableArrayRef<char> Data, uint64_t Value,
290  bool IsResolved) const {
291  unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
292  if (!Value)
293  return; // Doesn't change encoding.
294  MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
295  MCContext &Ctx = Asm.getContext();
296  // Apply any target-specific value adjustments.
297  Value = adjustFixupValue(Fixup, Value, Ctx, TheTriple, IsResolved);
298 
299  // Shift the value into position.
300  Value <<= Info.TargetOffset;
301 
302  unsigned Offset = Fixup.getOffset();
303  assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
304 
305  // Used to point to big endian bytes.
306  unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(Fixup.getKind());
307 
308  // For each byte of the fragment that the fixup touches, mask in the
309  // bits from the fixup value.
310  if (FulleSizeInBytes == 0) {
311  // Handle as little-endian
312  for (unsigned i = 0; i != NumBytes; ++i) {
313  Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
314  }
315  } else {
316  // Handle as big-endian
317  assert((Offset + FulleSizeInBytes) <= Data.size() && "Invalid fixup size!");
318  assert(NumBytes <= FulleSizeInBytes && "Invalid fixup size!");
319  for (unsigned i = 0; i != NumBytes; ++i) {
320  unsigned Idx = FulleSizeInBytes - 1 - i;
321  Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
322  }
323  }
324 }
325 
326 bool AArch64AsmBackend::mayNeedRelaxation(const MCInst &Inst) const {
327  return false;
328 }
329 
330 bool AArch64AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup,
331  uint64_t Value,
332  const MCRelaxableFragment *DF,
333  const MCAsmLayout &Layout) const {
334  // FIXME: This isn't correct for AArch64. Just moving the "generic" logic
335  // into the targets for now.
336  //
337  // Relax if the value is too big for a (signed) i8.
338  return int64_t(Value) != int64_t(int8_t(Value));
339 }
340 
341 void AArch64AsmBackend::relaxInstruction(const MCInst &Inst,
342  const MCSubtargetInfo &STI,
343  MCInst &Res) const {
344  llvm_unreachable("AArch64AsmBackend::relaxInstruction() unimplemented");
345 }
346 
347 bool AArch64AsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
348  // If the count is not 4-byte aligned, we must be writing data into the text
349  // section (otherwise we have unaligned instructions, and thus have far
350  // bigger problems), so just write zeros instead.
351  OW->WriteZeros(Count % 4);
352 
353  // We are properly aligned, so write NOPs as requested.
354  Count /= 4;
355  for (uint64_t i = 0; i != Count; ++i)
356  OW->write32(0xd503201f);
357  return true;
358 }
359 
360 bool AArch64AsmBackend::shouldForceRelocation(const MCAssembler &Asm,
361  const MCFixup &Fixup,
362  const MCValue &Target) {
363  // The ADRP instruction adds some multiple of 0x1000 to the current PC &
364  // ~0xfff. This means that the required offset to reach a symbol can vary by
365  // up to one step depending on where the ADRP is in memory. For example:
366  //
367  // ADRP x0, there
368  // there:
369  //
370  // If the ADRP occurs at address 0xffc then "there" will be at 0x1000 and
371  // we'll need that as an offset. At any other address "there" will be in the
372  // same page as the ADRP and the instruction should encode 0x0. Assuming the
373  // section isn't 0x1000-aligned, we therefore need to delegate this decision
374  // to the linker -- a relocation!
376  return true;
377  return false;
378 }
379 
380 namespace {
381 
382 namespace CU {
383 
384 /// \brief Compact unwind encoding values.
386  /// \brief A "frameless" leaf function, where no non-volatile registers are
387  /// saved. The return remains in LR throughout the function.
388  UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
389 
390  /// \brief No compact unwind encoding available. Instead the low 23-bits of
391  /// the compact unwind encoding is the offset of the DWARF FDE in the
392  /// __eh_frame section. This mode is never used in object files. It is only
393  /// generated by the linker in final linked images, which have only DWARF info
394  /// for a function.
395  UNWIND_ARM64_MODE_DWARF = 0x03000000,
396 
397  /// \brief This is a standard arm64 prologue where FP/LR are immediately
398  /// pushed on the stack, then SP is copied to FP. If there are any
399  /// non-volatile register saved, they are copied into the stack fame in pairs
400  /// in a contiguous ranger right below the saved FP/LR pair. Any subset of the
401  /// five X pairs and four D pairs can be saved, but the memory layout must be
402  /// in register number order.
403  UNWIND_ARM64_MODE_FRAME = 0x04000000,
404 
405  /// \brief Frame register pair encodings.
406  UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
407  UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
408  UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
409  UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
410  UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
411  UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
412  UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
413  UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
414  UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
415 };
416 
417 } // end CU namespace
418 
419 // FIXME: This should be in a separate file.
420 class DarwinAArch64AsmBackend : public AArch64AsmBackend {
421  const MCRegisterInfo &MRI;
422 
423  /// \brief Encode compact unwind stack adjustment for frameless functions.
424  /// See UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK in compact_unwind_encoding.h.
425  /// The stack size always needs to be 16 byte aligned.
426  uint32_t encodeStackAdjustment(uint32_t StackSize) const {
427  return (StackSize / 16) << 12;
428  }
429 
430 public:
431  DarwinAArch64AsmBackend(const Target &T, const Triple &TT,
432  const MCRegisterInfo &MRI)
433  : AArch64AsmBackend(T, TT, /*IsLittleEndian*/ true), MRI(MRI) {}
434 
435  std::unique_ptr<MCObjectWriter>
436  createObjectWriter(raw_pwrite_stream &OS) const override {
439  }
440 
441  /// \brief Generate the compact unwind encoding from the CFI directives.
442  uint32_t generateCompactUnwindEncoding(
443  ArrayRef<MCCFIInstruction> Instrs) const override {
444  if (Instrs.empty())
445  return CU::UNWIND_ARM64_MODE_FRAMELESS;
446 
447  bool HasFP = false;
448  unsigned StackSize = 0;
449 
450  uint32_t CompactUnwindEncoding = 0;
451  for (size_t i = 0, e = Instrs.size(); i != e; ++i) {
452  const MCCFIInstruction &Inst = Instrs[i];
453 
454  switch (Inst.getOperation()) {
455  default:
456  // Cannot handle this directive: bail out.
457  return CU::UNWIND_ARM64_MODE_DWARF;
459  // Defines a frame pointer.
460  assert(getXRegFromWReg(MRI.getLLVMRegNum(Inst.getRegister(), true)) ==
461  AArch64::FP &&
462  "Invalid frame pointer!");
463  assert(i + 2 < e && "Insufficient CFI instructions to define a frame!");
464 
465  const MCCFIInstruction &LRPush = Instrs[++i];
467  "Link register not pushed!");
468  const MCCFIInstruction &FPPush = Instrs[++i];
469  assert(FPPush.getOperation() == MCCFIInstruction::OpOffset &&
470  "Frame pointer not pushed!");
471 
472  unsigned LRReg = MRI.getLLVMRegNum(LRPush.getRegister(), true);
473  unsigned FPReg = MRI.getLLVMRegNum(FPPush.getRegister(), true);
474 
475  LRReg = getXRegFromWReg(LRReg);
476  FPReg = getXRegFromWReg(FPReg);
477 
478  assert(LRReg == AArch64::LR && FPReg == AArch64::FP &&
479  "Pushing invalid registers for frame!");
480 
481  // Indicate that the function has a frame.
482  CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
483  HasFP = true;
484  break;
485  }
487  assert(StackSize == 0 && "We already have the CFA offset!");
488  StackSize = std::abs(Inst.getOffset());
489  break;
490  }
492  // Registers are saved in pairs. We expect there to be two consecutive
493  // `.cfi_offset' instructions with the appropriate registers specified.
494  unsigned Reg1 = MRI.getLLVMRegNum(Inst.getRegister(), true);
495  if (i + 1 == e)
496  return CU::UNWIND_ARM64_MODE_DWARF;
497 
498  const MCCFIInstruction &Inst2 = Instrs[++i];
500  return CU::UNWIND_ARM64_MODE_DWARF;
501  unsigned Reg2 = MRI.getLLVMRegNum(Inst2.getRegister(), true);
502 
503  // N.B. The encodings must be in register number order, and the X
504  // registers before the D registers.
505 
506  // X19/X20 pair = 0x00000001,
507  // X21/X22 pair = 0x00000002,
508  // X23/X24 pair = 0x00000004,
509  // X25/X26 pair = 0x00000008,
510  // X27/X28 pair = 0x00000010
511  Reg1 = getXRegFromWReg(Reg1);
512  Reg2 = getXRegFromWReg(Reg2);
513 
514  if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
515  (CompactUnwindEncoding & 0xF1E) == 0)
516  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
517  else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
518  (CompactUnwindEncoding & 0xF1C) == 0)
519  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
520  else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
521  (CompactUnwindEncoding & 0xF18) == 0)
522  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
523  else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
524  (CompactUnwindEncoding & 0xF10) == 0)
525  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
526  else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
527  (CompactUnwindEncoding & 0xF00) == 0)
528  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
529  else {
530  Reg1 = getDRegFromBReg(Reg1);
531  Reg2 = getDRegFromBReg(Reg2);
532 
533  // D8/D9 pair = 0x00000100,
534  // D10/D11 pair = 0x00000200,
535  // D12/D13 pair = 0x00000400,
536  // D14/D15 pair = 0x00000800
537  if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
538  (CompactUnwindEncoding & 0xE00) == 0)
539  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
540  else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
541  (CompactUnwindEncoding & 0xC00) == 0)
542  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
543  else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
544  (CompactUnwindEncoding & 0x800) == 0)
545  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
546  else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
547  CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
548  else
549  // A pair was pushed which we cannot handle.
550  return CU::UNWIND_ARM64_MODE_DWARF;
551  }
552 
553  break;
554  }
555  }
556  }
557 
558  if (!HasFP) {
559  // With compact unwind info we can only represent stack adjustments of up
560  // to 65520 bytes.
561  if (StackSize > 65520)
562  return CU::UNWIND_ARM64_MODE_DWARF;
563 
564  CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
565  CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
566  }
567 
568  return CompactUnwindEncoding;
569  }
570 };
571 
572 } // end anonymous namespace
573 
574 namespace {
575 
576 class ELFAArch64AsmBackend : public AArch64AsmBackend {
577 public:
578  uint8_t OSABI;
579  bool IsILP32;
580 
581  ELFAArch64AsmBackend(const Target &T, const Triple &TT, uint8_t OSABI,
582  bool IsLittleEndian, bool IsILP32)
583  : AArch64AsmBackend(T, TT, IsLittleEndian), OSABI(OSABI),
584  IsILP32(IsILP32) {}
585 
586  std::unique_ptr<MCObjectWriter>
587  createObjectWriter(raw_pwrite_stream &OS) const override {
588  return createAArch64ELFObjectWriter(OS, OSABI, IsLittleEndian, IsILP32);
589  }
590 };
591 
592 }
593 
594 namespace {
595 class COFFAArch64AsmBackend : public AArch64AsmBackend {
596 public:
597  COFFAArch64AsmBackend(const Target &T, const Triple &TheTriple)
598  : AArch64AsmBackend(T, TheTriple, /*IsLittleEndian*/ true) {}
599 
600  std::unique_ptr<MCObjectWriter>
601  createObjectWriter(raw_pwrite_stream &OS) const override {
603  }
604 };
605 }
606 
608  const MCRegisterInfo &MRI,
609  const Triple &TheTriple,
610  StringRef CPU,
611  const MCTargetOptions &Options) {
612  if (TheTriple.isOSBinFormatMachO())
613  return new DarwinAArch64AsmBackend(T, TheTriple, MRI);
614 
615  if (TheTriple.isOSBinFormatCOFF())
616  return new COFFAArch64AsmBackend(T, TheTriple);
617 
618  assert(TheTriple.isOSBinFormatELF() && "Invalid target");
619 
620  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
621  bool IsILP32 = Options.getABIName() == "ilp32";
622  return new ELFAArch64AsmBackend(T, TheTriple, OSABI, /*IsLittleEndian=*/true,
623  IsILP32);
624 }
625 
627  const MCRegisterInfo &MRI,
628  const Triple &TheTriple,
629  StringRef CPU,
630  const MCTargetOptions &Options) {
631  assert(TheTriple.isOSBinFormatELF() &&
632  "Big endian is only supported for ELF targets!");
633  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
634  bool IsILP32 = Options.getABIName() == "ilp32";
635  return new ELFAArch64AsmBackend(T, TheTriple, OSABI, /*IsLittleEndian=*/false,
636  IsILP32);
637 }
void WriteZeros(unsigned N)
std::unique_ptr< MCObjectWriter > createAArch64ELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI, bool IsLittleEndian, bool IsILP32)
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
This represents an "assembler immediate".
Definition: MCValue.h:40
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:588
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:294
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
static unsigned getXRegFromWReg(unsigned Reg)
Defines the object file and target independent interfaces used by the assembler backend to write nati...
unsigned TargetOffset
The bit offset to write the relocation into.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:66
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
MCContext & getContext() const
Definition: MCAssembler.h:259
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:29
A four-byte section relative fixup.
Definition: MCFixup.h:42
A four-byte fixup.
Definition: MCFixup.h:26
Context object for machine code objects.
Definition: MCContext.h:59
A two-byte section relative fixup.
Definition: MCFixup.h:41
CompactUnwindEncodings
Compact unwind encoding values.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:159
static unsigned getFixupKindNumBytes(unsigned Kind)
The number of bytes the fixup may change.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:121
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
Definition: MCFragment.h:257
void write32(uint32_t Value)
unsigned const MachineRegisterInfo * MRI
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:291
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Definition: Triple.h:593
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:23
int getOffset() const
Definition: MCDwarf.h:485
OpType getOperation() const
Definition: MCDwarf.h:469
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:570
Should this fixup kind force a 4-byte aligned effective PC value?
uint32_t getOffset() const
Definition: MCFixup.h:95
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition: Triple.h:598
static unsigned AdrImmBits(unsigned Value)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A one-byte fixup.
Definition: MCFixup.h:24
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
PowerPC TLS Dynamic Call Fixup
unsigned getRegister() const
Definition: MCDwarf.h:472
SMLoc getLoc() const
Definition: MCFixup.h:112
std::unique_ptr< MCObjectWriter > createAArch64WinCOFFObjectWriter(raw_pwrite_stream &OS)
Target - Wrapper for Target specific information.
static unsigned getDRegFromBReg(unsigned Reg)
std::unique_ptr< MCObjectWriter > createAArch64MachObjectWriter(raw_pwrite_stream &OS, uint32_t CPUType, uint32_t CPUSubtype)
StringRef getABIName() const
getABIName - If this returns a non-empty string this represents the textual name of the ABI that we w...
MCAsmBackend * createAArch64leAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, const MCTargetOptions &Options)
MCAssemblerFlag
Definition: MCDirectives.h:48
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Definition: APFloat.h:1213
MCSubtargetInfo - Generic base class for all target subtargets.
A eight-byte fixup.
Definition: MCFixup.h:27
static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, MCContext &Ctx, const Triple &TheTriple, bool IsResolved)
MCAsmBackend * createAArch64beAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, const MCTargetOptions &Options)
Target independent information on a fixup kind.
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:337
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:73
Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:40
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
static uint64_t getPointerSize(const Value *V, const DataLayout &DL, const TargetLibraryInfo &TLI)
A two-byte fixup.
Definition: MCFixup.h:25
int getLLVMRegNum(unsigned RegNum, bool isEH) const
Map a dwarf register back to a target register.
MCFixupKind getKind() const
Definition: MCFixup.h:93
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:144