Go to the documentation of this file.
44 ARMELFObjectWriter(uint8_t OSABI)
56 #define ELF_RELOC(X, Y) .Case(#X, Y)
57 #include "llvm/BinaryFormat/ELFRelocs/ARM.def"
59 .
Case(
"BFD_RELOC_NONE", ELF::R_ARM_NONE)
60 .
Case(
"BFD_RELOC_8", ELF::R_ARM_ABS8)
61 .
Case(
"BFD_RELOC_16", ELF::R_ARM_ABS16)
62 .
Case(
"BFD_RELOC_32", ELF::R_ARM_ABS32)
70 unsigned IsPCRelConstant =
77 {
"fixup_arm_ldst_pcrel_12", 0, 32, IsPCRelConstant},
78 {
"fixup_t2_ldst_pcrel_12", 0, 32,
80 {
"fixup_arm_pcrel_10_unscaled", 0, 32, IsPCRelConstant},
81 {
"fixup_arm_pcrel_10", 0, 32, IsPCRelConstant},
82 {
"fixup_t2_pcrel_10", 0, 32,
86 {
"fixup_t2_pcrel_9", 0, 32,
88 {
"fixup_arm_ldst_abs_12", 0, 32, 0},
89 {
"fixup_thumb_adr_pcrel_10", 0, 8,
91 {
"fixup_arm_adr_pcrel_12", 0, 32, IsPCRelConstant},
92 {
"fixup_t2_adr_pcrel_12", 0, 32,
103 {
"fixup_arm_thumb_blx", 0, 32,
107 {
"fixup_arm_thumb_cp", 0, 8,
113 {
"fixup_arm_movt_hi16", 0, 20, 0},
114 {
"fixup_arm_movw_lo16", 0, 20, 0},
115 {
"fixup_t2_movt_hi16", 0, 20, 0},
116 {
"fixup_t2_movw_lo16", 0, 20, 0},
117 {
"fixup_arm_mod_imm", 0, 12, 0},
118 {
"fixup_t2_so_imm", 0, 26, 0},
123 {
"fixup_bfcsel_else_target", 0, 32, 0},
131 {
"fixup_arm_ldst_pcrel_12", 0, 32, IsPCRelConstant},
132 {
"fixup_t2_ldst_pcrel_12", 0, 32,
134 {
"fixup_arm_pcrel_10_unscaled", 0, 32, IsPCRelConstant},
135 {
"fixup_arm_pcrel_10", 0, 32, IsPCRelConstant},
136 {
"fixup_t2_pcrel_10", 0, 32,
140 {
"fixup_t2_pcrel_9", 0, 32,
142 {
"fixup_arm_ldst_abs_12", 0, 32, 0},
143 {
"fixup_thumb_adr_pcrel_10", 8, 8,
145 {
"fixup_arm_adr_pcrel_12", 0, 32, IsPCRelConstant},
146 {
"fixup_t2_adr_pcrel_12", 0, 32,
157 {
"fixup_arm_thumb_blx", 0, 32,
161 {
"fixup_arm_thumb_cp", 8, 8,
167 {
"fixup_arm_movt_hi16", 12, 20, 0},
168 {
"fixup_arm_movw_lo16", 12, 20, 0},
169 {
"fixup_t2_movt_hi16", 12, 20, 0},
170 {
"fixup_t2_movw_lo16", 12, 20, 0},
171 {
"fixup_arm_mod_imm", 20, 12, 0},
172 {
"fixup_t2_so_imm", 26, 6, 0},
177 {
"fixup_bfcsel_else_target", 0, 32, 0},
211 bool HasV8MBaselineOps = STI.
getFeatureBits()[ARM::HasV8MBaselineOps];
217 return HasThumb2 ? (unsigned)ARM::t2Bcc :
Op;
219 return HasThumb2 ? (unsigned)ARM::t2LDRpci :
Op;
221 return HasThumb2 ? (unsigned)ARM::t2ADR :
Op;
223 return HasV8MBaselineOps ? (unsigned)ARM::t2B :
Op;
239 int64_t Offset = int64_t(
Value) - 4;
240 if (Offset < Min || Offset > Max)
241 return "out of range pc-relative fixup value";
247 switch (
Fixup.getTargetKind()) {
255 int64_t Offset = int64_t(
Value) - 4;
256 if (Offset > 2046 || Offset < -2048)
257 return "out of range pc-relative fixup value";
267 int64_t Offset = int64_t(
Value) - 4;
268 if (Offset > 254 || Offset < -256)
269 return "out of range pc-relative fixup value";
276 int64_t Offset = int64_t(
Value) - 4;
278 return "misaligned pc-relative fixup value";
279 else if (Offset > 1020 || Offset < 0)
280 return "out of range pc-relative fixup value";
287 int64_t Offset = (
Value & ~1);
289 return "will be converted to nop";
314 return "out of range label-relative fixup value";
346 RelaxedOp == ARM::tHINT) {
363 const uint16_t Thumb1_16bitNopEncoding = 0x46c0;
364 const uint16_t Thumb2_16bitNopEncoding = 0xbf00;
365 const uint32_t ARMv4_NopEncoding = 0xe1a00000;
366 const uint32_t ARMv6T2_NopEncoding = 0xe320f000;
369 hasNOP(STI) ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding;
379 hasNOP(STI) ? ARMv6T2_NopEncoding : ARMv4_NopEncoding;
395 OS.
write(
"\0\0\xa0", 3);
403 if (IsLittleEndian) {
407 Swapped |= (
Value & 0x0000FFFF) << 16;
414 bool IsLittleEndian) {
417 if (IsLittleEndian) {
418 Value = (SecondHalf & 0xFFFF) << 16;
419 Value |= (FirstHalf & 0xFFFF);
421 Value = (SecondHalf & 0xFFFF);
422 Value |= (FirstHalf & 0xFFFF) << 16;
441 if (A->hasSubsectionsViaSymbols() &&
Asm.isThumbFunc(&A->getSymbol()) &&
442 A->getSymbol().isExternal() &&
467 unsigned Hi4 = (
Value & 0xF000) >> 12;
468 unsigned Lo12 =
Value & 0x0FFF;
471 Value = (Hi4 << 16) | (Lo12);
480 unsigned Hi4 = (
Value & 0xF000) >> 12;
481 unsigned i = (
Value & 0x800) >> 11;
482 unsigned Mid3 = (
Value & 0x700) >> 8;
483 unsigned Lo8 =
Value & 0x0FF;
488 Value = (Hi4 << 16) | (
i << 26) | (Mid3 << 12) | (Lo8);
501 if ((int64_t)
Value < 0) {
509 Value |= isAdd << 23;
522 if ((int64_t)
Value < 0) {
537 if ((int64_t)
Value < 0) {
543 out |= (
Value & 0x800) << 15;
544 out |= (
Value & 0x700) << 4;
545 out |= (
Value & 0x0FF);
558 dyn_cast<MCSymbolRefExpr>(
Fixup.getValue()))
561 return 0xffffff & ((
Value - 8) >> 2);
564 if (!isInt<25>(
Value)) {
572 bool I =
Value & 0x800000;
573 bool J1 =
Value & 0x400000;
574 bool J2 =
Value & 0x200000;
581 out |= (
Value & 0x1FF800) << 5;
582 out |= (
Value & 0x0007FF);
588 if (!isInt<21>(
Value)) {
596 out |= (
Value & 0x80000) << 7;
597 out |= (
Value & 0x40000) >> 7;
598 out |= (
Value & 0x20000) >> 4;
599 out |= (
Value & 0x1F800) << 5;
600 out |= (
Value & 0x007FF);
605 if (!isInt<25>(
Value - 4) ||
609 !isInt<23>(
Value - 4))) {
627 uint32_t signBit = (offset & 0x800000) >> 23;
628 uint32_t I1Bit = (offset & 0x400000) >> 22;
629 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
630 uint32_t I2Bit = (offset & 0x200000) >> 21;
631 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
632 uint32_t imm10Bits = (offset & 0x1FF800) >> 11;
633 uint32_t imm11Bits = (offset & 0x000007FF);
653 if (
Value % 4 != 0) {
660 dyn_cast<MCSymbolRefExpr>(
Fixup.getValue()))
663 uint32_t signBit = (offset & 0x400000) >> 22;
664 uint32_t I1Bit = (offset & 0x200000) >> 21;
665 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
666 uint32_t I2Bit = (offset & 0x100000) >> 20;
667 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
668 uint32_t imm10HBits = (offset & 0xFFC00) >> 10;
669 uint32_t imm10LBits = (offset & 0x3FF);
683 if (FixupDiagnostic) {
689 return ((
Value - 4) >> 2) & 0xff;
701 return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3);
709 if (FixupDiagnostic) {
714 return ((
Value - 4) >> 1) & 0x7ff;
720 if (FixupDiagnostic) {
725 return ((
Value - 4) >> 1) & 0xff;
730 if ((int64_t)
Value < 0) {
740 return Value | (isAdd << 23);
750 if ((int64_t)
Value < 0) {
760 Value |= isAdd << 23;
777 if ((int64_t)
Value < 0) {
791 Value |= isAdd << 23;
809 if ((int64_t)
Value < 0) {
819 EncValue |= (
Value & 0x800) << 15;
820 EncValue |= (
Value & 0x700) << 4;
821 EncValue |= (
Value & 0xff);
826 if (FixupDiagnostic) {
837 if (FixupDiagnostic) {
844 out |= (((
Value - 4) >> 1) & 0x1) << 11;
845 out |= (((
Value - 4) >> 1) & 0x7fe);
846 out |= (((
Value - 4) >> 1) & HighBitMask) << 5;
856 if (FixupDiagnostic) {
866 if (FixupDiagnostic) {
873 real_value = -real_value;
874 out |= ((real_value >> 1) & 0x1) << 11;
875 out |= ((real_value >> 1) & 0x7fe);
885 const MCSymbol *Sym = A ? &A->getSymbol() :
nullptr;
890 assert(Sym &&
"How did we resolve this?");
902 if (Sym && Sym->
isELF()) {
903 unsigned Type = cast<MCSymbolELF>(Sym)->getType();
1058 unsigned Offset =
Fixup.getOffset();
1059 assert(Offset + NumBytes <=
Data.size() &&
"Invalid fixup offset!");
1062 unsigned FullSizeBytes;
1065 assert((Offset + FullSizeBytes) <=
Data.size() &&
"Invalid fixup size!");
1066 assert(NumBytes <= FullSizeBytes &&
"Invalid fixup size!");
1072 for (
unsigned i = 0;
i != NumBytes; ++
i) {
1074 Data[Offset + Idx] |= uint8_t((
Value >> (
i * 8)) & 0xff);
1120 unsigned CFARegister = ARM::SP;
1121 int CFARegisterOffset = 0;
1124 int FloatRegCount = 0;
1128 switch (Inst.getOperation()) {
1130 CFARegisterOffset = Inst.getOffset();
1134 CFARegisterOffset = Inst.getOffset();
1141 if (ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(
Reg))
1142 RegOffsets[
Reg] = Inst.getOffset();
1143 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(
Reg)) {
1144 RegOffsets[
Reg] = Inst.getOffset();
1148 llvm::dbgs() <<
".cfi_offset on unknown register="
1149 << Inst.getRegister() <<
"\n");
1160 <<
"CFI directive not compatiable with comact "
1161 "unwind encoding, opcode=" << Inst.getOperation()
1169 if ((CFARegister == ARM::SP) && (CFARegisterOffset == 0))
1173 if (CFARegister != ARM::R7) {
1176 <<
" instead of r7\n");
1179 int StackAdjust = CFARegisterOffset - 8;
1180 if (RegOffsets.
lookup(ARM::LR) != (-4 - StackAdjust)) {
1183 <<
"LR not saved as standard frame, StackAdjust="
1185 <<
", CFARegisterOffset=" << CFARegisterOffset
1186 <<
", lr save at offset=" << RegOffsets[14] <<
"\n");
1189 if (RegOffsets.
lookup(ARM::R7) != (-8 - StackAdjust)) {
1191 llvm::dbgs() <<
"r7 not saved as standard frame\n");
1197 switch (StackAdjust) {
1201 CompactUnwindEncoding |= 0x00400000;
1204 CompactUnwindEncoding |= 0x00800000;
1207 CompactUnwindEncoding |= 0x00C00000;
1211 <<
".cfi_def_cfa stack adjust ("
1212 << StackAdjust <<
") out of range\n");
1229 int CurOffset = -8 - StackAdjust;
1230 for (
auto CSReg : GPRCSRegs) {
1231 auto Offset = RegOffsets.
find(CSReg.Reg);
1232 if (Offset == RegOffsets.
end())
1235 int RegOffset = Offset->second;
1236 if (RegOffset != CurOffset - 4) {
1239 << RegOffset <<
" but only supported at "
1240 << CurOffset <<
"\n");
1243 CompactUnwindEncoding |= CSReg.Encoding;
1248 if (FloatRegCount == 0)
1249 return CompactUnwindEncoding;
1257 if (FloatRegCount > 4) {
1259 llvm::dbgs() <<
"unsupported number of D registers saved ("
1260 << FloatRegCount <<
")\n");
1267 static unsigned FPRCSRegs[] = { ARM::D8, ARM::D10, ARM::D12, ARM::D14 };
1268 for (
int Idx = FloatRegCount - 1; Idx >= 0; --Idx) {
1269 auto Offset = RegOffsets.
find(FPRCSRegs[Idx]);
1270 if (Offset == RegOffsets.
end()) {
1272 llvm::dbgs() << FloatRegCount <<
" D-regs saved, but "
1273 << MRI.
getName(FPRCSRegs[Idx])
1276 }
else if (Offset->second != CurOffset - 8) {
1278 llvm::dbgs() << FloatRegCount <<
" D-regs saved, but "
1279 << MRI.
getName(FPRCSRegs[Idx])
1280 <<
" saved at " << Offset->second
1281 <<
", expected at " << CurOffset - 8
1288 return CompactUnwindEncoding | ((FloatRegCount - 1) << 8);
StringSwitch & Case(StringLiteral S, T Value)
This is an optimization pass for GlobalISel generic memory operations.
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
const char * getName(MCRegister RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
static Lanai::Fixups FixupKind(const MCExpr *Expr)
@ fixup_arm_ldst_pcrel_12
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
static MCOperand createImm(int64_t Val)
Context object for machine code objects.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
LLVM_NODISCARD R Default(T Value)
unsigned getNumFixupKinds() const override
Get the number of target specific fixup kinds.
return AArch64::GPR64RegClass contains(Reg)
Target - Wrapper for Target specific information.
@ FKF_Constant
This fixup kind should be resolved if defined.
static MCAsmBackend * createARMAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options, support::endianness Endian)
MCAsmBackend * createARMBEAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Reg
All possible values of the reg field in the ModR/M byte.
MCAsmBackend * createARMLEAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
@ UNWIND_ARM_DWARF_SECTION_OFFSET
static unsigned getFixupKindContainerSizeBytes(unsigned Kind)
getFixupKindContainerSizeBytes - The number of bytes of the container involved in big endian.
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef< char > Data, uint64_t Value, bool IsResolved, const MCSubtargetInfo *STI) const override
Apply the Value for given Fixup into the provided data fragment, at the offset specified by the fixup...
bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override
Simple predicate for targets where !Resolved implies requiring relaxation.
@ UNWIND_ARM_MODE_FRAME_D
Instances of this class represent a single low-level machine instruction.
@ UNWIND_ARM_FRAME_SECOND_PUSH_R11
@ FKF_IsAlignedDownTo32Bits
Should this fixup kind force a 4-byte aligned effective PC value?
bool writeNopData(raw_ostream &OS, uint64_t Count, const MCSubtargetInfo *STI) const override
Write an (optimal) nop sequence of Count bytes to the given output.
bool empty() const
empty - Check if the array is empty.
@ fixup_thumb_adr_pcrel_10
const support::endianness Endian
void setOpcode(unsigned Op)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint32_t generateCompactUnwindEncoding(ArrayRef< MCCFIInstruction > Instrs) const override
Generate compact unwind encoding for the function based on the CFI instructions.
@ FirstLiteralRelocationKind
The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for relocations coming from ....
static unsigned getFixupKindNumBytes(unsigned Kind)
getFixupKindNumBytes - The number of bytes the fixup may change.
@ FK_Data_4
A four-byte fixup.
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
Generic interface to target specific assembler backends.
@ FK_SecRel_4
A four-byte section relative fixup.
const Triple & getTargetTriple() const
static uint32_t swapHalfWords(uint32_t Value, bool IsLittleEndian)
@ MCAF_Code16
.code16 (X86) / .code 16 (ARM)
@ FK_SecRel_2
A two-byte section relative fixup.
const char * reasonForFixupRelaxation(const MCFixup &Fixup, uint64_t Value) const
const FeatureBitset & getFeatureBits() const
Flag
These should be considered private to the implementation of the MCInstrDesc class.
raw_ostream & write(unsigned char C)
ObjectFormatType getObjectFormat() const
Get the object format for this triple.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
This class implements an extremely fast bulk output stream that can only output to a stream.
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
void addOperand(const MCOperand Op)
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
void handleAssemblerFlag(MCAssemblerFlag Flag) override
Handle any target-specific assembler flags. By default, do nothing.
const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const override
Get information on a fixup kind.
Optional< unsigned > getLLVMRegNum(unsigned RegNum, bool isEH) const
Map a dwarf register back to a target register.
@ UNWIND_ARM_FRAME_SECOND_PUSH_R10
@ fixup_bfcsel_else_target
@ UNWIND_ARM_FRAME_D_REG_COUNT_MASK
bool isThumb() const
Tests whether the target is Thumb (little and big endian).
OSType getOS() const
Get the parsed operating system type of this triple.
unsigned getRelaxedOpcode(unsigned Op, const MCSubtargetInfo &STI) const
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
@ FKF_IsPCRel
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
bool hasNOP(const MCSubtargetInfo *STI) const
@ UNWIND_ARM_FRAME_SECOND_PUSH_R8
bool mayNeedRelaxation(const MCInst &Inst, const MCSubtargetInfo &STI) const override
Check whether the given instruction may need relaxation.
iterator find(const_arg_type_t< KeyT > Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Target independent information on a fixup kind.
void reportError(SMLoc L, const Twine &Msg)
@ FK_Data_1
A one-byte fixup.
Represent a reference to a symbol from inside an expression.
CompactUnwindEncodings
Compact unwind encoding values.
void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const override
Relax the instruction in the given fragment to the next wider instruction.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
PowerPC TLS Dynamic Call Fixup
StringRef - Represent a constant reference to a string, i.e.
StringRef str() const
Return a StringRef for the vector contents.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static MCOperand createReg(unsigned Reg)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
unsigned const MachineRegisterInfo * MRI
@ MCAF_Code32
.code32 (X86) / .code 32 (ARM)
bool isOSWindows() const
Tests whether the OS is Windows.
@ UNWIND_ARM_FRAME_STACK_ADJUST_MASK
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target) override
Hook to check if a relocation is needed for some target specific reason.
Encapsulates the layout of an assembly file at a particular point in time.
@ UNWIND_ARM_FRAME_FIRST_PUSH_R5
@ UNWIND_ARM_FRAME_SECOND_PUSH_R9
@ UNWIND_ARM_FRAME_FIRST_PUSH_R4
unsigned getOpcode() const
MCFixupKind
Extensible enumeration to represent the type of a fixup.
@ fixup_arm_pcrel_10_unscaled
unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, uint64_t Value, bool IsResolved, MCContext &Ctx, const MCSubtargetInfo *STI) const
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCRegisterInfo *RegInfo=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
A raw_ostream that writes to an SmallVector or SmallString.
A switch()-like statement whose cases are string literals.
@ UNWIND_ARM_FRAME_FIRST_PUSH_R6
This represents an "assembler immediate".
static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf, bool IsLittleEndian)
Optional< MCFixupKind > getFixupKind(StringRef Name) const override
Map a relocation name used in .reloc to a fixup kind.
@ FK_Data_2
A two-byte fixup.
Generic base class for all target subtargets.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
LLVM Value Representation.
static const char * checkPCRelOffset(uint64_t Value, int64_t Min, int64_t Max)
const MachO::CPUSubTypeARM Subtype
@ UNWIND_ARM_FRAME_SECOND_PUSH_R12