35 static const unsigned PCRelFlagVal =
41 AArch64AsmBackend(
const Target &
T,
const Triple &TT,
bool IsLittleEndian)
45 unsigned getNumFixupKinds()
const override {
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}};
93 void relaxInstruction(
MCInst &Inst,
98 unsigned getFixupKindContainereSizeInBytes(
unsigned Kind)
const;
145 unsigned lo2 =
Value & 0x3;
146 unsigned hi19 = (
Value & 0x1ffffc) >> 2;
147 return (hi19 << 5) | (lo2 << 29);
152 const Triple &TheTriple,
bool IsResolved) {
153 int64_t SignedValue =
static_cast<int64_t
>(
Value);
154 switch (
Fixup.getTargetKind()) {
158 if (SignedValue > 2097151 || SignedValue < -2097152)
164 if (!isInt<21>(SignedValue))
172 if (SignedValue > 2097151 || SignedValue < -2097152)
177 return (
Value >> 2) & 0x7ffff;
217 if (
Value >= 0x10000)
229 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
231 "fixup value out of range [-0xFFFF, 0xFFFF]");
235 SignedValue = ~SignedValue;
241 "relocation for a thread-local variable points to an "
259 SignedValue = SignedValue >> 16;
262 SignedValue = SignedValue >> 32;
265 SignedValue = SignedValue >> 48;
293 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
298 SignedValue = ~SignedValue;
301 else if (
Value > 0xFFFF) {
308 if (SignedValue > 32767 || SignedValue < -32768)
313 return (
Value >> 2) & 0x3fff;
317 if (SignedValue > 134217727 || SignedValue < -134217728)
322 return (
Value >> 2) & 0x3ffffff;
338 #define ELF_RELOC(X, Y) .Case(#X, Y)
339 #include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
341 .
Case(
"BFD_RELOC_NONE", ELF::R_AARCH64_NONE)
342 .
Case(
"BFD_RELOC_16", ELF::R_AARCH64_ABS16)
343 .
Case(
"BFD_RELOC_32", ELF::R_AARCH64_ABS32)
344 .
Case(
"BFD_RELOC_64", ELF::R_AARCH64_ABS64)
353 unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(
unsigned Kind)
const {
402 int64_t SignedValue =
static_cast<int64_t
>(
Value);
410 assert(Offset + NumBytes <=
Data.size() &&
"Invalid fixup offset!");
413 unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(
Fixup.getKind());
417 if (FulleSizeInBytes == 0) {
419 for (
unsigned i = 0;
i != NumBytes; ++
i) {
424 assert((Offset + FulleSizeInBytes) <=
Data.size() &&
"Invalid fixup size!");
425 assert(NumBytes <= FulleSizeInBytes &&
"Invalid fixup size!");
426 for (
unsigned i = 0;
i != NumBytes; ++
i) {
427 unsigned Idx = FulleSizeInBytes - 1 -
i;
447 bool AArch64AsmBackend::fixupNeedsRelaxation(
const MCFixup &Fixup,
455 return int64_t(
Value) != int64_t(int8_t(
Value));
458 void AArch64AsmBackend::relaxInstruction(
MCInst &Inst,
473 OS.
write(
"\x1f\x20\x03\xd5", 4);
477 bool AArch64AsmBackend::shouldForceRelocation(
const MCAssembler &
Asm,
510 UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
517 UNWIND_ARM64_MODE_DWARF = 0x03000000,
525 UNWIND_ARM64_MODE_FRAME = 0x04000000,
528 UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
529 UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
530 UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
531 UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
532 UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
533 UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
534 UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
535 UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
536 UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
542 class DarwinAArch64AsmBackend :
public AArch64AsmBackend {
549 return (StackSize / 16) << 12;
557 std::unique_ptr<MCObjectTargetWriter>
558 createObjectTargetWriter()
const override {
566 uint32_t generateCompactUnwindEncoding(
569 return CU::UNWIND_ARM64_MODE_FRAMELESS;
572 unsigned StackSize = 0;
576 for (
size_t i = 0,
e = Instrs.
size();
i !=
e; ++
i) {
582 return CU::UNWIND_ARM64_MODE_DWARF;
592 if (XReg != AArch64::FP)
593 return CU::UNWIND_ARM64_MODE_DWARF;
596 return CU::UNWIND_ARM64_MODE_DWARF;
600 return CU::UNWIND_ARM64_MODE_DWARF;
603 return CU::UNWIND_ARM64_MODE_DWARF;
606 return CU::UNWIND_ARM64_MODE_DWARF;
615 if (LRReg != AArch64::LR || FPReg != AArch64::FP)
616 return CU::UNWIND_ARM64_MODE_DWARF;
619 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
625 return CU::UNWIND_ARM64_MODE_DWARF;
634 return CU::UNWIND_ARM64_MODE_DWARF;
636 if (CurOffset != 0 && Inst.
getOffset() != CurOffset - 8)
637 return CU::UNWIND_ARM64_MODE_DWARF;
642 return CU::UNWIND_ARM64_MODE_DWARF;
646 return CU::UNWIND_ARM64_MODE_DWARF;
660 if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
661 (CompactUnwindEncoding & 0xF1E) == 0)
662 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
663 else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
664 (CompactUnwindEncoding & 0xF1C) == 0)
665 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
666 else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
667 (CompactUnwindEncoding & 0xF18) == 0)
668 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
669 else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
670 (CompactUnwindEncoding & 0xF10) == 0)
671 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
672 else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
673 (CompactUnwindEncoding & 0xF00) == 0)
674 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
683 if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
684 (CompactUnwindEncoding & 0xE00) == 0)
685 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
686 else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
687 (CompactUnwindEncoding & 0xC00) == 0)
688 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
689 else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
690 (CompactUnwindEncoding & 0x800) == 0)
691 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
692 else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
693 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
696 return CU::UNWIND_ARM64_MODE_DWARF;
707 if (StackSize > 65520)
708 return CU::UNWIND_ARM64_MODE_DWARF;
710 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
711 CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
714 return CompactUnwindEncoding;
722 class ELFAArch64AsmBackend :
public AArch64AsmBackend {
727 ELFAArch64AsmBackend(
const Target &
T,
const Triple &TT, uint8_t OSABI,
728 bool IsLittleEndian,
bool IsILP32)
729 : AArch64AsmBackend(
T,
TT, IsLittleEndian), OSABI(OSABI),
732 std::unique_ptr<MCObjectTargetWriter>
733 createObjectTargetWriter()
const override {
741 class COFFAArch64AsmBackend :
public AArch64AsmBackend {
743 COFFAArch64AsmBackend(
const Target &
T,
const Triple &TheTriple)
744 : AArch64AsmBackend(
T, TheTriple,
true) {}
746 std::unique_ptr<MCObjectTargetWriter>
747 createObjectTargetWriter()
const override {
759 return new DarwinAArch64AsmBackend(
T, TheTriple,
MRI);
763 return new COFFAArch64AsmBackend(
T, TheTriple);
769 return new ELFAArch64AsmBackend(
T, TheTriple, OSABI,
true,
779 "Big endian is only supported for ELF targets!");
782 return new ELFAArch64AsmBackend(
T, TheTriple, OSABI,
false,