37 AArch64AsmBackend(
const Target &
T,
const Triple &TT,
bool IsLittleEndian)
43 std::optional<MCFixupKind>
getFixupKind(StringRef Name)
const override;
45 MCFixupKindInfo getFixupKindInfo(
MCFixupKind Kind)
const override {
51 {
"fixup_aarch64_pcrel_adr_imm21", 0, 32, 0},
52 {
"fixup_aarch64_pcrel_adrp_imm21", 0, 32, 0},
53 {
"fixup_aarch64_add_imm12", 10, 12, 0},
54 {
"fixup_aarch64_ldst_imm12_scale1", 10, 12, 0},
55 {
"fixup_aarch64_ldst_imm12_scale2", 10, 12, 0},
56 {
"fixup_aarch64_ldst_imm12_scale4", 10, 12, 0},
57 {
"fixup_aarch64_ldst_imm12_scale8", 10, 12, 0},
58 {
"fixup_aarch64_ldst_imm12_scale16", 10, 12, 0},
59 {
"fixup_aarch64_ldr_pcrel_imm19", 5, 19, 0},
60 {
"fixup_aarch64_movw", 5, 16, 0},
61 {
"fixup_aarch64_pcrel_branch9", 5, 9, 0},
62 {
"fixup_aarch64_pcrel_branch14", 5, 14, 0},
63 {
"fixup_aarch64_pcrel_branch16", 5, 16, 0},
64 {
"fixup_aarch64_pcrel_branch19", 5, 19, 0},
65 {
"fixup_aarch64_pcrel_branch26", 0, 26, 0},
66 {
"fixup_aarch64_pcrel_call26", 0, 26, 0}};
82 void applyFixup(
const MCFragment &,
const MCFixup &,
const MCValue &Target,
86 const MCSubtargetInfo *STI)
const override;
88 unsigned getFixupKindContainereSizeInBytes(
unsigned Kind)
const;
134 unsigned lo2 =
Value & 0x3;
135 unsigned hi19 = (
Value & 0x1ffffc) >> 2;
136 return (hi19 << 5) | (lo2 << 29);
141 const Triple &TheTriple,
bool IsResolved) {
142 int64_t SignedValue =
static_cast<int64_t
>(
Value);
143 switch (
Fixup.getKind()) {
148 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
154 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
162 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
164 Ctx.reportError(
Fixup.getLoc(),
"fixup not sufficiently aligned");
166 return (
Value >> 2) & 0x7ffff;
173 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
180 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
182 Ctx.reportError(
Fixup.getLoc(),
"fixup must be 2-byte aligned");
189 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
191 Ctx.reportError(
Fixup.getLoc(),
"fixup must be 4-byte aligned");
198 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
200 Ctx.reportError(
Fixup.getLoc(),
"fixup must be 8-byte aligned");
207 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
209 Ctx.reportError(
Fixup.getLoc(),
"fixup must be 16-byte aligned");
218 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
219 Ctx.reportError(
Fixup.getLoc(),
220 "fixup value out of range [-0xFFFF, 0xFFFF]");
224 SignedValue = ~SignedValue;
229 Ctx.reportError(
Fixup.getLoc(),
230 "relocation for a thread-local variable points to an "
238 Ctx.reportError(
Fixup.getLoc(),
"unresolved movw fixup not yet "
248 SignedValue = SignedValue >> 16;
251 SignedValue = SignedValue >> 32;
254 SignedValue = SignedValue >> 48;
281 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
282 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
286 SignedValue = ~SignedValue;
288 }
else if (
Value > 0xFFFF) {
289 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
296 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
299 Ctx.reportError(
Fixup.getLoc(),
"fixup not sufficiently aligned");
300 return (
Value >> 2) & 0x1ff;
304 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
307 Ctx.reportError(
Fixup.getLoc(),
"fixup not sufficiently aligned");
308 return (
Value >> 2) & 0x3fff;
311 SignedValue = -SignedValue;
314 if (SignedValue < 0 || SignedValue > ((1 << 18) - 1))
315 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
318 Ctx.reportError(
Fixup.getLoc(),
"fixup not sufficiently aligned");
319 return (
Value >> 2) & 0xffff;
325 Ctx.reportError(
Fixup.getLoc(),
326 "cannot perform a PC-relative fixup with a non-zero "
331 Ctx.reportError(
Fixup.getLoc(),
"fixup value out of range");
334 Ctx.reportError(
Fixup.getLoc(),
"fixup not sufficiently aligned");
335 return (
Value >> 2) & 0x3ffffff;
346std::optional<MCFixupKind>
347AArch64AsmBackend::getFixupKind(
StringRef Name)
const {
351 constexpr llvm::EnumStringDef<uint16_t> TypesDefs[] = {
352#define ELF_RELOC(X, Y) {{#X}, Y},
353#include "llvm/BinaryFormat/ELFRelocs/AArch64.def"
355 {{
"BFD_RELOC_NONE"}, ELF::R_AARCH64_NONE},
356 {{
"BFD_RELOC_16"}, ELF::R_AARCH64_ABS16},
357 {{
"BFD_RELOC_32"}, ELF::R_AARCH64_ABS32},
358 {{
"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,
427 maybeAddReloc(
F,
Fixup, Target,
Value, IsResolved);
439 "expected relocatable expression");
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;
494 Data[3] &= ~(1 << 6);
500bool AArch64AsmBackend::writeNopData(raw_ostream &OS,
uint64_t Count,
501 const MCSubtargetInfo *STI)
const {
510 OS.
write(
"\x1f\x20\x03\xd5", 4);
522 UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
529 UNWIND_ARM64_MODE_DWARF = 0x03000000,
537 UNWIND_ARM64_MODE_FRAME = 0x04000000,
540 UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
541 UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
542 UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
543 UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
544 UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
545 UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
546 UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
547 UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
548 UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
554class DarwinAArch64AsmBackend :
public AArch64AsmBackend {
561 return (StackSize / 16) << 12;
565 DarwinAArch64AsmBackend(
const Target &
T,
const Triple &TT,
566 const MCRegisterInfo &
MRI)
569 std::unique_ptr<MCObjectTargetWriter>
570 createObjectTargetWriter()
const override {
578 uint64_t generateCompactUnwindEncoding(
const MCDwarfFrameInfo *FI,
579 const MCContext *Ctxt)
const override {
581 return CU::UNWIND_ARM64_MODE_DWARF;
586 return CU::UNWIND_ARM64_MODE_DWARF;
590 return CU::UNWIND_ARM64_MODE_DWARF;
594 return CU::UNWIND_ARM64_MODE_FRAMELESS;
595 if (!isDarwinCanonicalPersonality(FI->
Personality) &&
597 return CU::UNWIND_ARM64_MODE_DWARF;
603 int64_t CurOffset = 0;
604 for (
size_t i = 0, e = Instrs.
size(); i != e; ++i) {
605 const MCCFIInstruction &Inst = Instrs[i];
610 return CU::UNWIND_ARM64_MODE_DWARF;
620 if (XReg != AArch64::FP)
621 return CU::UNWIND_ARM64_MODE_DWARF;
624 return CU::UNWIND_ARM64_MODE_DWARF;
626 const MCCFIInstruction &LRPush = Instrs[++i];
628 return CU::UNWIND_ARM64_MODE_DWARF;
629 const MCCFIInstruction &FPPush = Instrs[++i];
631 return CU::UNWIND_ARM64_MODE_DWARF;
634 return CU::UNWIND_ARM64_MODE_DWARF;
637 MCRegister LRReg = *
MRI.getLLVMRegNum(LRPush.
getRegister(),
true);
643 if (LRReg != AArch64::LR ||
FPReg != AArch64::FP)
644 return CU::UNWIND_ARM64_MODE_DWARF;
647 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
653 return CU::UNWIND_ARM64_MODE_DWARF;
662 return CU::UNWIND_ARM64_MODE_DWARF;
664 if (CurOffset != 0 && Inst.
getOffset() != CurOffset - 8)
665 return CU::UNWIND_ARM64_MODE_DWARF;
668 const MCCFIInstruction &Inst2 = Instrs[++i];
670 return CU::UNWIND_ARM64_MODE_DWARF;
674 return CU::UNWIND_ARM64_MODE_DWARF;
688 if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
689 (CompactUnwindEncoding & 0xF1E) == 0)
690 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
691 else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
692 (CompactUnwindEncoding & 0xF1C) == 0)
693 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
694 else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
695 (CompactUnwindEncoding & 0xF18) == 0)
696 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
697 else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
698 (CompactUnwindEncoding & 0xF10) == 0)
699 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
700 else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
701 (CompactUnwindEncoding & 0xF00) == 0)
702 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
711 if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
712 (CompactUnwindEncoding & 0xE00) == 0)
713 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
714 else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
715 (CompactUnwindEncoding & 0xC00) == 0)
716 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
717 else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
718 (CompactUnwindEncoding & 0x800) == 0)
719 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
720 else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
721 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
724 return CU::UNWIND_ARM64_MODE_DWARF;
731 return CU::UNWIND_ARM64_MODE_DWARF;
738 if (StackSize > 65520)
739 return CU::UNWIND_ARM64_MODE_DWARF;
741 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
742 CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
745 return CompactUnwindEncoding;
753class ELFAArch64AsmBackend :
public AArch64AsmBackend {
758 ELFAArch64AsmBackend(
const Target &
T,
const Triple &TT, uint8_t OSABI,
759 bool IsLittleEndian,
bool IsILP32)
760 : AArch64AsmBackend(
T,
TT, IsLittleEndian), OSABI(OSABI),
763 std::unique_ptr<MCObjectTargetWriter>
764 createObjectTargetWriter()
const override {
772class COFFAArch64AsmBackend :
public AArch64AsmBackend {
774 COFFAArch64AsmBackend(
const Target &
T,
const Triple &TheTriple)
775 : AArch64AsmBackend(
T, TheTriple,
true) {}
777 std::unique_ptr<MCObjectTargetWriter>
778 createObjectTargetWriter()
const override {
790 return new DarwinAArch64AsmBackend(
T, TheTriple,
MRI);
794 return new COFFAArch64AsmBackend(
T, TheTriple);
800 return new ELFAArch64AsmBackend(
T, TheTriple, OSABI,
true,
810 "Big endian is only supported for ELF targets!");
813 return new ELFAArch64AsmBackend(
T, TheTriple, OSABI,
false,
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!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define BUILD_ENUM_STRINGS(Tab)
PowerPC TLS Dynamic Call Fixup
static constexpr MCPhysReg FPReg
MachineRegisterInfo & MRI
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
size_t size() const
Get the array size.
bool empty() const
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
LLVM_ABI EmitDwarfUnwindType emitDwarfUnwindInfo() 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
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 std::error_code fromString(StringRef String, Metadata &HSAMetadata)
Converts String to HSAMetadata.
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)
This is an optimization pass for GlobalISel generic memory operations.
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)
EnumStrings(const EnumStringsStorage< T, NumStrs, N, StrLen > &) -> EnumStrings< T, NumStrs >
constexpr MCFixupKind FirstTargetFixupKind
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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)
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.
@ 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)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
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)
constexpr MCFixupKind FirstLiteralRelocationKind
const MCSymbol * Personality
std::vector< MCCFIInstruction > Instructions