45 ARMELFObjectWriter(uint8_t OSABI)
58 {
"fixup_t2_ldst_pcrel_12", 0, 32,
63 {
"fixup_t2_pcrel_10", 0, 32,
67 {
"fixup_t2_pcrel_9", 0, 32,
70 {
"fixup_thumb_adr_pcrel_10", 0, 8,
74 {
"fixup_t2_adr_pcrel_12", 0, 32,
86 {
"fixup_arm_thumb_blx", 0, 32,
90 {
"fixup_arm_thumb_cp", 0, 8,
96 {
"fixup_arm_movt_hi16", 0, 20, 0},
97 {
"fixup_arm_movw_lo16", 0, 20, 0},
98 {
"fixup_t2_movt_hi16", 0, 20, 0},
99 {
"fixup_t2_movw_lo16", 0, 20, 0},
100 {
"fixup_arm_mod_imm", 0, 12, 0},
108 {
"fixup_t2_ldst_pcrel_12", 0, 32,
113 {
"fixup_t2_pcrel_10", 0, 32,
117 {
"fixup_t2_pcrel_9", 0, 32,
120 {
"fixup_thumb_adr_pcrel_10", 8, 8,
124 {
"fixup_t2_adr_pcrel_12", 0, 32,
136 {
"fixup_arm_thumb_blx", 0, 32,
140 {
"fixup_arm_thumb_cp", 8, 8,
146 {
"fixup_arm_movt_hi16", 12, 20, 0},
147 {
"fixup_arm_movw_lo16", 12, 20, 0},
148 {
"fixup_t2_movt_hi16", 12, 20, 0},
149 {
"fixup_t2_movw_lo16", 12, 20, 0},
150 {
"fixup_arm_mod_imm", 20, 12, 0},
176 bool HasV8MBaselineOps = STI->
getFeatureBits()[ARM::HasV8MBaselineOps];
182 return HasThumb2 ? (
unsigned)ARM::t2Bcc : Op;
184 return HasThumb2 ? (
unsigned)ARM::t2LDRpci : Op;
186 return HasThumb2 ? (
unsigned)ARM::t2ADR : Op;
188 return HasV8MBaselineOps ? (
unsigned)ARM::t2B : Op;
203 uint64_t
Value)
const {
204 switch ((
unsigned)Fixup.
getKind()) {
212 int64_t
Offset = int64_t(Value) - 4;
213 if (Offset > 2046 || Offset < -2048)
214 return "out of range pc-relative fixup value";
224 int64_t
Offset = int64_t(Value) - 4;
225 if (Offset > 254 || Offset < -256)
226 return "out of range pc-relative fixup value";
233 int64_t
Offset = int64_t(Value) - 4;
235 return "misaligned pc-relative fixup value";
236 else if (Offset > 1020 || Offset < 0)
237 return "out of range pc-relative fixup value";
244 int64_t
Offset = (Value & ~1);
246 return "will be converted to nop";
278 RelaxedOp == ARM::tHINT) {
293 const uint16_t Thumb1_16bitNopEncoding = 0x46c0;
294 const uint16_t Thumb2_16bitNopEncoding = 0xbf00;
295 const uint32_t ARMv4_NopEncoding = 0xe1a00000;
296 const uint32_t ARMv6T2_NopEncoding = 0xe320f000;
298 const uint16_t nopEncoding =
299 hasNOP() ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding;
300 uint64_t NumNops = Count / 2;
301 for (uint64_t
i = 0;
i != NumNops; ++
i)
309 hasNOP() ? ARMv6T2_NopEncoding : ARMv4_NopEncoding;
310 uint64_t NumNops = Count / 4;
311 for (uint64_t
i = 0;
i != NumNops; ++
i)
334 if (IsLittleEndian) {
337 uint32_t Swapped = (Value & 0xFFFF0000) >> 16;
338 Swapped |= (Value & 0x0000FFFF) << 16;
345 bool IsLittleEndian) {
348 if (IsLittleEndian) {
349 Value = (SecondHalf & 0xFFFF) << 16;
350 Value |= (FirstHalf & 0xFFFF);
352 Value = (SecondHalf & 0xFFFF);
353 Value |= (FirstHalf & 0xFFFF) << 16;
362 bool IsResolved)
const {
380 unsigned Hi4 = (Value & 0xF000) >> 12;
381 unsigned Lo12 = Value & 0x0FFF;
384 Value = (Hi4 << 16) | (Lo12);
392 unsigned Hi4 = (Value & 0xF000) >> 12;
393 unsigned i = (Value & 0x800) >> 11;
394 unsigned Mid3 = (Value & 0x700) >> 8;
395 unsigned Lo8 = Value & 0x0FF;
400 Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8);
411 if ((int64_t)Value < 0) {
415 if (Ctx && Value >= 4096) {
419 Value |= isAdd << 23;
432 if ((int64_t)Value < 0) {
447 if ((int64_t)Value < 0) {
453 out |= (Value & 0x800) << 15;
454 out |= (Value & 0x700) << 4;
455 out |= (Value & 0x0FF);
468 dyn_cast<MCSymbolRefExpr>(Fixup.
getValue()))
471 return 0xffffff & ((Value - 8) >> 2);
477 bool I = Value & 0x800000;
478 bool J1 = Value & 0x400000;
479 bool J2 = Value & 0x200000;
486 out |= (Value & 0x1FF800) << 5;
487 out |= (Value & 0x0007FF);
496 out |= (Value & 0x80000) << 7;
497 out |= (Value & 0x40000) >> 7;
498 out |= (Value & 0x20000) >> 4;
499 out |= (Value & 0x1F800) << 5;
500 out |= (Value & 0x007FF);
518 uint32_t signBit = (offset & 0x800000) >> 23;
519 uint32_t I1Bit = (offset & 0x400000) >> 22;
520 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
521 uint32_t I2Bit = (offset & 0x200000) >> 21;
522 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
523 uint32_t imm10Bits = (offset & 0x1FF800) >> 11;
524 uint32_t imm11Bits = (offset & 0x000007FF);
526 uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10Bits);
527 uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
528 (uint16_t)imm11Bits);
544 if (Ctx && Value % 4 != 0) {
551 dyn_cast<MCSymbolRefExpr>(Fixup.
getValue()))
554 uint32_t signBit = (offset & 0x400000) >> 22;
555 uint32_t I1Bit = (offset & 0x200000) >> 21;
556 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
557 uint32_t I2Bit = (offset & 0x100000) >> 20;
558 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
559 uint32_t imm10HBits = (offset & 0xFFC00) >> 10;
560 uint32_t imm10LBits = (offset & 0x3FF);
562 uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10HBits);
563 uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
564 ((uint16_t)imm10LBits) << 1);
571 if (Ctx && !STI->
getFeatureBits()[ARM::FeatureThumb2] && IsResolved) {
573 if (FixupDiagnostic) {
579 return ((Value - 4) >> 2) & 0xff;
591 return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3);
598 if (FixupDiagnostic) {
603 return ((Value - 4) >> 1) & 0x7ff;
608 if (FixupDiagnostic) {
613 return ((Value - 4) >> 1) & 0xff;
618 if ((int64_t)Value < 0) {
623 if (Ctx && Value >= 256) {
627 Value = (Value & 0xf) | ((Value & 0xf0) << 4);
628 return Value | (isAdd << 23);
638 if ((int64_t)Value < 0) {
644 if (Ctx && Value >= 256) {
648 Value |= isAdd << 23;
665 if ((int64_t)Value < 0) {
670 if (Ctx && (Value & 1)) {
675 if (Ctx && Value >= 256) {
679 Value |= isAdd << 23;
690 if (Ctx && Value >> 12) {
722 assert(Sym &&
"How did we resolve this?");
745 IsLittleEndian, IsResolved);
849 unsigned DataSize, uint64_t
Value,
850 bool IsPCRel)
const {
858 assert(Offset + NumBytes <= DataSize &&
"Invalid fixup offset!");
861 unsigned FullSizeBytes;
862 if (!IsLittleEndian) {
864 assert((Offset + FullSizeBytes) <= DataSize &&
"Invalid fixup size!");
865 assert(NumBytes <= FullSizeBytes &&
"Invalid fixup size!");
871 for (
unsigned i = 0;
i != NumBytes; ++
i) {
872 unsigned Idx = IsLittleEndian ?
i : (FullSizeBytes - 1 -
i);
873 Data[Offset + Idx] |= uint8_t((Value >> (
i * 8)) & 0xff);
919 int CFARegister = ARM::SP;
920 int CFARegisterOffset = 0;
923 int FloatRegCount = 0;
925 for (
size_t i = 0, e = Instrs.
size();
i != e; ++
i) {
941 if (ARMMCRegisterClasses[ARM::GPRRegClassID].
contains(Reg))
943 else if (ARMMCRegisterClasses[ARM::DPRRegClassID].
contains(Reg)) {
948 llvm::dbgs() <<
".cfi_offset on unknown register="
960 <<
"CFI directive not compatiable with comact "
969 if ((CFARegister == ARM::SP) && (CFARegisterOffset == 0))
973 if (CFARegister != ARM::R7) {
976 <<
" instead of r7\n");
979 int StackAdjust = CFARegisterOffset - 8;
980 if (RegOffsets.
lookup(ARM::LR) != (-4 - StackAdjust)) {
983 <<
"LR not saved as standard frame, StackAdjust="
985 <<
", CFARegisterOffset=" << CFARegisterOffset
986 <<
", lr save at offset=" << RegOffsets[14] <<
"\n");
989 if (RegOffsets.
lookup(ARM::R7) != (-8 - StackAdjust)) {
991 llvm::dbgs() <<
"r7 not saved as standard frame\n");
997 switch (StackAdjust) {
1001 CompactUnwindEncoding |= 0x00400000;
1004 CompactUnwindEncoding |= 0x00800000;
1007 CompactUnwindEncoding |= 0x00C00000;
1011 <<
".cfi_def_cfa stack adjust ("
1012 << StackAdjust <<
") out of range\n");
1029 int CurOffset = -8 - StackAdjust;
1030 for (
auto CSReg : GPRCSRegs) {
1035 int RegOffset =
Offset->second;
1036 if (RegOffset != CurOffset - 4) {
1039 << RegOffset <<
" but only supported at "
1040 << CurOffset <<
"\n");
1043 CompactUnwindEncoding |= CSReg.Encoding;
1048 if (FloatRegCount == 0)
1049 return CompactUnwindEncoding;
1057 if (FloatRegCount > 4) {
1059 llvm::dbgs() <<
"unsupported number of D registers saved ("
1060 << FloatRegCount <<
")\n");
1067 static unsigned FPRCSRegs[] = { ARM::D8, ARM::D10, ARM::D12, ARM::D14 };
1068 for (
int Idx = FloatRegCount - 1; Idx >= 0; --Idx) {
1069 auto Offset = RegOffsets.
find(FPRCSRegs[Idx]);
1072 llvm::dbgs() << FloatRegCount <<
" D-regs saved, but "
1073 << MRI.
getName(FPRCSRegs[Idx])
1076 }
else if (
Offset->second != CurOffset - 8) {
1078 llvm::dbgs() << FloatRegCount <<
" D-regs saved, but "
1079 << MRI.
getName(FPRCSRegs[Idx])
1080 <<
" saved at " <<
Offset->second
1081 <<
", expected at " << CurOffset - 8
1088 return CompactUnwindEncoding | ((FloatRegCount - 1) << 8);
1096 case ARM::AK_ARMV4T:
1098 case ARM::AK_ARMV5T:
1099 case ARM::AK_ARMV5TE:
1100 case ARM::AK_ARMV5TEJ:
1103 case ARM::AK_ARMV6K:
1105 case ARM::AK_ARMV7A:
1107 case ARM::AK_ARMV7S:
1109 case ARM::AK_ARMV7K:
1111 case ARM::AK_ARMV6M:
1113 case ARM::AK_ARMV7M:
1115 case ARM::AK_ARMV7EM:
1134 return new ARMAsmBackendWinCOFF(T, TheTriple);
1138 return new ARMAsmBackendELF(T, TheTriple, OSABI, isLittle);
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
unsigned getNumFixupKinds() const override
Get the number of target specific fixup kinds.
const MCSymbol & getSymbol() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
This represents an "assembler immediate".
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCAsmBackend * createARMAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, const MCTargetOptions &Options, bool IsLittleEndian)
MCAsmBackend * createThumbLEAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, const MCTargetOptions &Options)
A raw_ostream that writes to an SmallVector or SmallString.
const char * reasonForFixupRelaxation(const MCFixup &Fixup, uint64_t Value) const
unsigned getRelaxedOpcode(unsigned Op) const
MCContext & getContext() const
Defines the object file and target independent interfaces used by the assembler backend to write nati...
void write8(uint8_t Value)
unsigned getRegister() const
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.
return AArch64::GPR64RegClass contains(Reg)
bool isOSWindows() const
Tests whether the OS is Windows.
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...
#define DEBUG_WITH_TYPE(TYPE, X)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, bool IsPCRel, MCContext *Ctx, bool IsLittleEndian, bool IsResolved) const
static MCOperand createReg(unsigned Reg)
static MachO::CPUSubTypeARM getMachOSubTypeFromArch(StringRef Arch)
Encapsulates the layout of an assembly file at a particular point in time.
Reg
All possible values of the reg field in the ModR/M byte.
Represent a reference to a symbol from inside an expression.
ObjectFormatType getObjectFormat() const
getFormat - Get the object format for this triple.
bool mayNeedRelaxation(const MCInst &Inst) const override
Check whether the given instruction may need relaxation.
A four-byte section relative fixup.
Context object for machine code objects.
A two-byte section relative fixup.
.code16 (X86) / .code 16 (ARM)
Function Alias Analysis false
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
bool isThumbFunc(const MCSymbol *Func) const
Check whether a given symbol has been flagged with .thumb_func.
void processFixupValue(const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFixup &Fixup, const MCFragment *DF, const MCValue &Target, uint64_t &Value, bool &IsResolved) override
processFixupValue - Target hook to process the literal value of a fixup if necessary.
uint32_t getOffset() const
size_t size() const
size - Get the array size.
Instances of this class represent a single low-level machine instruction.
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
uint32_t generateCompactUnwindEncoding(ArrayRef< MCCFIInstruction > Instrs) const override
Generate compact unwind encoding for the function based on the CFI instructions.
unsigned const MachineRegisterInfo * MRI
CompactUnwindEncodings
Compact unwind encoding values.
static uint32_t swapHalfWords(uint32_t Value, bool IsLittleEndian)
MCAsmBackend * createARMBEAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, const MCTargetOptions &Options)
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.
const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const override
Get information on a fixup kind.
void reportError(SMLoc L, const Twine &Msg)
Should this fixup kind force a 4-byte aligned effective PC value?
MCAsmBackend * createARMLEAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, const MCTargetOptions &Options)
bool empty() const
empty - Check if the array is empty.
int getLLVMRegNum(unsigned RegNum, bool isEH) const
Map a dwarf register back to a target register.
MCFixupKind getKind() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
void write16(uint16_t Value)
OpType getOperation() const
static unsigned getFixupKindContainerSizeBytes(unsigned Kind)
getFixupKindContainerSizeBytes - The number of bytes of the container involved in big endian...
const MachO::CPUSubTypeARM Subtype
void setOpcode(unsigned Op)
const MCSymbolRefExpr * getSymA() const
void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, uint64_t Value, bool IsPCRel) const override
Apply the Value for given Fixup into the provided data fragment, at the offset specified by the fixup...
bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override
Write an (optimal) nop sequence of Count bytes to the given output.
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.
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
MCAsmBackend * createThumbBEAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, const MCTargetOptions &Options)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getOpcode() const
Target - Wrapper for Target specific information.
static int getSOImmVal(unsigned Arg)
getSOImmVal - Given a 32-bit immediate, if it is something that can fit into an shifter_operand immed...
.code32 (X86) / .code 32 (ARM)
void handleAssemblerFlag(MCAssemblerFlag Flag) override
Handle any target-specific assembler flags. By default, do nothing.
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
StringRef getArchName() const
getArchName - Get the architecture (first) component of the triple.
MCSubtargetInfo - Generic base class for all target subtargets.
iterator find(const KeyT &Val)
unsigned parseArch(StringRef Arch)
Target independent information on a fixup kind.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Generic interface to target specific assembler backends.
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
const char * getName(unsigned RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register...
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
static unsigned getFixupKindNumBytes(unsigned Kind)
getFixupKindNumBytes - The number of bytes the fixup may change.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
static MCOperand createImm(int64_t Val)
static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf, bool IsLittleEndian)