31 static const unsigned PCRelFlagVal =
37 AArch64AsmBackend(
const Target &
T,
bool IsLittleEndian)
40 unsigned getNumFixupKinds()
const override {
50 {
"fixup_aarch64_pcrel_adr_imm21", 0, 32, PCRelFlagVal },
51 {
"fixup_aarch64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal },
52 {
"fixup_aarch64_add_imm12", 10, 12, 0 },
53 {
"fixup_aarch64_ldst_imm12_scale1", 10, 12, 0 },
54 {
"fixup_aarch64_ldst_imm12_scale2", 10, 12, 0 },
55 {
"fixup_aarch64_ldst_imm12_scale4", 10, 12, 0 },
56 {
"fixup_aarch64_ldst_imm12_scale8", 10, 12, 0 },
57 {
"fixup_aarch64_ldst_imm12_scale16", 10, 12, 0 },
58 {
"fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal },
59 {
"fixup_aarch64_movw", 5, 16, 0 },
60 {
"fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal },
61 {
"fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal },
62 {
"fixup_aarch64_pcrel_branch26", 0, 26, PCRelFlagVal },
63 {
"fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal },
64 {
"fixup_aarch64_tlsdesc_call", 0, 0, 0 }
75 void applyFixup(
const MCFixup &Fixup,
char *Data,
unsigned DataSize,
76 uint64_t
Value,
bool IsPCRel)
const override;
78 bool mayNeedRelaxation(
const MCInst &Inst)
const override;
79 bool fixupNeedsRelaxation(
const MCFixup &Fixup, uint64_t
Value,
83 MCInst &Res)
const override;
84 bool writeNopData(uint64_t Count,
MCObjectWriter *OW)
const override;
90 unsigned getFixupKindContainereSizeInBytes(
unsigned Kind)
const;
135 unsigned lo2 = Value & 0x3;
136 unsigned hi19 = (Value & 0x1ffffc) >> 2;
137 return (hi19 << 5) | (lo2 << 29);
142 unsigned Kind = Fixup.
getKind();
143 int64_t SignedValue =
static_cast<int64_t
>(Value);
148 if (Ctx && (SignedValue > 2097151 || SignedValue < -2097152))
152 return AdrImmBits((Value & 0x1fffff000ULL) >> 12);
156 if (SignedValue > 2097151 || SignedValue < -2097152)
158 if (Ctx && (Value & 0x3))
161 return (Value >> 2) & 0x7ffff;
165 if (Ctx && Value >= 0x1000)
170 if (Ctx && (Value >= 0x2000))
172 if (Ctx && (Value & 0x1))
177 if (Ctx && (Value >= 0x4000))
179 if (Ctx && (Value & 0x3))
184 if (Ctx && (Value >= 0x8000))
186 if (Ctx && (Value & 0x7))
191 if (Ctx && (Value >= 0x10000))
193 if (Ctx && (Value & 0xf))
199 "no resolvable MOVZ/MOVK fixups supported yet");
203 if (Ctx && (SignedValue > 32767 || SignedValue < -32768))
206 if (Ctx && (Value & 0x3))
208 return (Value >> 2) & 0x3fff;
212 if (Ctx && (SignedValue > 134217727 || SignedValue < -134217728))
215 if (Ctx && (Value & 0x3))
217 return (Value >> 2) & 0x3ffffff;
228 unsigned AArch64AsmBackend::getFixupKindContainereSizeInBytes(
unsigned Kind)
const {
265 void AArch64AsmBackend::applyFixup(
const MCFixup &Fixup,
char *Data,
266 unsigned DataSize, uint64_t
Value,
267 bool IsPCRel)
const {
279 assert(Offset + NumBytes <= DataSize &&
"Invalid fixup offset!");
282 unsigned FulleSizeInBytes = getFixupKindContainereSizeInBytes(Fixup.
getKind());
286 if (FulleSizeInBytes == 0) {
288 for (
unsigned i = 0;
i != NumBytes; ++
i) {
289 Data[Offset +
i] |= uint8_t((Value >> (
i * 8)) & 0xff);
293 assert((Offset + FulleSizeInBytes) <= DataSize &&
"Invalid fixup size!");
294 assert(NumBytes <= FulleSizeInBytes &&
"Invalid fixup size!");
295 for (
unsigned i = 0;
i != NumBytes; ++
i) {
296 unsigned Idx = FulleSizeInBytes - 1 -
i;
297 Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
302 bool AArch64AsmBackend::mayNeedRelaxation(
const MCInst &Inst)
const {
306 bool AArch64AsmBackend::fixupNeedsRelaxation(
const MCFixup &Fixup,
314 return int64_t(Value) != int64_t(int8_t(Value));
317 void AArch64AsmBackend::relaxInstruction(
const MCInst &Inst,
323 bool AArch64AsmBackend::writeNopData(uint64_t Count,
MCObjectWriter *OW)
const {
331 for (uint64_t
i = 0;
i != Count; ++
i)
344 UNWIND_ARM64_MODE_FRAMELESS = 0x02000000,
351 UNWIND_ARM64_MODE_DWARF = 0x03000000,
359 UNWIND_ARM64_MODE_FRAME = 0x04000000,
362 UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001,
363 UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002,
364 UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004,
365 UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008,
366 UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010,
367 UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100,
368 UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200,
369 UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400,
370 UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800
376 class DarwinAArch64AsmBackend :
public AArch64AsmBackend {
383 return (StackSize / 16) << 12;
388 : AArch64AsmBackend(T,
true), MRI(MRI) {}
396 uint32_t generateCompactUnwindEncoding(
399 return CU::UNWIND_ARM64_MODE_FRAMELESS;
402 unsigned StackSize = 0;
405 for (
size_t i = 0, e = Instrs.
size();
i != e; ++
i) {
411 return CU::UNWIND_ARM64_MODE_DWARF;
416 "Invalid frame pointer!");
417 assert(
i + 2 < e &&
"Insufficient CFI instructions to define a frame!");
421 "Link register not pushed!");
424 "Frame pointer not pushed!");
427 unsigned FPReg =
MRI.getLLVMRegNum(FPPush.getRegister(),
true);
432 assert(LRReg == AArch64::LR && FPReg == AArch64::FP &&
433 "Pushing invalid registers for frame!");
436 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAME;
441 assert(StackSize == 0 &&
"We already have the CFA offset!");
450 return CU::UNWIND_ARM64_MODE_DWARF;
454 return CU::UNWIND_ARM64_MODE_DWARF;
468 if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
469 (CompactUnwindEncoding & 0xF1E) == 0)
470 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X19_X20_PAIR;
471 else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
472 (CompactUnwindEncoding & 0xF1C) == 0)
473 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X21_X22_PAIR;
474 else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
475 (CompactUnwindEncoding & 0xF18) == 0)
476 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X23_X24_PAIR;
477 else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
478 (CompactUnwindEncoding & 0xF10) == 0)
479 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X25_X26_PAIR;
480 else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
481 (CompactUnwindEncoding & 0xF00) == 0)
482 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_X27_X28_PAIR;
491 if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
492 (CompactUnwindEncoding & 0xE00) == 0)
493 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D8_D9_PAIR;
494 else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
495 (CompactUnwindEncoding & 0xC00) == 0)
496 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D10_D11_PAIR;
497 else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
498 (CompactUnwindEncoding & 0x800) == 0)
499 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D12_D13_PAIR;
500 else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
501 CompactUnwindEncoding |= CU::UNWIND_ARM64_FRAME_D14_D15_PAIR;
504 return CU::UNWIND_ARM64_MODE_DWARF;
515 if (StackSize > 65520)
516 return CU::UNWIND_ARM64_MODE_DWARF;
518 CompactUnwindEncoding |= CU::UNWIND_ARM64_MODE_FRAMELESS;
519 CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
522 return CompactUnwindEncoding;
528 bool &IsResolved)
override {
541 class ELFAArch64AsmBackend :
public AArch64AsmBackend {
546 ELFAArch64AsmBackend(
const Target &
T, uint8_t OSABI,
bool IsLittleEndian,
548 : AArch64AsmBackend(T, IsLittleEndian), OSABI(OSABI), IsILP32(IsILP32) {}
557 bool &IsResolved)
override;
560 void ELFAArch64AsmBackend::processFixupValue(
594 return new DarwinAArch64AsmBackend(T, MRI);
598 bool IsILP32 = Options.
getABIName() ==
"ilp32";
599 return new ELFAArch64AsmBackend(T, OSABI,
true, IsILP32);
608 "Big endian is only supported for ELF targets!");
610 bool IsILP32 = Options.
getABIName() ==
"ilp32";
611 return new ELFAArch64AsmBackend(T, OSABI,
false, IsILP32);
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
void WriteZeros(unsigned N)
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
This represents an "assembler immediate".
static unsigned getXRegFromWReg(unsigned Reg)
MCContext & getContext() const
Defines the object file and target independent interfaces used by the assembler backend to write nati...
unsigned getRegister() const
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)...
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
Encapsulates the layout of an assembly file at a particular point in time.
Context object for machine code objects.
CompactUnwindEncodings
Compact unwind encoding values.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
uint32_t getOffset() const
size_t size() const
size - Get the array size.
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...
void write32(uint32_t Value)
unsigned const MachineRegisterInfo * MRI
static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, MCContext *Ctx)
MCFixupKind
Extensible enumeration to represent the type of a fixup.
void reportError(SMLoc L, const Twine &Msg)
Should this fixup kind force a 4-byte aligned effective PC value?
bool empty() const
empty - Check if the array is empty.
MCObjectWriter * createAArch64MachObjectWriter(raw_pwrite_stream &OS, uint32_t CPUType, uint32_t CPUSubtype)
MCFixupKind getKind() const
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.
MCObjectWriter * createAArch64ELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI, bool IsLittleEndian, bool IsILP32)
OpType getOperation() const
Target - Wrapper for Target specific information.
static unsigned getDRegFromBReg(unsigned Reg)
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
MCAsmBackend * createAArch64leAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, const MCTargetOptions &Options)
StringRef getABIName() const
getABIName - If this returns a non-empty string this represents the textual name of the ABI that we w...
APFloat abs(APFloat X)
Returns the absolute value of the argument.
MCSubtargetInfo - Generic base class for all target subtargets.
MCAsmBackend * createAArch64beAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, const MCTargetOptions &Options)
Target independent information on a fixup kind.
An abstract base class for streams implementations that also support a pwrite operation.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Generic interface to target specific assembler backends.
StringRef - Represent a constant reference to a string, i.e.
static uint64_t getPointerSize(const Value *V, const DataLayout &DL, const TargetLibraryInfo &TLI)
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.