36 AArch64AsmBackend(
const Target &
T,
const Triple &TT,
bool IsLittleEndian)
42 std::optional<MCFixupKind>
getFixupKind(StringRef Name)
const override;
44 MCFixupKindInfo getFixupKindInfo(
MCFixupKind Kind)
const override {
50 {
"fixup_aarch64_pcrel_adr_imm21", 0, 32, 0},
51 {
"fixup_aarch64_pcrel_adrp_imm21", 0, 32, 0},
52 {
"fixup_aarch64_add_imm12", 10, 12, 0},
53 {
"fixup_aarch64_ldst_imm12_scale1", 10, 12, 0},
54 {
"fixup_aarch64_ldst_imm12_scale2", 10, 12, 0},
55 {
"fixup_aarch64_ldst_imm12_scale4", 10, 12, 0},
56 {
"fixup_aarch64_ldst_imm12_scale8", 10, 12, 0},
57 {
"fixup_aarch64_ldst_imm12_scale16", 10, 12, 0},
58 {
"fixup_aarch64_ldr_pcrel_imm19", 5, 19, 0},
59 {
"fixup_aarch64_movw", 5, 16, 0},
60 {
"fixup_aarch64_pcrel_branch9", 5, 9, 0},
61 {
"fixup_aarch64_pcrel_branch14", 5, 14, 0},
62 {
"fixup_aarch64_pcrel_branch16", 5, 16, 0},
63 {
"fixup_aarch64_pcrel_branch19", 5, 19, 0},
64 {
"fixup_aarch64_pcrel_branch26", 0, 26, 0},
65 {
"fixup_aarch64_pcrel_call26", 0, 26, 0}};
81 void applyFixup(
const MCFragment &,
const MCFixup &,
const MCValue &Target,
82 uint8_t *
Data, uint64_t
Value,
bool IsResolved)
override;
84 bool fixupNeedsRelaxation(
const MCFixup &
Fixup,
85 uint64_t
Value)
const override;
86 bool writeNopData(raw_ostream &OS, uint64_t
Count,
87 const MCSubtargetInfo *STI)
const override;
89 unsigned getFixupKindContainereSizeInBytes(
unsigned Kind)
const;
135 unsigned lo2 =
Value & 0x3;
136 unsigned hi19 = (
Value & 0x1ffffc) >> 2;
137 return (hi19 << 5) | (lo2 << 29);
142 const Triple &TheTriple,
bool IsResolved) {
143 int64_t SignedValue =
static_cast<int64_t
>(
Value);
144 switch (
Fixup.getKind()) {
149 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
155 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
163 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
165 Ctx.reportError(
Fixup.getLoc(),
"fixup not sufficiently aligned");
167 return (
Value >> 2) & 0x7ffff;
174 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
181 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
183 Ctx.reportError(
Fixup.getLoc(),
"fixup must be 2-byte aligned");
190 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
192 Ctx.reportError(
Fixup.getLoc(),
"fixup must be 4-byte aligned");
199 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
201 Ctx.reportError(
Fixup.getLoc(),
"fixup must be 8-byte aligned");
208 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
210 Ctx.reportError(
Fixup.getLoc(),
"fixup must be 16-byte aligned");
219 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
220 Ctx.reportError(
Fixup.getLoc(),
221 "fixup value out of range [-0xFFFF, 0xFFFF]");
225 SignedValue = ~SignedValue;
230 Ctx.reportError(
Fixup.getLoc(),
231 "relocation for a thread-local variable points to an "
239 Ctx.reportError(
Fixup.getLoc(),
"unresolved movw fixup not yet "
249 SignedValue = SignedValue >> 16;
252 SignedValue = SignedValue >> 32;
255 SignedValue = SignedValue >> 48;
282 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
283 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
287 SignedValue = ~SignedValue;
289 }
else if (
Value > 0xFFFF) {
290 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
297 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
300 Ctx.reportError(
Fixup.getLoc(),
"fixup not sufficiently aligned");
301 return (
Value >> 2) & 0x1ff;
305 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
308 Ctx.reportError(
Fixup.getLoc(),
"fixup not sufficiently aligned");
309 return (
Value >> 2) & 0x3fff;
312 SignedValue = -SignedValue;
315 if (SignedValue < 0 || SignedValue > ((1 << 18) - 1))
316 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
319 Ctx.reportError(
Fixup.getLoc(),
"fixup not sufficiently aligned");
320 return (
Value >> 2) & 0xffff;
326 Ctx.reportError(
Fixup.getLoc(),
327 "cannot perform a PC-relative fixup with a non-zero "
332 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
335 Ctx.reportError(
Fixup.getLoc(),
"fixup not sufficiently aligned");
336 return (
Value >> 2) & 0x3ffffff;
347std::optional<MCFixupKind>
348AArch64AsmBackend::getFixupKind(
StringRef Name)
const {
352 unsigned Type = llvm::StringSwitch<unsigned>(Name)
353#define ELF_RELOC(X, Y) .Case(#X, Y)
354#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
356 .Case(
"BFD_RELOC_NONE", ELF::R_AARCH64_NONE)
357 .Case(
"BFD_RELOC_16", ELF::R_AARCH64_ABS16)
358 .Case(
"BFD_RELOC_32", ELF::R_AARCH64_ABS32)
359 .Case(
"BFD_RELOC_64", ELF::R_AARCH64_ABS64)
368unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(
unsigned Kind)
const {
422void AArch64AsmBackend::applyFixup(
const MCFragment &
F,
const MCFixup &
Fixup,
423 const MCValue &Target, uint8_t *
Data,
424 uint64_t
Value,
bool IsResolved) {
427 maybeAddReloc(
F,
Fixup, Target,
Value, IsResolved);
439 "expected relocatable expression");
443 Value = (uint64_t(Expr->getDiscriminator()) << 32) |
444 (uint64_t(Expr->getKey()) << 60) |
445 (uint64_t(Expr->hasAddressDiversity()) << 63);
452 MCFixupKindInfo
Info = getFixupKindInfo(
Fixup.getKind());
454 int64_t SignedValue =
static_cast<int64_t
>(
Value);
462 "Invalid fixup offset!");
465 unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(
Fixup.getKind());
469 if (FulleSizeInBytes == 0) {
471 for (
unsigned i = 0; i != NumBytes; ++i) {
472 Data[i] |= uint8_t((
Value >> (i * 8)) & 0xff);
476 assert(
Fixup.getOffset() + FulleSizeInBytes <=
F.getSize() &&
477 "Invalid fixup size!");
478 assert(NumBytes <= FulleSizeInBytes &&
"Invalid fixup size!");
479 for (
unsigned i = 0; i != NumBytes; ++i) {
480 unsigned Idx = FulleSizeInBytes - 1 - i;
481 Data[Idx] |= uint8_t((
Value >> (i * 8)) & 0xff);
494 Data[3] &= ~(1 << 6);
500bool AArch64AsmBackend::fixupNeedsRelaxation(
const MCFixup &
Fixup,
501 uint64_t
Value)
const {
506 return int64_t(
Value) != int64_t(int8_t(
Value));
509bool AArch64AsmBackend::writeNopData(raw_ostream &OS, uint64_t
Count,
510 const MCSubtargetInfo *STI)
const {
518 for (uint64_t i = 0; i !=
Count; ++i)
519 OS.
write(
"\x1f\x20\x03\xd5", 4);
531 UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
538 UNWIND_ARM64_MODE_DWARF = 0x03000000,
546 UNWIND_ARM64_MODE_FRAME = 0x04000000,
549 UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
550 UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
551 UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
552 UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
553 UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
554 UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
555 UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
556 UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
557 UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
563class DarwinAArch64AsmBackend :
public AArch64AsmBackend {
570 return (StackSize / 16) << 12;
574 DarwinAArch64AsmBackend(
const Target &
T,
const Triple &TT,
575 const MCRegisterInfo &
MRI)
578 std::unique_ptr<MCObjectTargetWriter>
579 createObjectTargetWriter()
const override {
587 uint64_t generateCompactUnwindEncoding(
const MCDwarfFrameInfo *FI,
588 const MCContext *Ctxt)
const override {
591 return CU::UNWIND_ARM64_MODE_FRAMELESS;
592 if (!isDarwinCanonicalPersonality(FI->
Personality) &&
594 return CU::UNWIND_ARM64_MODE_DWARF;
597 uint64_t StackSize = 0;
599 uint64_t CompactUnwindEncoding = 0;
600 int64_t CurOffset = 0;
601 for (
size_t i = 0, e = Instrs.
size(); i != e; ++i) {
602 const MCCFIInstruction &Inst = Instrs[i];
607 return CU::UNWIND_ARM64_MODE_DWARF;
617 if (XReg != AArch64::FP)
618 return CU::UNWIND_ARM64_MODE_DWARF;
621 return CU::UNWIND_ARM64_MODE_DWARF;
623 const MCCFIInstruction &LRPush = Instrs[++i];
625 return CU::UNWIND_ARM64_MODE_DWARF;
626 const MCCFIInstruction &FPPush = Instrs[++i];
628 return CU::UNWIND_ARM64_MODE_DWARF;
631 return CU::UNWIND_ARM64_MODE_DWARF;
634 MCRegister LRReg = *
MRI.getLLVMRegNum(LRPush.
getRegister(),
true);
640 if (LRReg != AArch64::LR ||
FPReg != AArch64::FP)
641 return CU::UNWIND_ARM64_MODE_DWARF;
644 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
650 return CU::UNWIND_ARM64_MODE_DWARF;
659 return CU::UNWIND_ARM64_MODE_DWARF;
661 if (CurOffset != 0 && Inst.
getOffset() != CurOffset - 8)
662 return CU::UNWIND_ARM64_MODE_DWARF;
665 const MCCFIInstruction &Inst2 = Instrs[++i];
667 return CU::UNWIND_ARM64_MODE_DWARF;
671 return CU::UNWIND_ARM64_MODE_DWARF;
685 if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
686 (CompactUnwindEncoding & 0xF1E) == 0)
687 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
688 else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
689 (CompactUnwindEncoding & 0xF1C) == 0)
690 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
691 else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
692 (CompactUnwindEncoding & 0xF18) == 0)
693 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
694 else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
695 (CompactUnwindEncoding & 0xF10) == 0)
696 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
697 else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
698 (CompactUnwindEncoding & 0xF00) == 0)
699 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
708 if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
709 (CompactUnwindEncoding & 0xE00) == 0)
710 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
711 else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
712 (CompactUnwindEncoding & 0xC00) == 0)
713 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
714 else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
715 (CompactUnwindEncoding & 0x800) == 0)
716 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
717 else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
718 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
721 return CU::UNWIND_ARM64_MODE_DWARF;
732 if (StackSize > 65520)
733 return CU::UNWIND_ARM64_MODE_DWARF;
735 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
736 CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
739 return CompactUnwindEncoding;
747class ELFAArch64AsmBackend :
public AArch64AsmBackend {
752 ELFAArch64AsmBackend(
const Target &
T,
const Triple &TT, uint8_t OSABI,
753 bool IsLittleEndian,
bool IsILP32)
754 : AArch64AsmBackend(
T,
TT, IsLittleEndian), OSABI(OSABI),
757 std::unique_ptr<MCObjectTargetWriter>
758 createObjectTargetWriter()
const override {
766class COFFAArch64AsmBackend :
public AArch64AsmBackend {
768 COFFAArch64AsmBackend(
const Target &
T,
const Triple &TheTriple)
769 : AArch64AsmBackend(
T, TheTriple,
true) {}
771 std::unique_ptr<MCObjectTargetWriter>
772 createObjectTargetWriter()
const override {
784 return new DarwinAArch64AsmBackend(
T, TheTriple,
MRI);
788 return new COFFAArch64AsmBackend(
T, TheTriple);
794 return new ELFAArch64AsmBackend(
T, TheTriple, OSABI,
true,
804 "Big endian is only supported for ELF targets!");
807 return new ELFAArch64AsmBackend(
T, TheTriple, OSABI,
false,
unsigned const MachineRegisterInfo * MRI
static unsigned AdrImmBits(unsigned Value)
static unsigned getFixupKindNumBytes(unsigned Kind)
The number of bytes the fixup may change.
static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, uint64_t Value, MCContext &Ctx, const Triple &TheTriple, bool IsResolved)
static bool shouldForceRelocation(const MCFixup &Fixup)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Analysis containing CSE Info
PowerPC TLS Dynamic Call Fixup
static constexpr MCPhysReg FPReg
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
Generic interface to target specific assembler backends.
virtual MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
unsigned getRegister() const
OpType getOperation() const
int64_t getOffset() const
Context object for machine code objects.
LLVM_ABI bool emitCompactUnwindNonCanonical() const
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
StringRef - Represent a constant reference to a string, i.e.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
OSType getOS() const
Get the parsed operating system type of this triple.
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
EnvironmentType getEnvironment() const
Get the parsed environment type of this triple.
LLVM_ABI bool isArch32Bit() const
Test whether the architecture is 32-bit.
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
LLVM Value Representation.
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
raw_ostream & write(unsigned char C)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
CompactUnwindEncodings
Compact unwind encoding values.
Specifier getSymbolLoc(Specifier S)
@ fixup_aarch64_pcrel_branch9
@ fixup_aarch64_pcrel_branch16
@ fixup_aarch64_ldst_imm12_scale4
@ fixup_aarch64_pcrel_call26
@ fixup_aarch64_pcrel_branch26
@ fixup_aarch64_pcrel_branch19
@ fixup_aarch64_ldr_pcrel_imm19
@ fixup_aarch64_pcrel_adr_imm21
@ fixup_aarch64_pcrel_branch14
@ fixup_aarch64_ldst_imm12_scale2
@ fixup_aarch64_ldst_imm12_scale16
@ fixup_aarch64_pcrel_adrp_imm21
@ fixup_aarch64_add_imm12
@ fixup_aarch64_ldst_imm12_scale8
@ fixup_aarch64_ldst_imm12_scale1
Specifier getAddressFrag(Specifier S)
LLVM_ABI Expected< uint32_t > getCPUSubType(const Triple &T)
LLVM_ABI Expected< uint32_t > getCPUType(const Triple &T)
VE::Fixups getFixupKind(uint8_t S)
Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const ArmConfig &ArmCfg)
Apply fixup expression for edge to block content.
bool isRelocation(MCFixupKind FixupKind)
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
std::unique_ptr< MCObjectTargetWriter > createAArch64WinCOFFObjectWriter(const Triple &TheTriple)
uint16_t MCFixupKind
Extensible enumeration to represent the type of a fixup.
MCAsmBackend * createAArch64leAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
FunctionAddr VTableAddr Count
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
@ FK_SecRel_2
A two-byte section relative fixup.
@ FirstLiteralRelocationKind
@ FK_Data_8
A eight-byte fixup.
@ FK_Data_1
A one-byte fixup.
@ FK_Data_4
A four-byte fixup.
@ FK_SecRel_4
A four-byte section relative fixup.
@ FK_Data_2
A two-byte fixup.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
static MCRegister getXRegFromWReg(MCRegister Reg)
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::unique_ptr< MCObjectTargetWriter > createAArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype, bool IsILP32)
MCAsmBackend * createAArch64beAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
static MCRegister getDRegFromBReg(MCRegister Reg)
std::unique_ptr< MCObjectTargetWriter > createAArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32)
const MCSymbol * Personality
std::vector< MCCFIInstruction > Instructions