37 ARMELFObjectWriter(uint8_t OSABI)
48 isThumbMode(TT.startswith(
"thumb")) {}
57 return (STI->getFeatureBits() & ARM::HasV6T2Ops) != 0;
93 {
"fixup_arm_movt_hi16", 0, 20, 0 },
94 {
"fixup_arm_movw_lo16", 0, 20, 0 },
95 {
"fixup_t2_movt_hi16", 0, 20, 0 },
96 {
"fixup_t2_movw_lo16", 0, 20, 0 },
119 void applyFixup(
const MCFixup &Fixup,
char *Data,
unsigned DataSize,
120 uint64_t
Value)
const;
122 bool mayNeedRelaxation(
const MCInst &Inst)
const;
124 bool fixupNeedsRelaxation(
const MCFixup &Fixup,
129 void relaxInstruction(
const MCInst &Inst,
MCInst &Res)
const;
146 bool isThumb()
const {
return isThumbMode; }
147 void setIsThumb(
bool it) { isThumbMode = it; }
154 case ARM::tBcc:
return ARM::t2Bcc;
155 case ARM::tLDRpci:
return ARM::t2LDRpci;
156 case ARM::tADR:
return ARM::t2ADR;
157 case ARM::tB:
return ARM::t2B;
161 bool ARMAsmBackend::mayNeedRelaxation(
const MCInst &Inst)
const {
167 bool ARMAsmBackend::fixupNeedsRelaxation(
const MCFixup &Fixup,
171 switch ((
unsigned)Fixup.
getKind()) {
179 int64_t Offset = int64_t(Value) - 4;
180 return Offset > 2046 || Offset < -2048;
189 int64_t Offset = int64_t(Value) - 4;
190 return Offset > 254 || Offset < -256;
196 int64_t Offset = int64_t(Value) - 4;
197 return Offset > 1020 || Offset < 0 || Offset & 3;
203 void ARMAsmBackend::relaxInstruction(
const MCInst &Inst,
MCInst &Res)
const {
221 bool ARMAsmBackend::writeNopData(uint64_t Count,
MCObjectWriter *OW)
const {
222 const uint16_t Thumb1_16bitNopEncoding = 0x46c0;
223 const uint16_t Thumb2_16bitNopEncoding = 0xbf00;
224 const uint32_t ARMv4_NopEncoding = 0xe1a00000;
225 const uint32_t ARMv6T2_NopEncoding = 0xe320f000;
227 const uint16_t nopEncoding = hasNOP() ? Thumb2_16bitNopEncoding
228 : Thumb1_16bitNopEncoding;
229 uint64_t NumNops = Count / 2;
230 for (uint64_t i = 0; i != NumNops; ++i)
237 const uint32_t nopEncoding = hasNOP() ? ARMv6T2_NopEncoding
239 uint64_t NumNops = Count / 4;
240 for (uint64_t i = 0; i != NumNops; ++i)
246 case 1: OW->
Write8(0);
break;
256 unsigned Kind = Fixup.
getKind();
270 unsigned Hi4 = (Value & 0xF000) >> 12;
271 unsigned Lo12 = Value & 0x0FFF;
274 Value = (Hi4 << 16) | (Lo12);
284 unsigned Hi4 = (Value & 0xF000) >> 12;
285 unsigned i = (Value & 0x800) >> 11;
286 unsigned Mid3 = (Value & 0x700) >> 8;
287 unsigned Lo8 = Value & 0x0FF;
292 Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8);
293 uint64_t swapped = (Value & 0xFFFF0000) >> 16;
294 swapped |= (Value & 0x0000FFFF) << 16;
305 if ((int64_t)Value < 0) {
309 if (Ctx && Value >= 4096)
310 Ctx->FatalError(Fixup.
getLoc(),
"out of range pc-relative fixup value");
311 Value |= isAdd << 23;
316 uint64_t swapped = (Value & 0xFFFF0000) >> 16;
317 swapped |= (Value & 0x0000FFFF) << 16;
324 return ((Value - 4) >> 2) & 0xff;
329 if ((int64_t)Value < 0) {
334 Ctx->FatalError(Fixup.
getLoc(),
"out of range pc-relative fixup value");
342 if ((int64_t)Value < 0) {
347 uint32_t out = (opc << 21);
348 out |= (Value & 0x800) << 15;
349 out |= (Value & 0x700) << 4;
350 out |= (Value & 0x0FF);
352 uint64_t swapped = (out & 0xFFFF0000) >> 16;
353 swapped |= (out & 0x0000FFFF) << 16;
364 return 0xffffff & ((Value - 8) >> 2);
370 bool I = Value & 0x800000;
371 bool J1 = Value & 0x400000;
372 bool J2 = Value & 0x200000;
379 out |= (Value & 0x1FF800) << 5;
380 out |= (Value & 0x0007FF);
382 uint64_t swapped = (out & 0xFFFF0000) >> 16;
383 swapped |= (out & 0x0000FFFF) << 16;
391 out |= (Value & 0x80000) << 7;
392 out |= (Value & 0x40000) >> 7;
393 out |= (Value & 0x20000) >> 4;
394 out |= (Value & 0x1F800) << 5;
395 out |= (Value & 0x007FF);
397 uint32_t swapped = (out & 0xFFFF0000) >> 16;
398 swapped |= (out & 0x0000FFFF) << 16;
414 uint32_t offset = (Value - 4) >> 1;
415 uint32_t signBit = (offset & 0x800000) >> 23;
416 uint32_t I1Bit = (offset & 0x400000) >> 22;
417 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
418 uint32_t I2Bit = (offset & 0x200000) >> 21;
419 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
420 uint32_t imm10Bits = (offset & 0x1FF800) >> 11;
421 uint32_t imm11Bits = (offset & 0x000007FF);
424 uint32_t firstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10Bits);
425 uint32_t secondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
426 (uint16_t)imm11Bits);
427 Binary |= secondHalf << 16;
445 uint32_t offset = (Value - 2) >> 2;
446 uint32_t signBit = (offset & 0x400000) >> 22;
447 uint32_t I1Bit = (offset & 0x200000) >> 21;
448 uint32_t J1Bit = (I1Bit ^ 0x1) ^ signBit;
449 uint32_t I2Bit = (offset & 0x100000) >> 20;
450 uint32_t J2Bit = (I2Bit ^ 0x1) ^ signBit;
451 uint32_t imm10HBits = (offset & 0xFFC00) >> 10;
452 uint32_t imm10LBits = (offset & 0x3FF);
455 uint32_t firstHalf = (((uint16_t)signBit << 10) | (uint16_t)imm10HBits);
456 uint32_t secondHalf = (((uint16_t)J1Bit << 13) | ((uint16_t)J2Bit << 11) |
457 ((uint16_t)imm10LBits) << 1);
458 Binary |= secondHalf << 16;
466 return ((Value - 2) >> 2) & 0xff;
469 uint32_t
Binary = (Value - 4) >> 1;
470 return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3);
474 return ((Value - 4) >> 1) & 0x7ff;
477 return ((Value - 4) >> 1) & 0xff;
482 if ((int64_t)Value < 0) {
487 if (Ctx && Value >= 256)
488 Ctx->FatalError(Fixup.
getLoc(),
"out of range pc-relative fixup value");
489 Value = (Value & 0xf) | ((Value & 0xf0) << 4);
490 return Value | (isAdd << 23);
500 if ((int64_t)Value < 0) {
506 if (Ctx && Value >= 256)
507 Ctx->FatalError(Fixup.
getLoc(),
"out of range pc-relative fixup value");
508 Value |= isAdd << 23;
513 uint32_t swapped = (Value & 0xFFFF0000) >> 16;
514 swapped |= (Value & 0x0000FFFF) << 16;
608 void ARMAsmBackend::applyFixup(
const MCFixup &Fixup,
char *Data,
609 unsigned DataSize, uint64_t Value)
const {
615 assert(Offset + NumBytes <= DataSize &&
"Invalid fixup offset!");
620 for (
unsigned i = 0; i != NumBytes; ++i)
621 Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
628 class ELFARMAsmBackend :
public ARMAsmBackend {
631 ELFARMAsmBackend(
const Target &
T,
const StringRef TT,
633 : ARMAsmBackend(T, TT), OSABI(_OSABI) { }
641 class DarwinARMAsmBackend :
public ARMAsmBackend {
644 DarwinARMAsmBackend(
const Target &
T,
const StringRef TT,
646 : ARMAsmBackend(T, TT), Subtype(st) {
647 HasDataInCodeSupport =
true;
682 return new DarwinARMAsmBackend(T, TT, CS);
688 assert(0 &&
"Windows not supported on ARM");
692 return new ELFARMAsmBackend(T, TT, OSABI);
const MCSymbol & getSymbol() const
static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, MCContext *Ctx=NULL)
void Write32(uint32_t Value)
static uint64_t getPointerSize(const Value *V, AliasAnalysis &AA)
MCContext & getContext() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
#define llvm_unreachable(msg)
.code16 (X86) / .code 16 (ARM)
uint32_t getOffset() const
A switch()-like statement whose cases are string literals.
void Write8(uint8_t Value)
MCFixupKind
MCFixupKind - Extensible enumeration to represent the type of a fixup.
static unsigned getRelaxedOpcode(unsigned Op)
Should this fixup kind force a 4-byte aligned effective PC value?
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
MCFixupKind getKind() const
bool isOSDarwin() const
isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
MCObjectWriter * createARMMachObjectWriter(raw_ostream &OS, bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype)
createARMMachObjectWriter - Construct an ARM Mach-O object writer.
void Write16(uint16_t Value)
void setOpcode(unsigned Op)
const MCSymbolRefExpr * getSymA() const
MCSubtargetInfo * createARMMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS)
R Default(const T &Value) const
unsigned getOpcode() const
MCObjectWriter * createARMELFObjectWriter(raw_ostream &OS, uint8_t OSABI)
createARMELFObjectWriter - Construct an ELF Mach-O object writer.
static int getSOImmVal(unsigned Arg)
.code32 (X86) / .code 32 (ARM)
void dump_pretty(raw_ostream &OS, const MCAsmInfo *MAI=0, const MCInstPrinter *Printer=0, StringRef Separator=" ") const
Dump the MCInst as prettily as possible using the additional MC structures, if given. Operators are separated by the Separator string.
const MCSymbol & AliasedSymbol() const
MCAsmBackend * createARMAsmBackend(const Target &T, const MCRegisterInfo &MRI, StringRef TT, StringRef CPU)
StringRef getArchName() const
MCFixupKindInfo - Target independent information on a fixup kind.
LLVM Value Representation.
MCAsmBackend - Generic interface to target specific assembler backends.
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const T &Value)
const MCRegisterInfo & MRI
bool isThumbFunc(const MCSymbol *Func) const
Check whether a given symbol has been flagged with .thumb_func.
static unsigned getFixupKindNumBytes(unsigned Kind)
getFixupKindNumBytes - The number of bytes the fixup may change.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
getFixupKindInfo - Get information on a fixup kind.