35 static const unsigned PCRelFlagVal =
41 AArch64AsmBackend(
const Target &
T,
const Triple &TT,
bool IsLittleEndian)
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}};
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;
333std::optional<MCFixupKind>
339#define ELF_RELOC(X, Y) .Case(#X, Y)
340#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
342 .
Case(
"BFD_RELOC_NONE", ELF::R_AARCH64_NONE)
343 .
Case(
"BFD_RELOC_16", ELF::R_AARCH64_ABS16)
344 .
Case(
"BFD_RELOC_32", ELF::R_AARCH64_ABS32)
345 .
Case(
"BFD_RELOC_64", ELF::R_AARCH64_ABS64)
354unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(
unsigned Kind)
const {
403 int64_t SignedValue =
static_cast<int64_t
>(
Value);
414 unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(
Fixup.getKind());
418 if (FulleSizeInBytes == 0) {
420 for (
unsigned i = 0; i != NumBytes; ++i) {
425 assert((
Offset + FulleSizeInBytes) <=
Data.size() &&
"Invalid fixup size!");
426 assert(NumBytes <= FulleSizeInBytes &&
"Invalid fixup size!");
427 for (
unsigned i = 0; i != NumBytes; ++i) {
428 unsigned Idx = FulleSizeInBytes - 1 - i;
448bool AArch64AsmBackend::fixupNeedsRelaxation(
const MCFixup &
Fixup,
456 return int64_t(
Value) != int64_t(int8_t(
Value));
459void AArch64AsmBackend::relaxInstruction(
MCInst &Inst,
473 for (
uint64_t i = 0; i != Count; ++i)
474 OS.
write(
"\x1f\x20\x03\xd5", 4);
478bool AArch64AsmBackend::shouldForceRelocation(
const MCAssembler &Asm,
511 UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
518 UNWIND_ARM64_MODE_DWARF = 0x03000000,
526 UNWIND_ARM64_MODE_FRAME = 0x04000000,
529 UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
530 UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
531 UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
532 UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
533 UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
534 UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
535 UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
536 UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
537 UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
543class DarwinAArch64AsmBackend :
public AArch64AsmBackend {
550 return (StackSize / 16) << 12;
558 std::unique_ptr<MCObjectTargetWriter>
559 createObjectTargetWriter()
const override {
567 uint32_t generateCompactUnwindEncoding(
570 return CU::UNWIND_ARM64_MODE_FRAMELESS;
573 unsigned StackSize = 0;
577 for (
size_t i = 0, e = Instrs.
size(); i != e; ++i) {
583 return CU::UNWIND_ARM64_MODE_DWARF;
593 if (XReg != AArch64::FP)
594 return CU::UNWIND_ARM64_MODE_DWARF;
597 return CU::UNWIND_ARM64_MODE_DWARF;
601 return CU::UNWIND_ARM64_MODE_DWARF;
604 return CU::UNWIND_ARM64_MODE_DWARF;
607 return CU::UNWIND_ARM64_MODE_DWARF;
616 if (LRReg != AArch64::LR || FPReg != AArch64::FP)
617 return CU::UNWIND_ARM64_MODE_DWARF;
620 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
626 return CU::UNWIND_ARM64_MODE_DWARF;
635 return CU::UNWIND_ARM64_MODE_DWARF;
637 if (CurOffset != 0 && Inst.
getOffset() != CurOffset - 8)
638 return CU::UNWIND_ARM64_MODE_DWARF;
643 return CU::UNWIND_ARM64_MODE_DWARF;
647 return CU::UNWIND_ARM64_MODE_DWARF;
661 if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
662 (CompactUnwindEncoding & 0xF1E) == 0)
663 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
664 else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
665 (CompactUnwindEncoding & 0xF1C) == 0)
666 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
667 else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
668 (CompactUnwindEncoding & 0xF18) == 0)
669 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
670 else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
671 (CompactUnwindEncoding & 0xF10) == 0)
672 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
673 else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
674 (CompactUnwindEncoding & 0xF00) == 0)
675 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
684 if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
685 (CompactUnwindEncoding & 0xE00) == 0)
686 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
687 else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
688 (CompactUnwindEncoding & 0xC00) == 0)
689 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
690 else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
691 (CompactUnwindEncoding & 0x800) == 0)
692 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
693 else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
694 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
697 return CU::UNWIND_ARM64_MODE_DWARF;
708 if (StackSize > 65520)
709 return CU::UNWIND_ARM64_MODE_DWARF;
711 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
712 CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
715 return CompactUnwindEncoding;
723class ELFAArch64AsmBackend :
public AArch64AsmBackend {
728 ELFAArch64AsmBackend(
const Target &
T,
const Triple &TT, uint8_t OSABI,
729 bool IsLittleEndian,
bool IsILP32)
730 : AArch64AsmBackend(
T,
TT, IsLittleEndian), OSABI(OSABI),
733 std::unique_ptr<MCObjectTargetWriter>
734 createObjectTargetWriter()
const override {
742class COFFAArch64AsmBackend :
public AArch64AsmBackend {
744 COFFAArch64AsmBackend(
const Target &
T,
const Triple &TheTriple)
745 : AArch64AsmBackend(
T, TheTriple,
true) {}
747 std::unique_ptr<MCObjectTargetWriter>
748 createObjectTargetWriter()
const override {
760 return new DarwinAArch64AsmBackend(
T, TheTriple,
MRI);
764 return new COFFAArch64AsmBackend(
T, TheTriple);
770 return new ELFAArch64AsmBackend(
T, TheTriple, OSABI,
true,
780 "Big endian is only supported for ELF targets!");
783 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.
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)
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...