36 static const unsigned PCRelFlagVal =
42 AArch64AsmBackend(
const Target &
T,
const Triple &TT,
bool IsLittleEndian)
59 {
"fixup_aarch64_pcrel_adr_imm21", 0, 32, PCRelFlagVal},
60 {
"fixup_aarch64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal},
61 {
"fixup_aarch64_add_imm12", 10, 12, 0},
62 {
"fixup_aarch64_ldst_imm12_scale1", 10, 12, 0},
63 {
"fixup_aarch64_ldst_imm12_scale2", 10, 12, 0},
64 {
"fixup_aarch64_ldst_imm12_scale4", 10, 12, 0},
65 {
"fixup_aarch64_ldst_imm12_scale8", 10, 12, 0},
66 {
"fixup_aarch64_ldst_imm12_scale16", 10, 12, 0},
67 {
"fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal},
68 {
"fixup_aarch64_movw", 5, 16, 0},
69 {
"fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal},
70 {
"fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal},
71 {
"fixup_aarch64_pcrel_branch26", 0, 26, PCRelFlagVal},
72 {
"fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal}};
100 unsigned getFixupKindContainereSizeInBytes(
unsigned Kind)
const;
147 unsigned lo2 =
Value & 0x3;
148 unsigned hi19 = (
Value & 0x1ffffc) >> 2;
149 return (hi19 << 5) | (lo2 << 29);
154 const Triple &TheTriple,
bool IsResolved) {
155 int64_t SignedValue =
static_cast<int64_t
>(
Value);
156 switch (
Fixup.getTargetKind()) {
160 if (!isInt<21>(SignedValue))
166 if (!isInt<21>(SignedValue))
174 if (!isInt<21>(SignedValue))
179 return (
Value >> 2) & 0x7ffff;
185 if (!isUInt<12>(
Value))
192 if (!isUInt<13>(
Value))
201 if (!isUInt<14>(
Value))
210 if (!isUInt<15>(
Value))
219 if (!isUInt<16>(
Value))
231 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
233 "fixup value out of range [-0xFFFF, 0xFFFF]");
237 SignedValue = ~SignedValue;
243 "relocation for a thread-local variable points to an "
261 SignedValue = SignedValue >> 16;
264 SignedValue = SignedValue >> 32;
267 SignedValue = SignedValue >> 48;
295 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
300 SignedValue = ~SignedValue;
303 else if (
Value > 0xFFFF) {
310 if (!isInt<16>(SignedValue))
315 return (
Value >> 2) & 0x3fff;
322 "cannot perform a PC-relative fixup with a non-zero "
326 if (!isInt<28>(SignedValue))
331 return (
Value >> 2) & 0x3ffffff;
342std::optional<MCFixupKind>
348#define ELF_RELOC(X, Y) .Case(#X, Y)
349#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
351 .
Case(
"BFD_RELOC_NONE", ELF::R_AARCH64_NONE)
352 .
Case(
"BFD_RELOC_16", ELF::R_AARCH64_ABS16)
353 .
Case(
"BFD_RELOC_32", ELF::R_AARCH64_ABS32)
354 .
Case(
"BFD_RELOC_64", ELF::R_AARCH64_ABS64)
363unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(
unsigned Kind)
const {
407 if (SymLoc == AArch64AuthMCExpr::VK_AUTH ||
408 SymLoc == AArch64AuthMCExpr::VK_AUTHADDR) {
410 const auto *Expr = cast<AArch64AuthMCExpr>(
Fixup.getValue());
413 (
uint64_t(Expr->hasAddressDiversity()) << 63);
425 int64_t SignedValue =
static_cast<int64_t
>(
Value);
433 assert(
Offset + NumBytes <= Data.size() &&
"Invalid fixup offset!");
436 unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(
Fixup.getKind());
440 if (FulleSizeInBytes == 0) {
442 for (
unsigned i = 0; i != NumBytes; ++i) {
443 Data[
Offset + i] |= uint8_t((
Value >> (i * 8)) & 0xff);
447 assert((
Offset + FulleSizeInBytes) <= Data.size() &&
"Invalid fixup size!");
448 assert(NumBytes <= FulleSizeInBytes &&
"Invalid fixup size!");
449 for (
unsigned i = 0; i != NumBytes; ++i) {
450 unsigned Idx = FulleSizeInBytes - 1 - i;
464 Data[
Offset + 3] &= ~(1 << 6);
466 Data[
Offset + 3] |= (1 << 6);
470bool AArch64AsmBackend::fixupNeedsRelaxation(
const MCFixup &
Fixup,
478 return int64_t(
Value) != int64_t(int8_t(
Value));
481void AArch64AsmBackend::relaxInstruction(
MCInst &Inst,
495 for (
uint64_t i = 0; i != Count; ++i)
496 OS.
write(
"\x1f\x20\x03\xd5", 4);
500bool AArch64AsmBackend::shouldForceRelocation(
const MCAssembler &Asm,
533 UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
540 UNWIND_ARM64_MODE_DWARF = 0x03000000,
548 UNWIND_ARM64_MODE_FRAME = 0x04000000,
551 UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
552 UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
553 UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
554 UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
555 UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
556 UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
557 UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
558 UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
559 UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
565class DarwinAArch64AsmBackend :
public AArch64AsmBackend {
572 return (StackSize / 16) << 12;
580 std::unique_ptr<MCObjectTargetWriter>
581 createObjectTargetWriter()
const override {
593 return CU::UNWIND_ARM64_MODE_FRAMELESS;
594 if (!isDarwinCanonicalPersonality(FI->
Personality) &&
596 return CU::UNWIND_ARM64_MODE_DWARF;
599 unsigned StackSize = 0;
603 for (
size_t i = 0, e = Instrs.
size(); i != e; ++i) {
609 return CU::UNWIND_ARM64_MODE_DWARF;
619 if (XReg != AArch64::FP)
620 return CU::UNWIND_ARM64_MODE_DWARF;
623 return CU::UNWIND_ARM64_MODE_DWARF;
627 return CU::UNWIND_ARM64_MODE_DWARF;
630 return CU::UNWIND_ARM64_MODE_DWARF;
633 return CU::UNWIND_ARM64_MODE_DWARF;
642 if (LRReg != AArch64::LR || FPReg != AArch64::FP)
643 return CU::UNWIND_ARM64_MODE_DWARF;
646 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
652 return CU::UNWIND_ARM64_MODE_DWARF;
661 return CU::UNWIND_ARM64_MODE_DWARF;
663 if (CurOffset != 0 && Inst.
getOffset() != CurOffset - 8)
664 return CU::UNWIND_ARM64_MODE_DWARF;
669 return CU::UNWIND_ARM64_MODE_DWARF;
673 return CU::UNWIND_ARM64_MODE_DWARF;
687 if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
688 (CompactUnwindEncoding & 0xF1E) == 0)
689 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
690 else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
691 (CompactUnwindEncoding & 0xF1C) == 0)
692 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
693 else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
694 (CompactUnwindEncoding & 0xF18) == 0)
695 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
696 else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
697 (CompactUnwindEncoding & 0xF10) == 0)
698 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
699 else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
700 (CompactUnwindEncoding & 0xF00) == 0)
701 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
710 if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
711 (CompactUnwindEncoding & 0xE00) == 0)
712 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
713 else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
714 (CompactUnwindEncoding & 0xC00) == 0)
715 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
716 else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
717 (CompactUnwindEncoding & 0x800) == 0)
718 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
719 else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
720 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
723 return CU::UNWIND_ARM64_MODE_DWARF;
734 if (StackSize > 65520)
735 return CU::UNWIND_ARM64_MODE_DWARF;
737 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
738 CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
741 return CompactUnwindEncoding;
749class ELFAArch64AsmBackend :
public AArch64AsmBackend {
754 ELFAArch64AsmBackend(
const Target &
T,
const Triple &TT, uint8_t OSABI,
755 bool IsLittleEndian,
bool IsILP32)
756 : AArch64AsmBackend(
T,
TT, IsLittleEndian), OSABI(OSABI),
759 std::unique_ptr<MCObjectTargetWriter>
760 createObjectTargetWriter()
const override {
768class COFFAArch64AsmBackend :
public AArch64AsmBackend {
770 COFFAArch64AsmBackend(
const Target &
T,
const Triple &TheTriple)
771 : AArch64AsmBackend(
T, TheTriple,
true) {}
773 std::unique_ptr<MCObjectTargetWriter>
774 createObjectTargetWriter()
const override {
786 return new DarwinAArch64AsmBackend(
T, TheTriple,
MRI);
790 return new COFFAArch64AsmBackend(
T, TheTriple);
796 return new ELFAArch64AsmBackend(
T, TheTriple, OSABI,
true,
806 "Big endian is only supported for ELF targets!");
809 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...