LLVM  3.7.0
ARMAsmBackend.cpp
Go to the documentation of this file.
1 //===-- ARMAsmBackend.cpp - ARM Assembler Backend -------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCAsmBackend.h"
20 #include "llvm/MC/MCAssembler.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCDirectives.h"
24 #include "llvm/MC/MCExpr.h"
27 #include "llvm/MC/MCObjectWriter.h"
28 #include "llvm/MC/MCSectionELF.h"
29 #include "llvm/MC/MCSectionMachO.h"
31 #include "llvm/MC/MCValue.h"
32 #include "llvm/Support/ELF.h"
34 #include "llvm/Support/MachO.h"
36 using namespace llvm;
37 
38 namespace {
39 class ARMELFObjectWriter : public MCELFObjectTargetWriter {
40 public:
41  ARMELFObjectWriter(uint8_t OSABI)
42  : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, ELF::EM_ARM,
43  /*HasRelocationAddend*/ false) {}
44 };
45 
46 const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
47  const static MCFixupKindInfo InfosLE[ARM::NumTargetFixupKinds] = {
48  // This table *must* be in the order that the fixup_* kinds are defined in
49  // ARMFixupKinds.h.
50  //
51  // Name Offset (bits) Size (bits) Flags
52  {"fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
53  {"fixup_t2_ldst_pcrel_12", 0, 32,
56  {"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
57  {"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
58  {"fixup_t2_pcrel_10", 0, 32,
61  {"fixup_thumb_adr_pcrel_10", 0, 8,
64  {"fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
65  {"fixup_t2_adr_pcrel_12", 0, 32,
68  {"fixup_arm_condbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
69  {"fixup_arm_uncondbranch", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
70  {"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
71  {"fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
72  {"fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
73  {"fixup_arm_uncondbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
74  {"fixup_arm_condbl", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
75  {"fixup_arm_blx", 0, 24, MCFixupKindInfo::FKF_IsPCRel},
76  {"fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
77  {"fixup_arm_thumb_blx", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
78  {"fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
79  {"fixup_arm_thumb_cp", 0, 8,
82  {"fixup_arm_thumb_bcc", 0, 8, MCFixupKindInfo::FKF_IsPCRel},
83  // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
84  // - 19.
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},
89  };
90  const static MCFixupKindInfo InfosBE[ARM::NumTargetFixupKinds] = {
91  // This table *must* be in the order that the fixup_* kinds are defined in
92  // ARMFixupKinds.h.
93  //
94  // Name Offset (bits) Size (bits) Flags
95  {"fixup_arm_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
96  {"fixup_t2_ldst_pcrel_12", 0, 32,
99  {"fixup_arm_pcrel_10_unscaled", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
100  {"fixup_arm_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
101  {"fixup_t2_pcrel_10", 0, 32,
104  {"fixup_thumb_adr_pcrel_10", 8, 8,
107  {"fixup_arm_adr_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
108  {"fixup_t2_adr_pcrel_12", 0, 32,
111  {"fixup_arm_condbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
112  {"fixup_arm_uncondbranch", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
113  {"fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
114  {"fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
115  {"fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
116  {"fixup_arm_uncondbl", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
117  {"fixup_arm_condbl", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
118  {"fixup_arm_blx", 8, 24, MCFixupKindInfo::FKF_IsPCRel},
119  {"fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
120  {"fixup_arm_thumb_blx", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
121  {"fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
122  {"fixup_arm_thumb_cp", 8, 8,
125  {"fixup_arm_thumb_bcc", 8, 8, MCFixupKindInfo::FKF_IsPCRel},
126  // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16
127  // - 19.
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},
132  };
133 
134  if (Kind < FirstTargetFixupKind)
135  return MCAsmBackend::getFixupKindInfo(Kind);
136 
137  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
138  "Invalid kind!");
139  return (IsLittleEndian ? InfosLE : InfosBE)[Kind - FirstTargetFixupKind];
140 }
141 
142 void ARMAsmBackend::handleAssemblerFlag(MCAssemblerFlag Flag) {
143  switch (Flag) {
144  default:
145  break;
146  case MCAF_Code16:
147  setIsThumb(true);
148  break;
149  case MCAF_Code32:
150  setIsThumb(false);
151  break;
152  }
153 }
154 } // end anonymous namespace
155 
156 unsigned ARMAsmBackend::getRelaxedOpcode(unsigned Op) const {
157  bool HasThumb2 = STI->getFeatureBits()[ARM::FeatureThumb2];
158 
159  switch (Op) {
160  default:
161  return Op;
162  case ARM::tBcc:
163  return HasThumb2 ? (unsigned)ARM::t2Bcc : Op;
164  case ARM::tLDRpci:
165  return HasThumb2 ? (unsigned)ARM::t2LDRpci : Op;
166  case ARM::tADR:
167  return HasThumb2 ? (unsigned)ARM::t2ADR : Op;
168  case ARM::tB:
169  return HasThumb2 ? (unsigned)ARM::t2B : Op;
170  case ARM::tCBZ:
171  return ARM::tHINT;
172  case ARM::tCBNZ:
173  return ARM::tHINT;
174  }
175 }
176 
177 bool ARMAsmBackend::mayNeedRelaxation(const MCInst &Inst) const {
178  if (getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode())
179  return true;
180  return false;
181 }
182 
183 bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
184  const MCRelaxableFragment *DF,
185  const MCAsmLayout &Layout) const {
186  switch ((unsigned)Fixup.getKind()) {
188  // Relaxing tB to t2B. tB has a signed 12-bit displacement with the
189  // low bit being an implied zero. There's an implied +4 offset for the
190  // branch, so we adjust the other way here to determine what's
191  // encodable.
192  //
193  // Relax if the value is too big for a (signed) i8.
194  int64_t Offset = int64_t(Value) - 4;
195  return Offset > 2046 || Offset < -2048;
196  }
198  // Relaxing tBcc to t2Bcc. tBcc has a signed 9-bit displacement with the
199  // low bit being an implied zero. There's an implied +4 offset for the
200  // branch, so we adjust the other way here to determine what's
201  // encodable.
202  //
203  // Relax if the value is too big for a (signed) i8.
204  int64_t Offset = int64_t(Value) - 4;
205  return Offset > 254 || Offset < -256;
206  }
209  // If the immediate is negative, greater than 1020, or not a multiple
210  // of four, the wide version of the instruction must be used.
211  int64_t Offset = int64_t(Value) - 4;
212  return Offset > 1020 || Offset < 0 || Offset & 3;
213  }
215  // If we have a Thumb CBZ or CBNZ instruction and its target is the next
216  // instruction it is is actually out of range for the instruction.
217  // It will be changed to a NOP.
218  int64_t Offset = (Value & ~1);
219  return Offset == 2;
220  }
221  llvm_unreachable("Unexpected fixup kind in fixupNeedsRelaxation()!");
222 }
223 
224 void ARMAsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const {
225  unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode());
226 
227  // Sanity check w/ diagnostic if we get here w/ a bogus instruction.
228  if (RelaxedOp == Inst.getOpcode()) {
229  SmallString<256> Tmp;
230  raw_svector_ostream OS(Tmp);
231  Inst.dump_pretty(OS);
232  OS << "\n";
233  report_fatal_error("unexpected instruction to relax: " + OS.str());
234  }
235 
236  // If we are changing Thumb CBZ or CBNZ instruction to a NOP, aka tHINT, we
237  // have to change the operands too.
238  if ((Inst.getOpcode() == ARM::tCBZ || Inst.getOpcode() == ARM::tCBNZ) &&
239  RelaxedOp == ARM::tHINT) {
240  Res.setOpcode(RelaxedOp);
244  return;
245  }
246 
247  // The rest of instructions we're relaxing have the same operands.
248  // We just need to update to the proper opcode.
249  Res = Inst;
250  Res.setOpcode(RelaxedOp);
251 }
252 
253 bool ARMAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
254  const uint16_t Thumb1_16bitNopEncoding = 0x46c0; // using MOV r8,r8
255  const uint16_t Thumb2_16bitNopEncoding = 0xbf00; // NOP
256  const uint32_t ARMv4_NopEncoding = 0xe1a00000; // using MOV r0,r0
257  const uint32_t ARMv6T2_NopEncoding = 0xe320f000; // NOP
258  if (isThumb()) {
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)
263  OW->write16(nopEncoding);
264  if (Count & 1)
265  OW->write8(0);
266  return true;
267  }
268  // ARM mode
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)
273  OW->write32(nopEncoding);
274  // FIXME: should this function return false when unable to write exactly
275  // 'Count' bytes with NOP encodings?
276  switch (Count % 4) {
277  default:
278  break; // No leftover bytes to write
279  case 1:
280  OW->write8(0);
281  break;
282  case 2:
283  OW->write16(0);
284  break;
285  case 3:
286  OW->write16(0);
287  OW->write8(0xa0);
288  break;
289  }
290 
291  return true;
292 }
293 
294 static uint32_t swapHalfWords(uint32_t Value, bool IsLittleEndian) {
295  if (IsLittleEndian) {
296  // Note that the halfwords are stored high first and low second in thumb;
297  // so we need to swap the fixup value here to map properly.
298  uint32_t Swapped = (Value & 0xFFFF0000) >> 16;
299  Swapped |= (Value & 0x0000FFFF) << 16;
300  return Swapped;
301  } else
302  return Value;
303 }
304 
305 static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf,
306  bool IsLittleEndian) {
307  uint32_t Value;
308 
309  if (IsLittleEndian) {
310  Value = (SecondHalf & 0xFFFF) << 16;
311  Value |= (FirstHalf & 0xFFFF);
312  } else {
313  Value = (SecondHalf & 0xFFFF);
314  Value |= (FirstHalf & 0xFFFF) << 16;
315  }
316 
317  return Value;
318 }
319 
320 static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
321  bool IsPCRel, MCContext *Ctx,
322  bool IsLittleEndian) {
323  unsigned Kind = Fixup.getKind();
324  switch (Kind) {
325  default:
326  llvm_unreachable("Unknown fixup kind!");
327  case FK_Data_1:
328  case FK_Data_2:
329  case FK_Data_4:
330  return Value;
331  case FK_SecRel_2:
332  return Value;
333  case FK_SecRel_4:
334  return Value;
336  if (!IsPCRel)
337  Value >>= 16;
338  // Fallthrough
340  unsigned Hi4 = (Value & 0xF000) >> 12;
341  unsigned Lo12 = Value & 0x0FFF;
342  // inst{19-16} = Hi4;
343  // inst{11-0} = Lo12;
344  Value = (Hi4 << 16) | (Lo12);
345  return Value;
346  }
348  if (!IsPCRel)
349  Value >>= 16;
350  // Fallthrough
352  unsigned Hi4 = (Value & 0xF000) >> 12;
353  unsigned i = (Value & 0x800) >> 11;
354  unsigned Mid3 = (Value & 0x700) >> 8;
355  unsigned Lo8 = Value & 0x0FF;
356  // inst{19-16} = Hi4;
357  // inst{26} = i;
358  // inst{14-12} = Mid3;
359  // inst{7-0} = Lo8;
360  Value = (Hi4 << 16) | (i << 26) | (Mid3 << 12) | (Lo8);
361  return swapHalfWords(Value, IsLittleEndian);
362  }
364  // ARM PC-relative values are offset by 8.
365  Value -= 4;
366  // FALLTHROUGH
368  // Offset by 4, adjusted by two due to the half-word ordering of thumb.
369  Value -= 4;
370  bool isAdd = true;
371  if ((int64_t)Value < 0) {
372  Value = -Value;
373  isAdd = false;
374  }
375  if (Ctx && Value >= 4096)
376  Ctx->reportFatalError(Fixup.getLoc(), "out of range pc-relative fixup value");
377  Value |= isAdd << 23;
378 
379  // Same addressing mode as fixup_arm_pcrel_10,
380  // but with 16-bit halfwords swapped.
381  if (Kind == ARM::fixup_t2_ldst_pcrel_12)
382  return swapHalfWords(Value, IsLittleEndian);
383 
384  return Value;
385  }
387  return ((Value - 4) >> 2) & 0xff;
389  // ARM PC-relative values are offset by 8.
390  Value -= 8;
391  unsigned opc = 4; // bits {24-21}. Default to add: 0b0100
392  if ((int64_t)Value < 0) {
393  Value = -Value;
394  opc = 2; // 0b0010
395  }
396  if (Ctx && ARM_AM::getSOImmVal(Value) == -1)
397  Ctx->reportFatalError(Fixup.getLoc(), "out of range pc-relative fixup value");
398  // Encode the immediate and shift the opcode into place.
399  return ARM_AM::getSOImmVal(Value) | (opc << 21);
400  }
401 
403  Value -= 4;
404  unsigned opc = 0;
405  if ((int64_t)Value < 0) {
406  Value = -Value;
407  opc = 5;
408  }
409 
410  uint32_t out = (opc << 21);
411  out |= (Value & 0x800) << 15;
412  out |= (Value & 0x700) << 4;
413  out |= (Value & 0x0FF);
414 
415  return swapHalfWords(out, IsLittleEndian);
416  }
417 
422  case ARM::fixup_arm_blx:
423  // These values don't encode the low two bits since they're always zero.
424  // Offset by 8 just as above.
425  if (const MCSymbolRefExpr *SRE =
426  dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
427  if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_TLSCALL)
428  return 0;
429  return 0xffffff & ((Value - 8) >> 2);
431  Value = Value - 4;
432  Value >>= 1; // Low bit is not encoded.
433 
434  uint32_t out = 0;
435  bool I = Value & 0x800000;
436  bool J1 = Value & 0x400000;
437  bool J2 = Value & 0x200000;
438  J1 ^= I;
439  J2 ^= I;
440 
441  out |= I << 26; // S bit
442  out |= !J1 << 13; // J1 bit
443  out |= !J2 << 11; // J2 bit
444  out |= (Value & 0x1FF800) << 5; // imm6 field
445  out |= (Value & 0x0007FF); // imm11 field
446 
447  return swapHalfWords(out, IsLittleEndian);
448  }
450  Value = Value - 4;
451  Value >>= 1; // Low bit is not encoded.
452 
453  uint64_t out = 0;
454  out |= (Value & 0x80000) << 7; // S bit
455  out |= (Value & 0x40000) >> 7; // J2 bit
456  out |= (Value & 0x20000) >> 4; // J1 bit
457  out |= (Value & 0x1F800) << 5; // imm6 field
458  out |= (Value & 0x007FF); // imm11 field
459 
460  return swapHalfWords(out, IsLittleEndian);
461  }
463  // The value doesn't encode the low bit (always zero) and is offset by
464  // four. The 32-bit immediate value is encoded as
465  // imm32 = SignExtend(S:I1:I2:imm10:imm11:0)
466  // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
467  // The value is encoded into disjoint bit positions in the destination
468  // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
469  // J = either J1 or J2 bit
470  //
471  // BL: xxxxxSIIIIIIIIII xxJxJIIIIIIIIIII
472  //
473  // Note that the halfwords are stored high first, low second; so we need
474  // to transpose the fixup value here to map properly.
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);
483 
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);
487  return joinHalfWords(FirstHalf, SecondHalf, IsLittleEndian);
488  }
490  // The value doesn't encode the low two bits (always zero) and is offset by
491  // four (see fixup_arm_thumb_cp). The 32-bit immediate value is encoded as
492  // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:00)
493  // where I1 = NOT(J1 ^ S) and I2 = NOT(J2 ^ S).
494  // The value is encoded into disjoint bit positions in the destination
495  // opcode. x = unchanged, I = immediate value bit, S = sign extension bit,
496  // J = either J1 or J2 bit, 0 = zero.
497  //
498  // BLX: xxxxxSIIIIIIIIII xxJxJIIIIIIIIII0
499  //
500  // Note that the halfwords are stored high first, low second; so we need
501  // to transpose the fixup value here to map properly.
502  uint32_t offset = (Value - 2) >> 2;
503  if (const MCSymbolRefExpr *SRE =
504  dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
505  if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_TLSCALL)
506  offset = 0;
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);
514 
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);
518  return joinHalfWords(FirstHalf, SecondHalf, IsLittleEndian);
519  }
521  // Offset by 4, and don't encode the low two bits. Two bytes of that
522  // 'off by 4' is implicitly handled by the half-word ordering of the
523  // Thumb encoding, so we only need to adjust by 2 here.
524  return ((Value - 2) >> 2) & 0xff;
526  // Offset by 4 and don't encode the lower bit, which is always 0.
527  uint32_t Binary = (Value - 4) >> 1;
528  return ((Binary & 0x20) << 4) | ((Binary & 0x1f) << 3);
529  }
531  // Offset by 4 and don't encode the lower bit, which is always 0.
532  return ((Value - 4) >> 1) & 0x7ff;
534  // Offset by 4 and don't encode the lower bit, which is always 0.
535  return ((Value - 4) >> 1) & 0xff;
537  Value = Value - 8; // ARM fixups offset by an additional word and don't
538  // need to adjust for the half-word ordering.
539  bool isAdd = true;
540  if ((int64_t)Value < 0) {
541  Value = -Value;
542  isAdd = false;
543  }
544  // The value has the low 4 bits encoded in [3:0] and the high 4 in [11:8].
545  if (Ctx && Value >= 256)
546  Ctx->reportFatalError(Fixup.getLoc(), "out of range pc-relative fixup value");
547  Value = (Value & 0xf) | ((Value & 0xf0) << 4);
548  return Value | (isAdd << 23);
549  }
551  Value = Value - 4; // ARM fixups offset by an additional word and don't
552  // need to adjust for the half-word ordering.
553  // Fall through.
554  case ARM::fixup_t2_pcrel_10: {
555  // Offset by 4, adjusted by two due to the half-word ordering of thumb.
556  Value = Value - 4;
557  bool isAdd = true;
558  if ((int64_t)Value < 0) {
559  Value = -Value;
560  isAdd = false;
561  }
562  // These values don't encode the low two bits since they're always zero.
563  Value >>= 2;
564  if (Ctx && Value >= 256)
565  Ctx->reportFatalError(Fixup.getLoc(), "out of range pc-relative fixup value");
566  Value |= isAdd << 23;
567 
568  // Same addressing mode as fixup_arm_pcrel_10, but with 16-bit halfwords
569  // swapped.
570  if (Kind == ARM::fixup_t2_pcrel_10)
571  return swapHalfWords(Value, IsLittleEndian);
572 
573  return Value;
574  }
575  }
576 }
577 
578 void ARMAsmBackend::processFixupValue(const MCAssembler &Asm,
579  const MCAsmLayout &Layout,
580  const MCFixup &Fixup,
581  const MCFragment *DF,
582  const MCValue &Target, uint64_t &Value,
583  bool &IsResolved) {
584  const MCSymbolRefExpr *A = Target.getSymA();
585  // Some fixups to thumb function symbols need the low bit (thumb bit)
586  // twiddled.
587  if ((unsigned)Fixup.getKind() != ARM::fixup_arm_ldst_pcrel_12 &&
593  if (A) {
594  const MCSymbol &Sym = A->getSymbol();
595  if (Asm.isThumbFunc(&Sym))
596  Value |= 1;
597  }
598  }
599  // For Thumb1 BL instruction, it is possible to be a long jump between
600  // the basic blocks of the same function. Thus, we would like to resolve
601  // the offset when the destination has the same MCFragment.
602  if (A && (unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_bl) {
603  const MCSymbol &Sym = A->getSymbol();
604  IsResolved = (Sym.getFragment() == DF);
605  }
606  // We must always generate a relocation for BL/BLX instructions if we have
607  // a symbol to reference, as the linker relies on knowing the destination
608  // symbol's thumb-ness to get interworking right.
609  if (A && ((unsigned)Fixup.getKind() == ARM::fixup_arm_thumb_blx ||
610  (unsigned)Fixup.getKind() == ARM::fixup_arm_blx ||
613  IsResolved = false;
614 
615  // Try to get the encoded value for the fixup as-if we're mapping it into
616  // the instruction. This allows adjustFixupValue() to issue a diagnostic
617  // if the value aren't invalid.
618  (void)adjustFixupValue(Fixup, Value, false, &Asm.getContext(),
619  IsLittleEndian);
620 }
621 
622 /// getFixupKindNumBytes - The number of bytes the fixup may change.
623 static unsigned getFixupKindNumBytes(unsigned Kind) {
624  switch (Kind) {
625  default:
626  llvm_unreachable("Unknown fixup kind!");
627 
628  case FK_Data_1:
632  return 1;
633 
634  case FK_Data_2:
637  return 2;
638 
645  case ARM::fixup_arm_blx:
648  return 3;
649 
650  case FK_Data_4:
662  return 4;
663 
664  case FK_SecRel_2:
665  return 2;
666  case FK_SecRel_4:
667  return 4;
668  }
669 }
670 
671 /// getFixupKindContainerSizeBytes - The number of bytes of the
672 /// container involved in big endian.
673 static unsigned getFixupKindContainerSizeBytes(unsigned Kind) {
674  switch (Kind) {
675  default:
676  llvm_unreachable("Unknown fixup kind!");
677 
678  case FK_Data_1:
679  return 1;
680  case FK_Data_2:
681  return 2;
682  case FK_Data_4:
683  return 4;
684 
690  // Instruction size is 2 bytes.
691  return 2;
692 
699  case ARM::fixup_arm_blx:
713  // Instruction size is 4 bytes.
714  return 4;
715  }
716 }
717 
718 void ARMAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
719  unsigned DataSize, uint64_t Value,
720  bool IsPCRel) const {
721  unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
722  Value = adjustFixupValue(Fixup, Value, IsPCRel, nullptr, IsLittleEndian);
723  if (!Value)
724  return; // Doesn't change encoding.
725 
726  unsigned Offset = Fixup.getOffset();
727  assert(Offset + NumBytes <= DataSize && "Invalid fixup offset!");
728 
729  // Used to point to big endian bytes.
730  unsigned FullSizeBytes;
731  if (!IsLittleEndian) {
732  FullSizeBytes = getFixupKindContainerSizeBytes(Fixup.getKind());
733  assert((Offset + FullSizeBytes) <= DataSize && "Invalid fixup size!");
734  assert(NumBytes <= FullSizeBytes && "Invalid fixup size!");
735  }
736 
737  // For each byte of the fragment that the fixup touches, mask in the bits from
738  // the fixup value. The Value has been "split up" into the appropriate
739  // bitfields above.
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);
743  }
744 }
745 
747  const MCRegisterInfo &MRI,
748  const Triple &TheTriple, StringRef CPU,
749  bool isLittle) {
750  switch (TheTriple.getObjectFormat()) {
751  default:
752  llvm_unreachable("unsupported object format");
753  case Triple::MachO: {
756  .Cases("armv4t", "thumbv4t", MachO::CPU_SUBTYPE_ARM_V4T)
757  .Cases("armv5e", "thumbv5e", MachO::CPU_SUBTYPE_ARM_V5TEJ)
758  .Cases("armv6", "thumbv6", MachO::CPU_SUBTYPE_ARM_V6)
759  .Cases("armv6m", "thumbv6m", MachO::CPU_SUBTYPE_ARM_V6M)
760  .Cases("armv7em", "thumbv7em", MachO::CPU_SUBTYPE_ARM_V7EM)
761  .Cases("armv7k", "thumbv7k", MachO::CPU_SUBTYPE_ARM_V7K)
762  .Cases("armv7m", "thumbv7m", MachO::CPU_SUBTYPE_ARM_V7M)
763  .Cases("armv7s", "thumbv7s", MachO::CPU_SUBTYPE_ARM_V7S)
765 
766  return new ARMAsmBackendDarwin(T, TheTriple, CS);
767  }
768  case Triple::COFF:
769  assert(TheTriple.isOSWindows() && "non-Windows ARM COFF is not supported");
770  return new ARMAsmBackendWinCOFF(T, TheTriple);
771  case Triple::ELF:
772  assert(TheTriple.isOSBinFormatELF() && "using ELF for non-ELF target");
773  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
774  return new ARMAsmBackendELF(T, TheTriple, OSABI, isLittle);
775  }
776 }
777 
779  const MCRegisterInfo &MRI,
780  const Triple &TT, StringRef CPU) {
781  return createARMAsmBackend(T, MRI, TT, CPU, true);
782 }
783 
785  const MCRegisterInfo &MRI,
786  const Triple &TT, StringRef CPU) {
787  return createARMAsmBackend(T, MRI, TT, CPU, false);
788 }
789 
791  const MCRegisterInfo &MRI,
792  const Triple &TT, StringRef CPU) {
793  return createARMAsmBackend(T, MRI, TT, CPU, true);
794 }
795 
797  const MCRegisterInfo &MRI,
798  const Triple &TT, StringRef CPU) {
799  return createARMAsmBackend(T, MRI, TT, CPU, false);
800 }
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:251
const MCSymbol & getSymbol() const
Definition: MCExpr.h:328
SMLoc getLoc() const
Definition: MCFixup.h:108
This represents an "assembler immediate".
Definition: MCValue.h:44
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L, const Twine &Msg) const
Definition: MCContext.cpp:474
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:488
MCContext & getContext() const
Definition: MCAssembler.h:731
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.
Definition: MCInst.cpp:51
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.
Definition: Triple.h:464
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:62
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:29
static unsigned getRelaxedOpcode(unsigned Op)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:159
ObjectFormatType getObjectFormat() const
getFormat - Get the object format for this triple.
Definition: Triple.h:272
A four-byte section relative fixup.
Definition: MCFixup.h:38
#define false
Definition: ConvertUTF.c:65
A four-byte fixup.
Definition: MCFixup.h:26
Context object for machine code objects.
Definition: MCContext.h:48
MCAsmBackend * createARMLEAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU)
A two-byte section relative fixup.
Definition: MCFixup.h:37
.code16 (X86) / .code 16 (ARM)
Definition: MCDirectives.h:50
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
Definition: MCFixup.h:91
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:97
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...
Definition: MCAssembler.h:259
void write32(uint32_t Value)
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
const MCExpr * getValue() const
Definition: MCFixup.h:94
static uint32_t swapHalfWords(uint32_t Value, bool IsLittleEndian)
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:23
Should this fixup kind force a 4-byte aligned effective PC value?
MCFragment * getFragment() const
Definition: MCSymbol.h:382
MCFixupKind getKind() const
Definition: MCFixup.h:89
A one-byte fixup.
Definition: MCFixup.h:24
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
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)
Definition: MCInst.h:158
const MCSymbolRefExpr * getSymA() const
Definition: MCValue.h:51
R Default(const T &Value) const
Definition: StringSwitch.h:111
unsigned getOpcode() const
Definition: MCInst.h:159
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)
Definition: MCDirectives.h:51
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:479
MCAssemblerFlag
Definition: MCDirectives.h:47
StringRef getArchName() const
getArchName - Get the architecture (first) component of the triple.
Definition: Triple.cpp:783
#define I(x, y, z)
Definition: MD5.cpp:54
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.
Definition: Value.h:69
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.
Definition: MCAsmBackend.h:34
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const T &Value)
Definition: StringSwitch.h:85
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
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)
Definition: MCInst.h:117
A two-byte fixup.
Definition: MCFixup.h:25
static uint32_t joinHalfWords(uint32_t FirstHalf, uint32_t SecondHalf, bool IsLittleEndian)