29 static const unsigned PCRelFlagVal =
35 unsigned getNumFixupKinds()
const override {
45 {
"fixup_aarch64_pcrel_adr_imm21", 0, 32, PCRelFlagVal },
46 {
"fixup_aarch64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal },
47 {
"fixup_aarch64_add_imm12", 10, 12, 0 },
48 {
"fixup_aarch64_ldst_imm12_scale1", 10, 12, 0 },
49 {
"fixup_aarch64_ldst_imm12_scale2", 10, 12, 0 },
50 {
"fixup_aarch64_ldst_imm12_scale4", 10, 12, 0 },
51 {
"fixup_aarch64_ldst_imm12_scale8", 10, 12, 0 },
52 {
"fixup_aarch64_ldst_imm12_scale16", 10, 12, 0 },
53 {
"fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal },
54 {
"fixup_aarch64_movw", 5, 16, 0 },
55 {
"fixup_aarch64_pcrel_branch14", 5, 14, PCRelFlagVal },
56 {
"fixup_aarch64_pcrel_branch19", 5, 19, PCRelFlagVal },
57 {
"fixup_aarch64_pcrel_branch26", 0, 26, PCRelFlagVal },
58 {
"fixup_aarch64_pcrel_call26", 0, 26, PCRelFlagVal },
59 {
"fixup_aarch64_tlsdesc_call", 0, 0, 0 }
71 uint64_t
Value,
bool IsPCRel)
const override;
73 bool mayNeedRelaxation(
const MCInst &Inst)
const override;
77 void relaxInstruction(
const MCInst &Inst,
MCInst &Res)
const override;
78 bool writeNopData(uint64_t Count,
MCObjectWriter *OW)
const override;
127 unsigned lo2 = Value & 0x3;
128 unsigned hi19 = (Value & 0x1ffffc) >> 2;
129 return (hi19 << 5) | (lo2 << 29);
133 int64_t SignedValue =
static_cast<int64_t
>(Value);
138 if (SignedValue > 2097151 || SignedValue < -2097152)
142 return AdrImmBits((Value & 0x1fffff000ULL) >> 12);
146 if (SignedValue > 2097151 || SignedValue < -2097152)
149 return (Value >> 2) & 0x7ffff;
158 if (Value & 1 || Value >= 0x2000)
163 if (Value & 3 || Value >= 0x4000)
168 if (Value & 7 || Value >= 0x8000)
173 if (Value & 15 || Value >= 0x10000)
181 if (SignedValue > 32767 || SignedValue < -32768)
186 return (Value >> 2) & 0x3fff;
190 if (SignedValue > 134217727 || SignedValue < -134217728)
195 return (Value >> 2) & 0x3ffffff;
204 void AArch64AsmBackend::applyFixup(
const MCFixup &
Fixup,
char *Data,
205 unsigned DataSize, uint64_t
Value,
206 bool IsPCRel)
const {
218 assert(Offset + NumBytes <= DataSize &&
"Invalid fixup offset!");
222 for (
unsigned i = 0; i != NumBytes; ++i)
223 Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
226 bool AArch64AsmBackend::mayNeedRelaxation(
const MCInst &Inst)
const {
230 bool AArch64AsmBackend::fixupNeedsRelaxation(
const MCFixup &Fixup,
238 return int64_t(Value) != int64_t(int8_t(Value));
241 void AArch64AsmBackend::relaxInstruction(
const MCInst &Inst,
246 bool AArch64AsmBackend::writeNopData(uint64_t Count,
MCObjectWriter *OW)
const {
254 for (uint64_t i = 0; i != Count; ++i)
267 UNWIND_AArch64_MODE_FRAMELESS = 0x02000000,
274 UNWIND_AArch64_MODE_DWARF = 0x03000000,
282 UNWIND_AArch64_MODE_FRAME = 0x04000000,
285 UNWIND_AArch64_FRAME_X19_X20_PAIR = 0x00000001,
286 UNWIND_AArch64_FRAME_X21_X22_PAIR = 0x00000002,
287 UNWIND_AArch64_FRAME_X23_X24_PAIR = 0x00000004,
288 UNWIND_AArch64_FRAME_X25_X26_PAIR = 0x00000008,
289 UNWIND_AArch64_FRAME_X27_X28_PAIR = 0x00000010,
290 UNWIND_AArch64_FRAME_D8_D9_PAIR = 0x00000100,
291 UNWIND_AArch64_FRAME_D10_D11_PAIR = 0x00000200,
292 UNWIND_AArch64_FRAME_D12_D13_PAIR = 0x00000400,
293 UNWIND_AArch64_FRAME_D14_D15_PAIR = 0x00000800
299 class DarwinAArch64AsmBackend :
public AArch64AsmBackend {
305 uint32_t encodeStackAdjustment(uint32_t StackSize)
const {
306 return (StackSize / 16) << 12;
311 : AArch64AsmBackend(T), MRI(MRI) {}
319 uint32_t generateCompactUnwindEncoding(
322 return CU::UNWIND_AArch64_MODE_FRAMELESS;
325 unsigned StackSize = 0;
327 uint32_t CompactUnwindEncoding = 0;
328 for (
size_t i = 0, e = Instrs.
size(); i != e; ++i) {
334 return CU::UNWIND_AArch64_MODE_DWARF;
339 "Invalid frame pointer!");
340 assert(i + 2 < e &&
"Insufficient CFI instructions to define a frame!");
344 "Link register not pushed!");
347 "Frame pointer not pushed!");
349 unsigned LRReg = MRI.getLLVMRegNum(LRPush.
getRegister(),
true);
350 unsigned FPReg = MRI.getLLVMRegNum(FPPush.getRegister(),
true);
355 assert(LRReg == AArch64::LR && FPReg == AArch64::FP &&
356 "Pushing invalid registers for frame!");
359 CompactUnwindEncoding |= CU::UNWIND_AArch64_MODE_FRAME;
364 assert(StackSize == 0 &&
"We already have the CFA offset!");
371 unsigned Reg1 = MRI.getLLVMRegNum(Inst.
getRegister(),
true);
373 return CU::UNWIND_AArch64_MODE_DWARF;
377 return CU::UNWIND_AArch64_MODE_DWARF;
378 unsigned Reg2 = MRI.getLLVMRegNum(Inst2.
getRegister(),
true);
391 if (Reg1 == AArch64::X19 && Reg2 == AArch64::X20 &&
392 (CompactUnwindEncoding & 0xF1E) == 0)
393 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X19_X20_PAIR;
394 else if (Reg1 == AArch64::X21 && Reg2 == AArch64::X22 &&
395 (CompactUnwindEncoding & 0xF1C) == 0)
396 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X21_X22_PAIR;
397 else if (Reg1 == AArch64::X23 && Reg2 == AArch64::X24 &&
398 (CompactUnwindEncoding & 0xF18) == 0)
399 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X23_X24_PAIR;
400 else if (Reg1 == AArch64::X25 && Reg2 == AArch64::X26 &&
401 (CompactUnwindEncoding & 0xF10) == 0)
402 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X25_X26_PAIR;
403 else if (Reg1 == AArch64::X27 && Reg2 == AArch64::X28 &&
404 (CompactUnwindEncoding & 0xF00) == 0)
405 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_X27_X28_PAIR;
414 if (Reg1 == AArch64::D8 && Reg2 == AArch64::D9 &&
415 (CompactUnwindEncoding & 0xE00) == 0)
416 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D8_D9_PAIR;
417 else if (Reg1 == AArch64::D10 && Reg2 == AArch64::D11 &&
418 (CompactUnwindEncoding & 0xC00) == 0)
419 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D10_D11_PAIR;
420 else if (Reg1 == AArch64::D12 && Reg2 == AArch64::D13 &&
421 (CompactUnwindEncoding & 0x800) == 0)
422 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D12_D13_PAIR;
423 else if (Reg1 == AArch64::D14 && Reg2 == AArch64::D15)
424 CompactUnwindEncoding |= CU::UNWIND_AArch64_FRAME_D14_D15_PAIR;
427 return CU::UNWIND_AArch64_MODE_DWARF;
438 if (StackSize > 65520)
439 return CU::UNWIND_AArch64_MODE_DWARF;
441 CompactUnwindEncoding |= CU::UNWIND_AArch64_MODE_FRAMELESS;
442 CompactUnwindEncoding |= encodeStackAdjustment(StackSize);
445 return CompactUnwindEncoding;
453 class ELFAArch64AsmBackend :
public AArch64AsmBackend {
458 ELFAArch64AsmBackend(
const Target &
T, uint8_t OSABI,
bool IsLittleEndian)
459 : AArch64AsmBackend(T), OSABI(OSABI), IsLittleEndian(IsLittleEndian) {}
468 bool &IsResolved)
override;
470 void applyFixup(
const MCFixup &Fixup,
char *Data,
unsigned DataSize,
471 uint64_t Value,
bool IsPCRel)
const override;
474 void ELFAArch64AsmBackend::processFixupValue(
497 static bool isByteSwappedFixup(
const MCExpr *E) {
510 void ELFAArch64AsmBackend::applyFixup(
const MCFixup &Fixup,
char *Data,
511 unsigned DataSize, uint64_t Value,
512 bool IsPCRel)
const {
515 if (isByteSwappedFixup(Fixup.
getValue()))
518 AArch64AsmBackend::applyFixup (Fixup, Data, DataSize, Value, IsPCRel);
527 return new DarwinAArch64AsmBackend(T, MRI);
529 assert(TheTriple.
isOSBinFormatELF() &&
"Expect either MachO or ELF target");
531 return new ELFAArch64AsmBackend(T, OSABI,
true);
539 "Big endian is only supported for ELF targets!");
541 return new ELFAArch64AsmBackend(T, OSABI,
MCAsmBackend * createAArch64beAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU)
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
StringRef getSectionName() const
void WriteZeros(unsigned N)
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
const MCSymbol & getSymbol() const
This represents an "assembler immediate".
static unsigned getXRegFromWReg(unsigned Reg)
Defines the object file and target independent interfaces used by the assembler backend to write nati...
unsigned getRegister() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
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.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Base class for the full range of assembler expressions which are needed for parsing.
uint32_t ByteSwap_32(uint32_t Value)
ByteSwap_32 - This function returns a byte-swapped representation of the 32-bit argument, Value.
static uint64_t getPointerSize(const Value *V, const DataLayout &DL, const TargetLibraryInfo *TLI)
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)
const MCExpr * getValue() const
MCObjectWriter * createAArch64ELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI, bool IsLittleEndian)
MCFixupKind
Extensible enumeration to represent the type of a fixup.
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)
Triple - Helper class for working with autoconf configuration names.
PowerPC TLS Dynamic Call Fixup
OpType getOperation() const
const MCSymbolRefExpr * getSymA() const
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value)
Target - Wrapper for Target specific information.
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static unsigned getDRegFromBReg(unsigned Reg)
MCAsmBackend * createAArch64leAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU)
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
APFloat abs(APFloat X)
Returns the absolute value of the argument.
MCSectionELF - This represents a section on linux, lots of unix variants and some bare metal systems...
Target independent information on a fixup kind.
An abstract base class for streams implementations that also support a pwrite operation.
const ARM::ArchExtKind Kind
LLVM Value Representation.
Generic interface to target specific assembler backends.
StringRef - Represent a constant reference to a string, i.e.
bool isUndefined() const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.