33 static const unsigned PCRelFlagVal =
39 AArch64AsmBackend(
const Target &
T,
const Triple &TT,
bool IsLittleEndian)
56 {
"fixup_aarch64_pcrel_adr_imm21", 0, 32, PCRelFlagVal},
57 {
"fixup_aarch64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal},
58 {
"fixup_aarch64_add_imm12", 10, 12, 0},
59 {
"fixup_aarch64_ldst_imm12_scale1", 10, 12, 0},
60 {
"fixup_aarch64_ldst_imm12_scale2", 10, 12, 0},
61 {
"fixup_aarch64_ldst_imm12_scale4", 10, 12, 0},
62 {
"fixup_aarch64_ldst_imm12_scale8", 10, 12, 0},
63 {
"fixup_aarch64_ldst_imm12_scale16", 10, 12, 0},
64 {
"fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal},
65 {
"fixup_aarch64_movw", 5, 16, 0},
66 {
"fixup_aarch64_pcrel_branch9", 5, 9, PCRelFlagVal},
67 {
"fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal},
68 {
"fixup_aarch64_pcrel_branch16", 5, 16, 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}};
98 unsigned getFixupKindContainereSizeInBytes(
unsigned Kind)
const;
148 unsigned lo2 =
Value & 0x3;
149 unsigned hi19 = (
Value & 0x1ffffc) >> 2;
150 return (hi19 << 5) | (lo2 << 29);
155 const Triple &TheTriple,
bool IsResolved) {
156 int64_t SignedValue =
static_cast<int64_t
>(
Value);
157 switch (
Fixup.getTargetKind()) {
161 if (!isInt<21>(SignedValue))
167 if (!isInt<21>(SignedValue))
175 if (!isInt<21>(SignedValue))
180 return (
Value >> 2) & 0x7ffff;
186 if (!isUInt<12>(
Value))
193 if (!isUInt<13>(
Value))
202 if (!isUInt<14>(
Value))
211 if (!isUInt<15>(
Value))
220 if (!isUInt<16>(
Value))
232 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
234 "fixup value out of range [-0xFFFF, 0xFFFF]");
238 SignedValue = ~SignedValue;
244 "relocation for a thread-local variable points to an "
262 SignedValue = SignedValue >> 16;
265 SignedValue = SignedValue >> 32;
268 SignedValue = SignedValue >> 48;
296 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
301 SignedValue = ~SignedValue;
304 else if (
Value > 0xFFFF) {
311 if (!isInt<11>(SignedValue))
316 return (
Value >> 2) & 0x1ff;
319 if (!isInt<16>(SignedValue))
324 return (
Value >> 2) & 0x3fff;
327 SignedValue = -SignedValue;
330 if (SignedValue < 0 || SignedValue > ((1 << 18) - 1))
335 return (
Value >> 2) & 0xffff;
342 "cannot perform a PC-relative fixup with a non-zero "
346 if (!isInt<28>(SignedValue))
351 return (
Value >> 2) & 0x3ffffff;
362std::optional<MCFixupKind>
368#define ELF_RELOC(X, Y) .Case(#X, Y)
369#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
371 .
Case(
"BFD_RELOC_NONE", ELF::R_AARCH64_NONE)
372 .
Case(
"BFD_RELOC_16", ELF::R_AARCH64_ABS16)
373 .
Case(
"BFD_RELOC_32", ELF::R_AARCH64_ABS32)
374 .
Case(
"BFD_RELOC_64", ELF::R_AARCH64_ABS64)
383unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(
unsigned Kind)
const {
429 if (SymLoc == AArch64AuthMCExpr::VK_AUTH ||
430 SymLoc == AArch64AuthMCExpr::VK_AUTHADDR) {
432 const auto *Expr = cast<AArch64AuthMCExpr>(
Fixup.getValue());
435 (
uint64_t(Expr->hasAddressDiversity()) << 63);
447 int64_t SignedValue =
static_cast<int64_t
>(
Value);
455 assert(
Offset + NumBytes <= Data.size() &&
"Invalid fixup offset!");
458 unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(
Fixup.getKind());
462 if (FulleSizeInBytes == 0) {
464 for (
unsigned i = 0; i != NumBytes; ++i) {
469 assert((
Offset + FulleSizeInBytes) <= Data.size() &&
"Invalid fixup size!");
470 assert(NumBytes <= FulleSizeInBytes &&
"Invalid fixup size!");
471 for (
unsigned i = 0; i != NumBytes; ++i) {
472 unsigned Idx = FulleSizeInBytes - 1 - i;
486 Data[
Offset + 3] &= ~(1 << 6);
488 Data[
Offset + 3] |= (1 << 6);
492bool AArch64AsmBackend::fixupNeedsRelaxation(
const MCFixup &
Fixup,
498 return int64_t(
Value) != int64_t(int8_t(
Value));
501void AArch64AsmBackend::relaxInstruction(
MCInst &Inst,
515 for (
uint64_t i = 0; i != Count; ++i)
516 OS.
write(
"\x1f\x20\x03\xd5", 4);
520bool AArch64AsmBackend::shouldForceRelocation(
const MCAssembler &Asm,
554 UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
561 UNWIND_ARM64_MODE_DWARF = 0x03000000,
569 UNWIND_ARM64_MODE_FRAME = 0x04000000,
572 UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
573 UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
574 UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
575 UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
576 UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
577 UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
578 UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
579 UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
580 UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
586class DarwinAArch64AsmBackend :
public AArch64AsmBackend {
593 return (StackSize / 16) << 12;
601 std::unique_ptr<MCObjectTargetWriter>
602 createObjectTargetWriter()
const override {
614 return CU::UNWIND_ARM64_MODE_FRAMELESS;
615 if (!isDarwinCanonicalPersonality(FI->
Personality) &&
617 return CU::UNWIND_ARM64_MODE_DWARF;
623 int64_t CurOffset = 0;
624 for (
size_t i = 0, e = Instrs.
size(); i != e; ++i) {
630 return CU::UNWIND_ARM64_MODE_DWARF;
640 if (XReg != AArch64::FP)
641 return CU::UNWIND_ARM64_MODE_DWARF;
644 return CU::UNWIND_ARM64_MODE_DWARF;
648 return CU::UNWIND_ARM64_MODE_DWARF;
651 return CU::UNWIND_ARM64_MODE_DWARF;
654 return CU::UNWIND_ARM64_MODE_DWARF;
663 if (LRReg != AArch64::LR ||
FPReg != AArch64::FP)
664 return CU::UNWIND_ARM64_MODE_DWARF;
667 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
673 return CU::UNWIND_ARM64_MODE_DWARF;
682 return CU::UNWIND_ARM64_MODE_DWARF;
684 if (CurOffset != 0 && Inst.
getOffset() != CurOffset - 8)
685 return CU::UNWIND_ARM64_MODE_DWARF;
690 return CU::UNWIND_ARM64_MODE_DWARF;
694 return CU::UNWIND_ARM64_MODE_DWARF;
708 if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
709 (CompactUnwindEncoding & 0xF1E) == 0)
710 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
711 else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
712 (CompactUnwindEncoding & 0xF1C) == 0)
713 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
714 else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
715 (CompactUnwindEncoding & 0xF18) == 0)
716 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
717 else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
718 (CompactUnwindEncoding & 0xF10) == 0)
719 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
720 else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
721 (CompactUnwindEncoding & 0xF00) == 0)
722 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
731 if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
732 (CompactUnwindEncoding & 0xE00) == 0)
733 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
734 else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
735 (CompactUnwindEncoding & 0xC00) == 0)
736 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
737 else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
738 (CompactUnwindEncoding & 0x800) == 0)
739 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
740 else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
741 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
744 return CU::UNWIND_ARM64_MODE_DWARF;
755 if (StackSize > 65520)
756 return CU::UNWIND_ARM64_MODE_DWARF;
758 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
759 CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
762 return CompactUnwindEncoding;
770class ELFAArch64AsmBackend :
public AArch64AsmBackend {
776 bool IsLittleEndian,
bool IsILP32)
777 : AArch64AsmBackend(
T,
TT, IsLittleEndian), OSABI(OSABI),
780 std::unique_ptr<MCObjectTargetWriter>
781 createObjectTargetWriter()
const override {
789class COFFAArch64AsmBackend :
public AArch64AsmBackend {
791 COFFAArch64AsmBackend(
const Target &
T,
const Triple &TheTriple)
792 : AArch64AsmBackend(
T, TheTriple,
true) {}
794 std::unique_ptr<MCObjectTargetWriter>
795 createObjectTargetWriter()
const override {
807 return new DarwinAArch64AsmBackend(
T, TheTriple,
MRI);
811 return new COFFAArch64AsmBackend(
T, TheTriple);
817 return new ELFAArch64AsmBackend(
T, TheTriple, OSABI,
true,
827 "Big endian is only supported for ELF targets!");
830 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
PowerPC TLS Dynamic Call Fixup
static constexpr Register FPReg
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
Simple predicate for targets where !Resolved implies requiring relaxation.
virtual bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, const MCSubtargetInfo *STI)
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...
unsigned getRegister() const
OpType getOperation() const
int64_t getOffset() 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...
Wrapper class representing physical registers. Should be passed by value.
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_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
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)
MCAsmBackend * createAArch64leAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
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.
static MCRegister getXRegFromWReg(MCRegister Reg)
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
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...