43 ARMELFObjectWriter(uint8_t OSABI)
56 {
"fixup_t2_ldst_pcrel_12", 0, 32,
61 {
"fixup_t2_pcrel_10", 0, 32,
65 {
"fixup_t2_pcrel_9", 0, 32,
68 {
"fixup_thumb_adr_pcrel_10", 0, 8,
72 {
"fixup_t2_adr_pcrel_12", 0, 32,
84 {
"fixup_arm_thumb_blx", 0, 32,
88 {
"fixup_arm_thumb_cp", 0, 8,
94 {
"fixup_arm_movt_hi16", 0, 20, 0},
95 {
"fixup_arm_movw_lo16", 0, 20, 0},
96 {
"fixup_t2_movt_hi16", 0, 20, 0},
97 {
"fixup_t2_movw_lo16", 0, 20, 0},
98 {
"fixup_arm_mod_imm", 0, 12, 0},
99 {
"fixup_t2_so_imm", 0, 26, 0},
107 {
"fixup_t2_ldst_pcrel_12", 0, 32,
112 {
"fixup_t2_pcrel_10", 0, 32,
116 {
"fixup_t2_pcrel_9", 0, 32,
119 {
"fixup_thumb_adr_pcrel_10", 8, 8,
123 {
"fixup_t2_adr_pcrel_12", 0, 32,
135 {
"fixup_arm_thumb_blx", 0, 32,
139 {
"fixup_arm_thumb_cp", 8, 8,
145 {
"fixup_arm_movt_hi16", 12, 20, 0},
146 {
"fixup_arm_movw_lo16", 12, 20, 0},
147 {
"fixup_t2_movt_hi16", 12, 20, 0},
148 {
"fixup_t2_movw_lo16", 12, 20, 0},
149 {
"fixup_arm_mod_imm", 20, 12, 0},
150 {
"fixup_t2_so_imm", 26, 6, 0},
178 bool HasV8MBaselineOps = STI.
getFeatureBits()[ARM::HasV8MBaselineOps];
184 return HasThumb2 ? (
unsigned)ARM::t2Bcc : Op;
186 return HasThumb2 ? (
unsigned)ARM::t2LDRpci : Op;
188 return HasThumb2 ? (
unsigned)ARM::t2ADR : Op;
190 return HasV8MBaselineOps ? (
unsigned)ARM::t2B : Op;
206 uint64_t
Value)
const {
207 switch ((
unsigned)Fixup.
getKind()) {
215 int64_t
Offset = int64_t(Value) - 4;
216 if (Offset > 2046 || Offset < -2048)
217 return "out of range pc-relative fixup value";
227 int64_t
Offset = int64_t(Value) - 4;
228 if (Offset > 254 || Offset < -256)
229 return "out of range pc-relative fixup value";
236 int64_t
Offset = int64_t(Value) - 4;
238 return "misaligned pc-relative fixup value";
239 else if (Offset > 1020 || Offset < 0)
240 return "out of range pc-relative fixup value";
247 int64_t
Offset = (Value & ~1);
249 return "will be converted to nop";
261 return reasonForFixupRelaxation(Fixup, Value);
281 RelaxedOp == ARM::tHINT) {
296 const uint16_t Thumb1_16bitNopEncoding = 0x46c0;
297 const uint16_t Thumb2_16bitNopEncoding = 0xbf00;
298 const uint32_t ARMv4_NopEncoding = 0xe1a00000;
299 const uint32_t ARMv6T2_NopEncoding = 0xe320f000;
301 const uint16_t nopEncoding =
302 hasNOP() ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding;
303 uint64_t NumNops = Count / 2;
304 for (uint64_t i = 0; i != NumNops; ++i)
312 hasNOP() ? ARMv6T2_NopEncoding : ARMv4_NopEncoding;
313 uint64_t NumNops = Count / 4;
314 for (uint64_t i = 0; i != NumNops; ++i)
328 OS.
write(
"\0\0\xa0", 3);
336 if (IsLittleEndian) {
339 uint32_t Swapped = (Value & 0xFFFF0000) >> 16;
340 Swapped |= (Value & 0x0000FFFF) << 16;
347 bool IsLittleEndian) {
350 if (IsLittleEndian) {
351 Value = (SecondHalf & 0xFFFF) << 16;
352 Value |= (FirstHalf & 0xFFFF);
354 Value = (SecondHalf & 0xFFFF);
355 Value |= (FirstHalf & 0xFFFF) << 16;
374 if (A->hasSubsectionsViaSymbols() && Asm.
isThumbFunc(&A->getSymbol()) &&
375 A->getSymbol().isExternal() &&
400 unsigned Hi4 = (Value & 0xF000) >> 12;
401 unsigned Lo12 = Value & 0x0FFF;
404 Value = (Hi4 << 16) | (Lo12);
413 unsigned Hi4 = (Value & 0xF000) >> 12;
414 unsigned i = (Value & 0x800) >> 11;
415 unsigned Mid3 = (Value & 0x700) >> 8;
416 unsigned Lo8 = Value & 0x0FF;
421 Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8);
432 if ((int64_t)Value < 0) {
440 Value |= isAdd << 23;
453 if ((int64_t)Value < 0) {
468 if ((int64_t)Value < 0) {
474 out |= (Value & 0x800) << 15;
475 out |= (Value & 0x700) << 4;
476 out |= (Value & 0x0FF);
489 dyn_cast<MCSymbolRefExpr>(Fixup.
getValue()))
492 return 0xffffff & ((Value - 8) >> 2);
495 if (!isInt<25>(Value)) {
503 bool I = Value & 0x800000;
504 bool J1 = Value & 0x400000;
505 bool J2 = Value & 0x200000;
512 out |= (Value & 0x1FF800) << 5;
513 out |= (Value & 0x0007FF);
519 if (!isInt<21>(Value)) {
527 out |= (Value & 0x80000) << 7;
528 out |= (Value & 0x40000) >> 7;
529 out |= (Value & 0x20000) >> 4;
530 out |= (Value & 0x1F800) << 5;
531 out |= (Value & 0x007FF);
536 if (!isInt<25>(Value - 4) ||
540 !isInt<23>(Value - 4))) {
558 uint32_t signBit = (offset & 0x800000) >> 23;
559 uint32_t I1Bit = (offset & 0x400000) >> 22;
560 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
561 uint32_t I2Bit = (offset & 0x200000) >> 21;
562 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
563 uint32_t imm10Bits = (offset & 0x1FF800) >> 11;
564 uint32_t imm11Bits = (offset & 0x000007FF);
566 uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10Bits);
567 uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
568 (uint16_t)imm11Bits);
584 if (Value % 4 != 0) {
591 dyn_cast<MCSymbolRefExpr>(Fixup.
getValue()))
594 uint32_t signBit = (offset & 0x400000) >> 22;
595 uint32_t I1Bit = (offset & 0x200000) >> 21;
596 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
597 uint32_t I2Bit = (offset & 0x100000) >> 20;
598 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
599 uint32_t imm10HBits = (offset & 0xFFC00) >> 10;
600 uint32_t imm10LBits = (offset & 0x3FF);
602 uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10HBits);
603 uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
604 ((uint16_t)imm10LBits) << 1);
613 const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
614 if (FixupDiagnostic) {
620 return ((Value - 4) >> 2) & 0xff;
632 return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3);
639 const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
640 if (FixupDiagnostic) {
645 return ((Value - 4) >> 1) & 0x7ff;
650 const char *FixupDiagnostic = reasonForFixupRelaxation(Fixup, Value);
651 if (FixupDiagnostic) {
656 return ((Value - 4) >> 1) & 0xff;
661 if ((int64_t)Value < 0) {
670 Value = (Value & 0xf) | ((Value & 0xf0) << 4);
671 return Value | (isAdd << 23);
681 if ((int64_t)Value < 0) {
691 Value |= isAdd << 23;
708 if ((int64_t)Value < 0) {
722 Value |= isAdd << 23;
740 if ((int64_t)Value < 0) {
749 uint64_t EncValue = 0;
750 EncValue |= (Value & 0x800) << 15;
751 EncValue |= (Value & 0x700) << 4;
752 EncValue |= (Value & 0xff);
765 assert(Sym &&
"How did we resolve this?");
777 if (Sym && Sym->
isELF()) {
914 assert(Offset + NumBytes <= Data.
size() &&
"Invalid fixup offset!");
917 unsigned FullSizeBytes;
920 assert((Offset + FullSizeBytes) <= Data.
size() &&
"Invalid fixup size!");
921 assert(NumBytes <= FullSizeBytes &&
"Invalid fixup size!");
927 for (
unsigned i = 0; i != NumBytes; ++i) {
928 unsigned Idx = Endian ==
support::little ? i : (FullSizeBytes - 1 - i);
929 Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
975 int CFARegister = ARM::SP;
976 int CFARegisterOffset = 0;
979 int FloatRegCount = 0;
981 for (
size_t i = 0, e = Instrs.
size(); i != e; ++i) {
997 if (ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(Reg))
999 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(Reg)) {
1004 llvm::dbgs() <<
".cfi_offset on unknown register=" 1016 <<
"CFI directive not compatiable with comact " 1025 if ((CFARegister == ARM::SP) && (CFARegisterOffset == 0))
1029 if (CFARegister != ARM::R7) {
1032 <<
" instead of r7\n");
1035 int StackAdjust = CFARegisterOffset - 8;
1036 if (RegOffsets.
lookup(ARM::LR) != (-4 - StackAdjust)) {
1039 <<
"LR not saved as standard frame, StackAdjust=" 1041 <<
", CFARegisterOffset=" << CFARegisterOffset
1042 <<
", lr save at offset=" << RegOffsets[14] <<
"\n");
1045 if (RegOffsets.
lookup(ARM::R7) != (-8 - StackAdjust)) {
1047 llvm::dbgs() <<
"r7 not saved as standard frame\n");
1053 switch (StackAdjust) {
1057 CompactUnwindEncoding |= 0x00400000;
1060 CompactUnwindEncoding |= 0x00800000;
1063 CompactUnwindEncoding |= 0x00C00000;
1067 <<
".cfi_def_cfa stack adjust (" 1068 << StackAdjust <<
") out of range\n");
1085 int CurOffset = -8 - StackAdjust;
1086 for (
auto CSReg : GPRCSRegs) {
1091 int RegOffset =
Offset->second;
1092 if (RegOffset != CurOffset - 4) {
1095 << RegOffset <<
" but only supported at " 1096 << CurOffset <<
"\n");
1099 CompactUnwindEncoding |= CSReg.Encoding;
1104 if (FloatRegCount == 0)
1105 return CompactUnwindEncoding;
1113 if (FloatRegCount > 4) {
1115 llvm::dbgs() <<
"unsupported number of D registers saved (" 1116 << FloatRegCount <<
")\n");
1123 static unsigned FPRCSRegs[] = { ARM::D8, ARM::D10, ARM::D12, ARM::D14 };
1124 for (
int Idx = FloatRegCount - 1; Idx >= 0; --Idx) {
1125 auto Offset = RegOffsets.
find(FPRCSRegs[Idx]);
1128 llvm::dbgs() << FloatRegCount <<
" D-regs saved, but " 1129 <<
MRI.getName(FPRCSRegs[Idx])
1132 }
else if (
Offset->second != CurOffset - 8) {
1134 llvm::dbgs() << FloatRegCount <<
" D-regs saved, but " 1135 <<
MRI.getName(FPRCSRegs[Idx])
1136 <<
" saved at " <<
Offset->second
1137 <<
", expected at " << CurOffset - 8
1144 return CompactUnwindEncoding | ((FloatRegCount - 1) << 8);
1152 case ARM::ArchKind::ARMV4T:
1154 case ARM::ArchKind::ARMV5T:
1155 case ARM::ArchKind::ARMV5TE:
1156 case ARM::ArchKind::ARMV5TEJ:
1158 case ARM::ArchKind::ARMV6:
1159 case ARM::ArchKind::ARMV6K:
1161 case ARM::ArchKind::ARMV7A:
1163 case ARM::ArchKind::ARMV7S:
1165 case ARM::ArchKind::ARMV7K:
1167 case ARM::ArchKind::ARMV6M:
1169 case ARM::ArchKind::ARMV7M:
1171 case ARM::ArchKind::ARMV7EM:
1191 return new ARMAsmBackendWinCOFF(T, STI);
1195 return new ARMAsmBackendELF(T, STI, OSABI, Endian);
MCAsmBackend * createARMLEAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
unsigned getRelaxedOpcode(unsigned Op, const MCSubtargetInfo &STI) const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
This represents an "assembler immediate".
const char * reasonForFixupRelaxation(const MCFixup &Fixup, uint64_t Value) const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
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.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ") 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.
static Lanai::Fixups FixupKind(const MCExpr *Expr)
static bool isThumb(const MCSubtargetInfo &STI)
return AArch64::GPR64RegClass contains(Reg)
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...
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
MCContext & getContext() const
static MCOperand createReg(unsigned Reg)
const FeatureBitset & getFeatureBits() const
static MachO::CPUSubTypeARM getMachOSubTypeFromArch(StringRef Arch)
Encapsulates the layout of an assembly file at a particular point in time.
Represent a reference to a symbol from inside an expression.
A four-byte section relative fixup.
Context object for machine code objects.
A two-byte section relative fixup.
.code16 (X86) / .code 16 (ARM)
MCAsmBackend * createARMBEAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Instances of this class represent a single low-level machine instruction.
static MCAsmBackend * createARMAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options, support::endianness Endian)
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...
iterator find(const_arg_type_t< KeyT > Val)
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
bool isOSWindows() const
Tests whether the OS is Windows.
A relaxable fragment holds on to its MCInst, since it may need to be relaxed during the assembler lay...
uint32_t generateCompactUnwindEncoding(ArrayRef< MCCFIInstruction > Instrs) const override
Generate compact unwind encoding for the function based on the CFI instructions.
unsigned const MachineRegisterInfo * MRI
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
The instances of the Type class are immutable: once they are created, they are never changed...
CompactUnwindEncodings
Compact unwind encoding values.
static uint32_t swapHalfWords(uint32_t Value, bool IsLittleEndian)
size_t size() const
size - Get the array size.
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.
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)
const MCSymbolRefExpr * getSymA() const
OpType getOperation() const
const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const override
Get information on a fixup kind.
int getT2SOImmVal(unsigned Arg)
getT2SOImmVal - Given a 32-bit immediate, if it is something that can fit into a Thumb-2 shifter_oper...
void reportError(SMLoc L, const Twine &Msg)
Should this fixup kind force a 4-byte aligned effective PC value?
uint32_t getOffset() const
unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, uint64_t Value, bool IsResolved, MCContext &Ctx, const MCSubtargetInfo *STI) const
bool writeNopData(raw_ostream &OS, uint64_t Count) const override
Write an (optimal) nop sequence of Count bytes to the given output.
static wasm::ValType getType(const TargetRegisterClass *RC)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
raw_ostream & write(unsigned char C)
unsigned getRegister() const
static unsigned getFixupKindContainerSizeBytes(unsigned Kind)
getFixupKindContainerSizeBytes - The number of bytes of the container involved in big endian...
StringRef getArchName() const
getArchName - Get the architecture (first) component of the triple.
void setOpcode(unsigned Op)
int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
ArchKind parseArch(StringRef Arch)
const MCSymbol & getSymbol() const
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, MCInst &Res) const override
Relax the instruction in the given fragment to the next wider instruction.
StringRef str()
Return a StringRef for the vector contents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Target - Wrapper for Target specific information.
bool isThumbFunc(const MCSymbol *Func) const
Check whether a given symbol has been flagged with .thumb_func.
.code32 (X86) / .code 32 (ARM)
void handleAssemblerFlag(MCAssemblerFlag Flag) override
Handle any target-specific assembler flags. By default, do nothing.
ObjectFormatType getObjectFormat() const
getFormat - Get the object format for this triple.
static unsigned getRelaxedOpcode(const MCInst &Inst, bool is16BitMode)
Generic base class for all target subtargets.
Target independent information on a fixup kind.
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...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool mayNeedRelaxation(const MCInst &Inst, const MCSubtargetInfo &STI) const override
Check whether the given instruction may need relaxation.
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...
LLVM Value Representation.
Generic interface to target specific assembler backends.
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
This class implements an extremely fast bulk output stream that can only output to a stream...
const MCExpr * getValue() const
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
unsigned getOpcode() const
static unsigned getFixupKindNumBytes(unsigned Kind)
getFixupKindNumBytes - The number of bytes the fixup may change.
static MCOperand createImm(int64_t Val)
static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf, bool IsLittleEndian)
MCFixupKind getKind() const
bool empty() const
empty - Check if the array is empty.
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.