32 static const unsigned PCRelFlagVal =
37 AArch64AsmBackend(
const Target &
T,
const Triple &TT,
bool IsLittleEndian)
41 unsigned getNumFixupKinds()
const override {
51 {
"fixup_aarch64_pcrel_adr_imm21", 0, 32, PCRelFlagVal},
52 {
"fixup_aarch64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal},
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, PCRelFlagVal},
60 {
"fixup_aarch64_movw", 5, 16, 0},
61 {
"fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal},
62 {
"fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal},
63 {
"fixup_aarch64_pcrel_branch26", 0, 26, PCRelFlagVal},
64 {
"fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal},
65 {
"fixup_aarch64_tlsdesc_call", 0, 0, 0}};
77 uint64_t
Value,
bool IsResolved,
80 bool mayNeedRelaxation(
const MCInst &Inst,
82 bool fixupNeedsRelaxation(
const MCFixup &Fixup, uint64_t
Value,
86 MCInst &Res)
const override;
87 bool writeNopData(
raw_ostream &OS, uint64_t Count)
const override;
93 unsigned getFixupKindContainereSizeInBytes(
unsigned Kind)
const;
143 unsigned lo2 = Value & 0x3;
144 unsigned hi19 = (Value & 0x1ffffc) >> 2;
145 return (hi19 << 5) | (lo2 << 29);
150 const Triple &TheTriple,
bool IsResolved) {
151 unsigned Kind = Fixup.
getKind();
152 int64_t SignedValue =
static_cast<int64_t
>(Value);
157 if (SignedValue > 2097151 || SignedValue < -2097152)
164 return AdrImmBits((Value & 0x1fffff000ULL) >> 12);
168 if (SignedValue > 2097151 || SignedValue < -2097152)
173 return (Value >> 2) & 0x7ffff;
213 if (Value >= 0x10000)
226 "relocation for a thread-local variable points to an " 244 SignedValue = SignedValue >> 16;
247 SignedValue = SignedValue >> 32;
250 SignedValue = SignedValue >> 48;
278 if (SignedValue > 0xFFFF || SignedValue < -0xFFFF)
283 SignedValue = ~SignedValue;
284 Value =
static_cast<uint64_t
>(SignedValue);
286 else if (Value > 0xFFFF) {
293 if (SignedValue > 32767 || SignedValue < -32768)
298 return (Value >> 2) & 0x3fff;
302 if (SignedValue > 134217727 || SignedValue < -134217728)
307 return (Value >> 2) & 0x3ffffff;
320 unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(
unsigned Kind)
const {
367 int64_t SignedValue =
static_cast<int64_t
>(Value);
375 assert(Offset + NumBytes <= Data.
size() &&
"Invalid fixup offset!");
378 unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(Fixup.
getKind());
382 if (FulleSizeInBytes == 0) {
384 for (
unsigned i = 0; i != NumBytes; ++i) {
385 Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
389 assert((Offset + FulleSizeInBytes) <= Data.
size() &&
"Invalid fixup size!");
390 assert(NumBytes <= FulleSizeInBytes &&
"Invalid fixup size!");
391 for (
unsigned i = 0; i != NumBytes; ++i) {
392 unsigned Idx = FulleSizeInBytes - 1 - i;
393 Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
405 Data[Offset + 3] &= ~(1 << 6);
407 Data[Offset + 3] |= (1 << 6);
411 bool AArch64AsmBackend::mayNeedRelaxation(
const MCInst &Inst,
416 bool AArch64AsmBackend::fixupNeedsRelaxation(
const MCFixup &Fixup,
424 return int64_t(Value) != int64_t(int8_t(Value));
427 void AArch64AsmBackend::relaxInstruction(
const MCInst &Inst,
433 bool AArch64AsmBackend::writeNopData(
raw_ostream &OS, uint64_t Count)
const {
441 for (uint64_t i = 0; i != Count; ++i)
442 support::endian::write<uint32_t>(OS, 0xd503201f, Endian);
446 bool AArch64AsmBackend::shouldForceRelocation(
const MCAssembler &Asm,
482 UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
489 UNWIND_ARM64_MODE_DWARF = 0x03000000,
497 UNWIND_ARM64_MODE_FRAME = 0x04000000,
500 UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
501 UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
502 UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
503 UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
504 UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
505 UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
506 UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
507 UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
508 UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
514 class DarwinAArch64AsmBackend :
public AArch64AsmBackend {
521 return (StackSize / 16) << 12;
525 DarwinAArch64AsmBackend(
const Target &
T,
const Triple &TT,
527 : AArch64AsmBackend(T, TT,
true),
MRI(MRI) {}
529 std::unique_ptr<MCObjectTargetWriter>
530 createObjectTargetWriter()
const override {
536 uint32_t generateCompactUnwindEncoding(
539 return CU::UNWIND_ARM64_MODE_FRAMELESS;
542 unsigned StackSize = 0;
545 for (
size_t i = 0, e = Instrs.
size(); i != e; ++i) {
551 return CU::UNWIND_ARM64_MODE_DWARF;
562 return CU::UNWIND_ARM64_MODE_DWARF;
565 assert(i + 2 < e &&
"Insufficient CFI instructions to define a frame!");
569 "Link register not pushed!");
572 "Frame pointer not pushed!");
575 unsigned FPReg = MRI.
getLLVMRegNum(FPPush.getRegister(),
true);
581 "Pushing invalid registers for frame!");
584 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
589 assert(StackSize == 0 &&
"We already have the CFA offset!");
598 return CU::UNWIND_ARM64_MODE_DWARF;
602 return CU::UNWIND_ARM64_MODE_DWARF;
616 if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
617 (CompactUnwindEncoding & 0xF1E) == 0)
618 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
619 else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
620 (CompactUnwindEncoding & 0xF1C) == 0)
621 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
622 else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
623 (CompactUnwindEncoding & 0xF18) == 0)
624 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
625 else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
626 (CompactUnwindEncoding & 0xF10) == 0)
627 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
628 else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
629 (CompactUnwindEncoding & 0xF00) == 0)
630 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
639 if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
640 (CompactUnwindEncoding & 0xE00) == 0)
641 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
642 else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
643 (CompactUnwindEncoding & 0xC00) == 0)
644 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
645 else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
646 (CompactUnwindEncoding & 0x800) == 0)
647 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
648 else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
649 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
652 return CU::UNWIND_ARM64_MODE_DWARF;
663 if (StackSize > 65520)
664 return CU::UNWIND_ARM64_MODE_DWARF;
666 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
667 CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
670 return CompactUnwindEncoding;
678 class ELFAArch64AsmBackend :
public AArch64AsmBackend {
683 ELFAArch64AsmBackend(
const Target &
T,
const Triple &TT, uint8_t OSABI,
684 bool IsLittleEndian,
bool IsILP32)
685 : AArch64AsmBackend(T, TT, IsLittleEndian), OSABI(OSABI),
688 std::unique_ptr<MCObjectTargetWriter>
689 createObjectTargetWriter()
const override {
697 class COFFAArch64AsmBackend :
public AArch64AsmBackend {
699 COFFAArch64AsmBackend(
const Target &
T,
const Triple &TheTriple)
700 : AArch64AsmBackend(T, TheTriple,
true) {}
702 std::unique_ptr<MCObjectTargetWriter>
703 createObjectTargetWriter()
const override {
715 return new DarwinAArch64AsmBackend(T, TheTriple, MRI);
718 return new COFFAArch64AsmBackend(T, TheTriple);
723 bool IsILP32 = Options.
getABIName() ==
"ilp32";
724 return new ELFAArch64AsmBackend(T, TheTriple, OSABI,
true,
734 "Big endian is only supported for ELF targets!");
736 bool IsILP32 = Options.
getABIName() ==
"ilp32";
737 return new ELFAArch64AsmBackend(T, TheTriple, OSABI,
false,
This class represents lattice values for constants.
This represents an "assembler immediate".
std::unique_ptr< MCObjectTargetWriter > createAArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype)
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert 'NumZeros' nulls.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
static unsigned getXRegFromWReg(unsigned Reg)
unsigned TargetOffset
The bit offset to write the relocation into.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
const Triple & getTargetTriple() const
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
MCContext & getContext() const
Encapsulates the layout of an assembly file at a particular point in time.
MCAsmBackend * createAArch64leAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
A four-byte section relative fixup.
Context object for machine code objects.
A two-byte section relative fixup.
CompactUnwindEncodings
Compact unwind encoding values.
static uint64_t getPointerSize(const Value *V, const DataLayout &DL, const TargetLibraryInfo &TLI, const Function *F)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static VariantKind getAddressFrag(VariantKind Kind)
Analysis containing CSE Info
Instances of this class represent a single low-level machine instruction.
static unsigned getFixupKindNumBytes(unsigned Kind)
The number of bytes the fixup may change.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
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...
unsigned const MachineRegisterInfo * MRI
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
size_t size() const
size - Get the array size.
MCFixupKind
Extensible enumeration to represent the type of a fixup.
static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, uint64_t Value, MCContext &Ctx, const Triple &TheTriple, bool IsResolved)
OpType getOperation() const
void reportError(SMLoc L, const Twine &Msg)
Should this fixup kind force a 4-byte aligned effective PC value?
std::unique_ptr< MCObjectTargetWriter > createAArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32)
uint32_t getOffset() const
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
static unsigned AdrImmBits(unsigned Value)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
PowerPC TLS Dynamic Call Fixup
unsigned getRegister() const
Target - Wrapper for Target specific information.
MCAsmBackend * createAArch64beAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
static unsigned getDRegFromBReg(unsigned Reg)
StringRef getABIName() const
getABIName - If this returns a non-empty string this represents the textual name of the ABI that we w...
std::unique_ptr< MCObjectTargetWriter > createAArch64WinCOFFObjectWriter()
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Generic base class for all target subtargets.
Target independent information on a fixup kind.
uint32_t getRefKind() const
static VariantKind getSymbolLoc(VariantKind Kind)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Generic interface to target specific assembler backends.
This class implements an extremely fast bulk output stream that can only output to a stream...
int getLLVMRegNum(unsigned RegNum, bool isEH) const
Map a dwarf register back to a target register.
MCFixupKind getKind() const
bool empty() const
empty - Check if the array is empty.