41 ARMELFObjectWriter(uint8_t OSABI)
53 {
"fixup_t2_ldst_pcrel_12", 0, 32,
58 {
"fixup_t2_pcrel_10", 0, 32,
61 {
"fixup_thumb_adr_pcrel_10", 0, 8,
65 {
"fixup_t2_adr_pcrel_12", 0, 32,
79 {
"fixup_arm_thumb_cp", 0, 8,
85 {
"fixup_arm_movt_hi16", 0, 20, 0},
86 {
"fixup_arm_movw_lo16", 0, 20, 0},
87 {
"fixup_t2_movt_hi16", 0, 20, 0},
88 {
"fixup_t2_movw_lo16", 0, 20, 0},
96 {
"fixup_t2_ldst_pcrel_12", 0, 32,
101 {
"fixup_t2_pcrel_10", 0, 32,
104 {
"fixup_thumb_adr_pcrel_10", 8, 8,
108 {
"fixup_t2_adr_pcrel_12", 0, 32,
122 {
"fixup_arm_thumb_cp", 8, 8,
128 {
"fixup_arm_movt_hi16", 12, 20, 0},
129 {
"fixup_arm_movw_lo16", 12, 20, 0},
130 {
"fixup_t2_movt_hi16", 12, 20, 0},
131 {
"fixup_t2_movw_lo16", 12, 20, 0},
157 bool HasThumb2 = STI->getFeatureBits()[ARM::FeatureThumb2];
163 return HasThumb2 ? (
unsigned)ARM::t2Bcc : Op;
165 return HasThumb2 ? (
unsigned)ARM::t2LDRpci : Op;
167 return HasThumb2 ? (
unsigned)ARM::t2ADR : Op;
169 return HasThumb2 ? (
unsigned)ARM::t2B : Op;
177 bool ARMAsmBackend::mayNeedRelaxation(
const MCInst &Inst)
const {
186 switch ((
unsigned)Fixup.
getKind()) {
194 int64_t Offset = int64_t(Value) - 4;
195 return Offset > 2046 || Offset < -2048;
204 int64_t Offset = int64_t(Value) - 4;
205 return Offset > 254 || Offset < -256;
211 int64_t Offset = int64_t(Value) - 4;
212 return Offset > 1020 || Offset < 0 || Offset & 3;
218 int64_t Offset = (Value & ~1);
224 void ARMAsmBackend::relaxInstruction(
const MCInst &Inst,
MCInst &Res)
const {
239 RelaxedOp == ARM::tHINT) {
253 bool ARMAsmBackend::writeNopData(uint64_t Count,
MCObjectWriter *OW)
const {
254 const uint16_t Thumb1_16bitNopEncoding = 0x46c0;
255 const uint16_t Thumb2_16bitNopEncoding = 0xbf00;
256 const uint32_t ARMv4_NopEncoding = 0xe1a00000;
257 const uint32_t ARMv6T2_NopEncoding = 0xe320f000;
259 const uint16_t nopEncoding =
260 hasNOP() ? Thumb2_16bitNopEncoding : Thumb1_16bitNopEncoding;
261 uint64_t NumNops = Count / 2;
262 for (uint64_t i = 0; i != NumNops; ++i)
269 const uint32_t nopEncoding =
270 hasNOP() ? ARMv6T2_NopEncoding : ARMv4_NopEncoding;
271 uint64_t NumNops = Count / 4;
272 for (uint64_t i = 0; i != NumNops; ++i)
295 if (IsLittleEndian) {
298 uint32_t Swapped = (Value & 0xFFFF0000) >> 16;
299 Swapped |= (Value & 0x0000FFFF) << 16;
306 bool IsLittleEndian) {
309 if (IsLittleEndian) {
310 Value = (SecondHalf & 0xFFFF) << 16;
311 Value |= (FirstHalf & 0xFFFF);
313 Value = (SecondHalf & 0xFFFF);
314 Value |= (FirstHalf & 0xFFFF) << 16;
322 bool IsLittleEndian) {
323 unsigned Kind = Fixup.
getKind();
340 unsigned Hi4 = (Value & 0xF000) >> 12;
341 unsigned Lo12 = Value & 0x0FFF;
344 Value = (Hi4 << 16) | (Lo12);
352 unsigned Hi4 = (Value & 0xF000) >> 12;
353 unsigned i = (Value & 0x800) >> 11;
354 unsigned Mid3 = (Value & 0x700) >> 8;
355 unsigned Lo8 = Value & 0x0FF;
360 Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8);
371 if ((int64_t)Value < 0) {
375 if (Ctx && Value >= 4096)
377 Value |= isAdd << 23;
387 return ((Value - 4) >> 2) & 0xff;
392 if ((int64_t)Value < 0) {
405 if ((int64_t)Value < 0) {
410 uint32_t out = (opc << 21);
411 out |= (Value & 0x800) << 15;
412 out |= (Value & 0x700) << 4;
413 out |= (Value & 0x0FF);
426 dyn_cast<MCSymbolRefExpr>(Fixup.
getValue()))
429 return 0xffffff & ((Value - 8) >> 2);
435 bool I = Value & 0x800000;
436 bool J1 = Value & 0x400000;
437 bool J2 = Value & 0x200000;
444 out |= (Value & 0x1FF800) << 5;
445 out |= (Value & 0x0007FF);
454 out |= (Value & 0x80000) << 7;
455 out |= (Value & 0x40000) >> 7;
456 out |= (Value & 0x20000) >> 4;
457 out |= (Value & 0x1F800) << 5;
458 out |= (Value & 0x007FF);
475 uint32_t offset = (Value - 4) >> 1;
476 uint32_t signBit = (offset & 0x800000) >> 23;
477 uint32_t I1Bit = (offset & 0x400000) >> 22;
478 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
479 uint32_t I2Bit = (offset & 0x200000) >> 21;
480 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
481 uint32_t imm10Bits = (offset & 0x1FF800) >> 11;
482 uint32_t imm11Bits = (offset & 0x000007FF);
484 uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10Bits);
485 uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
486 (uint16_t)imm11Bits);
502 uint32_t offset = (Value - 2) >> 2;
504 dyn_cast<MCSymbolRefExpr>(Fixup.
getValue()))
507 uint32_t signBit = (offset & 0x400000) >> 22;
508 uint32_t I1Bit = (offset & 0x200000) >> 21;
509 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
510 uint32_t I2Bit = (offset & 0x100000) >> 20;
511 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
512 uint32_t imm10HBits = (offset & 0xFFC00) >> 10;
513 uint32_t imm10LBits = (offset & 0x3FF);
515 uint32_t FirstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10HBits);
516 uint32_t SecondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
517 ((uint16_t)imm10LBits) << 1);
524 return ((Value - 2) >> 2) & 0xff;
527 uint32_t
Binary = (Value - 4) >> 1;
528 return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3);
532 return ((Value - 4) >> 1) & 0x7ff;
535 return ((Value - 4) >> 1) & 0xff;
540 if ((int64_t)Value < 0) {
545 if (Ctx && Value >= 256)
547 Value = (Value & 0xf) | ((Value & 0xf0) << 4);
548 return Value | (isAdd << 23);
558 if ((int64_t)Value < 0) {
564 if (Ctx && Value >= 256)
566 Value |= isAdd << 23;
718 void ARMAsmBackend::applyFixup(
const MCFixup &Fixup,
char *Data,
719 unsigned DataSize, uint64_t Value,
720 bool IsPCRel)
const {
727 assert(Offset + NumBytes <= DataSize &&
"Invalid fixup offset!");
730 unsigned FullSizeBytes;
731 if (!IsLittleEndian) {
733 assert((Offset + FullSizeBytes) <= DataSize &&
"Invalid fixup size!");
734 assert(NumBytes <= FullSizeBytes &&
"Invalid fixup size!");
740 for (
unsigned i = 0; i != NumBytes; ++i) {
741 unsigned Idx = IsLittleEndian ? i : (FullSizeBytes - 1 - i);
742 Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
766 return new ARMAsmBackendDarwin(T, TheTriple, CS);
769 assert(TheTriple.
isOSWindows() &&
"non-Windows ARM COFF is not supported");
770 return new ARMAsmBackendWinCOFF(T, TheTriple);
774 return new ARMAsmBackendELF(T, TheTriple, OSABI, isLittle);
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
const MCSymbol & getSymbol() const
This represents an "assembler immediate".
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L, const Twine &Msg) const
A raw_ostream that writes to an SmallVector or SmallString.
MCContext & getContext() const
Defines the object file and target independent interfaces used by the assembler backend to write nati...
static bool isThumb(const MCSubtargetInfo &STI)
void write8(uint8_t Value)
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.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
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...
static MCOperand createReg(unsigned Reg)
Encapsulates the layout of an assembly file at a particular point in time.
static unsigned getRelaxedOpcode(unsigned Op)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Represent a reference to a symbol from inside an expression.
ObjectFormatType getObjectFormat() const
getFormat - Get the object format for this triple.
A four-byte section relative fixup.
Context object for machine code objects.
MCAsmBackend * createARMLEAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU)
A two-byte section relative fixup.
.code16 (X86) / .code 16 (ARM)
MCAsmBackend * createThumbBEAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU)
MCAsmBackend * createARMAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, bool IsLittleEndian)
bool isThumbFunc(const MCSymbol *Func) const
Check whether a given symbol has been flagged with .thumb_func.
uint32_t getOffset() const
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)
A switch()-like statement whose cases are string literals.
const MCExpr * getValue() const
static uint32_t swapHalfWords(uint32_t Value, bool IsLittleEndian)
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Should this fixup kind force a 4-byte aligned effective PC value?
MCFragment * getFragment() const
MCFixupKind getKind() const
Triple - Helper class for working with autoconf configuration names.
void write16(uint16_t Value)
PowerPC TLS Dynamic Call Fixup
static unsigned getFixupKindContainerSizeBytes(unsigned Kind)
getFixupKindContainerSizeBytes - The number of bytes of the container involved in big endian...
void setOpcode(unsigned Op)
const MCSymbolRefExpr * getSymA() const
R Default(const T &Value) const
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)
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
StringRef getArchName() const
getArchName - Get the architecture (first) component of the triple.
Target independent information on a fixup kind.
const ARM::ArchExtKind Kind
static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, bool IsPCRel, MCContext *Ctx, bool IsLittleEndian)
LLVM Value Representation.
MCAsmBackend * createThumbLEAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU)
MCAsmBackend * createARMBEAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU)
Generic interface to target specific assembler backends.
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const T &Value)
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 MCOperand createImm(int64_t Val)
static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf, bool IsLittleEndian)