36 static const unsigned PCRelFlagVal =
42 AArch64AsmBackend(
const Target &
T,
const Triple &TT,
bool IsLittleEndian)
58 {
"fixup_aarch64_pcrel_adr_imm21", 0, 32, PCRelFlagVal},
59 {
"fixup_aarch64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal},
60 {
"fixup_aarch64_add_imm12", 10, 12, 0},
61 {
"fixup_aarch64_ldst_imm12_scale1", 10, 12, 0},
62 {
"fixup_aarch64_ldst_imm12_scale2", 10, 12, 0},
63 {
"fixup_aarch64_ldst_imm12_scale4", 10, 12, 0},
64 {
"fixup_aarch64_ldst_imm12_scale8", 10, 12, 0},
65 {
"fixup_aarch64_ldst_imm12_scale16", 10, 12, 0},
66 {
"fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal},
67 {
"fixup_aarch64_movw", 5, 16, 0},
68 {
"fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal},
69 {
"fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal},
70 {
"fixup_aarch64_pcrel_branch26", 0, 26, PCRelFlagVal},
71 {
"fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal}};
99 unsigned getFixupKindContainereSizeInBytes(
unsigned Kind)
const;
146 unsigned lo2 =
Value & 0x3;
147 unsigned hi19 = (
Value & 0x1ffffc) >> 2;
148 return (hi19 << 5) | (lo2 << 29);
153 const Triple &TheTriple,
bool IsResolved) {
154 int64_t SignedValue =
static_cast<int64_t
>(
Value);
155 switch (
Fixup.getTargetKind()) {
159 if (!isInt<21>(SignedValue))
165 if (!isInt<21>(SignedValue))
173 if (!isInt<21>(SignedValue))
178 return (
Value >> 2) & 0x7ffff;
184 if (!isUInt<12>(
Value))
191 if (!isUInt<13>(
Value))
200 if (!isUInt<14>(
Value))
209 if (!isUInt<15>(
Value))
218 if (!isUInt<16>(
Value))
230 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
232 "fixup value out of range [-0xFFFF, 0xFFFF]");
236 SignedValue = ~SignedValue;
242 "relocation for a thread-local variable points to an "
260 SignedValue = SignedValue >> 16;
263 SignedValue = SignedValue >> 32;
266 SignedValue = SignedValue >> 48;
294 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
299 SignedValue = ~SignedValue;
302 else if (
Value > 0xFFFF) {
309 if (!isInt<16>(SignedValue))
314 return (
Value >> 2) & 0x3fff;
321 "cannot perform a PC-relative fixup with a non-zero "
325 if (!isInt<28>(SignedValue))
330 return (
Value >> 2) & 0x3ffffff;
341std::optional<MCFixupKind>
347#define ELF_RELOC(X, Y) .Case(#X, Y)
348#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
350 .
Case(
"BFD_RELOC_NONE", ELF::R_AARCH64_NONE)
351 .
Case(
"BFD_RELOC_16", ELF::R_AARCH64_ABS16)
352 .
Case(
"BFD_RELOC_32", ELF::R_AARCH64_ABS32)
353 .
Case(
"BFD_RELOC_64", ELF::R_AARCH64_ABS64)
362unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(
unsigned Kind)
const {
406 if (SymLoc == AArch64AuthMCExpr::VK_AUTH ||
407 SymLoc == AArch64AuthMCExpr::VK_AUTHADDR) {
409 const auto *Expr = cast<AArch64AuthMCExpr>(
Fixup.getValue());
412 (
uint64_t(Expr->hasAddressDiversity()) << 63);
424 int64_t SignedValue =
static_cast<int64_t
>(
Value);
435 unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(
Fixup.getKind());
439 if (FulleSizeInBytes == 0) {
441 for (
unsigned i = 0; i != NumBytes; ++i) {
446 assert((
Offset + FulleSizeInBytes) <=
Data.size() &&
"Invalid fixup size!");
447 assert(NumBytes <= FulleSizeInBytes &&
"Invalid fixup size!");
448 for (
unsigned i = 0; i != NumBytes; ++i) {
449 unsigned Idx = FulleSizeInBytes - 1 - i;
469bool AArch64AsmBackend::fixupNeedsRelaxation(
const MCFixup &
Fixup,
477 return int64_t(
Value) != int64_t(int8_t(
Value));
480void AArch64AsmBackend::relaxInstruction(
MCInst &Inst,
494 for (
uint64_t i = 0; i != Count; ++i)
495 OS.
write(
"\x1f\x20\x03\xd5", 4);
499bool AArch64AsmBackend::shouldForceRelocation(
const MCAssembler &Asm,
532 UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
539 UNWIND_ARM64_MODE_DWARF = 0x03000000,
547 UNWIND_ARM64_MODE_FRAME = 0x04000000,
550 UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
551 UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
552 UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
553 UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
554 UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
555 UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
556 UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
557 UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
558 UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
564class DarwinAArch64AsmBackend :
public AArch64AsmBackend {
571 return (StackSize / 16) << 12;
579 std::unique_ptr<MCObjectTargetWriter>
580 createObjectTargetWriter()
const override {
592 return CU::UNWIND_ARM64_MODE_FRAMELESS;
593 if (!isDarwinCanonicalPersonality(FI->
Personality) &&
595 return CU::UNWIND_ARM64_MODE_DWARF;
598 unsigned StackSize = 0;
602 for (
size_t i = 0, e = Instrs.
size(); i != e; ++i) {
608 return CU::UNWIND_ARM64_MODE_DWARF;
618 if (XReg != AArch64::FP)
619 return CU::UNWIND_ARM64_MODE_DWARF;
622 return CU::UNWIND_ARM64_MODE_DWARF;
626 return CU::UNWIND_ARM64_MODE_DWARF;
629 return CU::UNWIND_ARM64_MODE_DWARF;
632 return CU::UNWIND_ARM64_MODE_DWARF;
641 if (LRReg != AArch64::LR || FPReg != AArch64::FP)
642 return CU::UNWIND_ARM64_MODE_DWARF;
645 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
651 return CU::UNWIND_ARM64_MODE_DWARF;
660 return CU::UNWIND_ARM64_MODE_DWARF;
662 if (CurOffset != 0 && Inst.
getOffset() != CurOffset - 8)
663 return CU::UNWIND_ARM64_MODE_DWARF;
668 return CU::UNWIND_ARM64_MODE_DWARF;
672 return CU::UNWIND_ARM64_MODE_DWARF;
686 if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
687 (CompactUnwindEncoding & 0xF1E) == 0)
688 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
689 else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
690 (CompactUnwindEncoding & 0xF1C) == 0)
691 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
692 else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
693 (CompactUnwindEncoding & 0xF18) == 0)
694 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
695 else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
696 (CompactUnwindEncoding & 0xF10) == 0)
697 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
698 else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
699 (CompactUnwindEncoding & 0xF00) == 0)
700 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
709 if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
710 (CompactUnwindEncoding & 0xE00) == 0)
711 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
712 else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
713 (CompactUnwindEncoding & 0xC00) == 0)
714 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
715 else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
716 (CompactUnwindEncoding & 0x800) == 0)
717 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
718 else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
719 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
722 return CU::UNWIND_ARM64_MODE_DWARF;
733 if (StackSize > 65520)
734 return CU::UNWIND_ARM64_MODE_DWARF;
736 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
737 CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
740 return CompactUnwindEncoding;
748class ELFAArch64AsmBackend :
public AArch64AsmBackend {
753 ELFAArch64AsmBackend(
const Target &
T,
const Triple &TT, uint8_t OSABI,
754 bool IsLittleEndian,
bool IsILP32)
755 : AArch64AsmBackend(
T,
TT, IsLittleEndian), OSABI(OSABI),
758 std::unique_ptr<MCObjectTargetWriter>
759 createObjectTargetWriter()
const override {
767class COFFAArch64AsmBackend :
public AArch64AsmBackend {
769 COFFAArch64AsmBackend(
const Target &
T,
const Triple &TheTriple)
770 : AArch64AsmBackend(
T, TheTriple,
true) {}
772 std::unique_ptr<MCObjectTargetWriter>
773 createObjectTargetWriter()
const override {
785 return new DarwinAArch64AsmBackend(
T, TheTriple,
MRI);
789 return new COFFAArch64AsmBackend(
T, TheTriple);
795 return new ELFAArch64AsmBackend(
T, TheTriple, OSABI,
true,
805 "Big endian is only supported for ELF targets!");
808 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)
Analysis containing CSE Info
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
PowerPC TLS Dynamic Call Fixup
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static VariantKind getSymbolLoc(VariantKind Kind)
static VariantKind getAddressFrag(VariantKind Kind)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
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 bool writeNopData(raw_ostream &OS, uint64_t Count, const MCSubtargetInfo *STI) const =0
Write an (optimal) nop sequence of Count bytes to the given output.
virtual void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const
Relax the instruction in the given fragment to the next wider instruction.
virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const =0
Simple predicate for targets where !Resolved implies requiring relaxation.
virtual bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target)
Hook to check if a relocation is needed for some target specific reason.
virtual unsigned getNumFixupKinds() const =0
Get the number of target specific fixup kinds.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
virtual std::optional< MCFixupKind > getFixupKind(StringRef Name) const
Map a relocation name used in .reloc to a fixup kind.
virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef< char > Data, uint64_t Value, bool IsResolved, const MCSubtargetInfo *STI) const =0
Apply the Value for given Fixup into the provided data fragment, at the offset specified by the fixup...
Encapsulates the layout of an assembly file at a particular point in time.
unsigned getRegister() const
OpType getOperation() const
Context object for machine code objects.
bool emitCompactUnwindNonCanonical() const
void reportError(SMLoc L, const Twine &Msg)
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Instances of this class represent a single low-level machine instruction.
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...
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
This represents an "assembler immediate".
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
StringRef - Represent a constant reference to a string, i.e.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
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.
bool isArch32Bit() const
Test whether the architecture is 32-bit.
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
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.
@ 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
Expected< uint32_t > getCPUSubType(const Triple &T)
Expected< uint32_t > getCPUType(const Triple &T)
This is an optimization pass for GlobalISel generic memory operations.
std::unique_ptr< MCObjectTargetWriter > createAArch64WinCOFFObjectWriter(const Triple &TheTriple)
static unsigned getXRegFromWReg(unsigned Reg)
MCAsmBackend * createAArch64leAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
static unsigned getDRegFromBReg(unsigned Reg)
MCFixupKind
Extensible enumeration to represent the type of a fixup.
@ FK_SecRel_2
A two-byte section relative fixup.
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
@ 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.
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)
std::unique_ptr< MCObjectTargetWriter > createAArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32)
const MCSymbol * Personality
std::vector< MCCFIInstruction > Instructions
Target independent information on a fixup kind.
@ FKF_IsAlignedDownTo32Bits
Should this fixup kind force a 4-byte aligned effective PC value?
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...