LLVM  8.0.1
HexagonAsmBackend.cpp
Go to the documentation of this file.
1 //===-- HexagonAsmBackend.cpp - Hexagon 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 
10 #include "Hexagon.h"
11 #include "HexagonFixupKinds.h"
18 #include "llvm/MC/MCAsmBackend.h"
19 #include "llvm/MC/MCAsmLayout.h"
20 #include "llvm/MC/MCAssembler.h"
21 #include "llvm/MC/MCContext.h"
24 #include "llvm/MC/MCInstrInfo.h"
25 #include "llvm/MC/MCObjectWriter.h"
26 #include "llvm/Support/Debug.h"
28 
29 #include <sstream>
30 
31 using namespace llvm;
32 using namespace Hexagon;
33 
34 #define DEBUG_TYPE "hexagon-asm-backend"
35 
37  ("mno-fixup", cl::desc("Disable fixing up resolved relocations for Hexagon"));
38 
39 namespace {
40 
41 class HexagonAsmBackend : public MCAsmBackend {
42  uint8_t OSABI;
43  StringRef CPU;
44  mutable uint64_t relaxedCnt;
45  std::unique_ptr <MCInstrInfo> MCII;
46  std::unique_ptr <MCInst *> RelaxTarget;
47  MCInst * Extender;
48 
49  void ReplaceInstruction(MCCodeEmitter &E, MCRelaxableFragment &RF,
50  MCInst &HMB) const {
52  SmallString<256> Code;
53  raw_svector_ostream VecOS(Code);
54  E.encodeInstruction(HMB, VecOS, Fixups, *RF.getSubtargetInfo());
55 
56  // Update the fragment.
57  RF.setInst(HMB);
58  RF.getContents() = Code;
59  RF.getFixups() = Fixups;
60  }
61 
62 public:
63  HexagonAsmBackend(const Target &T, const Triple &TT, uint8_t OSABI,
64  StringRef CPU)
65  : MCAsmBackend(support::little), OSABI(OSABI), CPU(CPU),
66  MCII(T.createMCInstrInfo()), RelaxTarget(new MCInst *),
67  Extender(nullptr) {}
68 
69  std::unique_ptr<MCObjectTargetWriter>
70  createObjectTargetWriter() const override {
71  return createHexagonELFObjectWriter(OSABI, CPU);
72  }
73 
74  void setExtender(MCContext &Context) const {
75  if (Extender == nullptr)
76  const_cast<HexagonAsmBackend *>(this)->Extender = new (Context) MCInst;
77  }
78 
79  MCInst *takeExtender() const {
80  assert(Extender != nullptr);
81  MCInst * Result = Extender;
82  const_cast<HexagonAsmBackend *>(this)->Extender = nullptr;
83  return Result;
84  }
85 
86  unsigned getNumFixupKinds() const override {
88  }
89 
90  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
91  const static MCFixupKindInfo Infos[Hexagon::NumTargetFixupKinds] = {
92  // This table *must* be in same the order of fixup_* kinds in
93  // HexagonFixupKinds.h.
94  //
95  // namei offset bits flags
96  { "fixup_Hexagon_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
97  { "fixup_Hexagon_B15_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
98  { "fixup_Hexagon_B7_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
99  { "fixup_Hexagon_LO16", 0, 32, 0 },
100  { "fixup_Hexagon_HI16", 0, 32, 0 },
101  { "fixup_Hexagon_32", 0, 32, 0 },
102  { "fixup_Hexagon_16", 0, 32, 0 },
103  { "fixup_Hexagon_8", 0, 32, 0 },
104  { "fixup_Hexagon_GPREL16_0", 0, 32, 0 },
105  { "fixup_Hexagon_GPREL16_1", 0, 32, 0 },
106  { "fixup_Hexagon_GPREL16_2", 0, 32, 0 },
107  { "fixup_Hexagon_GPREL16_3", 0, 32, 0 },
108  { "fixup_Hexagon_HL16", 0, 32, 0 },
109  { "fixup_Hexagon_B13_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
110  { "fixup_Hexagon_B9_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
111  { "fixup_Hexagon_B32_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
112  { "fixup_Hexagon_32_6_X", 0, 32, 0 },
113  { "fixup_Hexagon_B22_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
114  { "fixup_Hexagon_B15_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
115  { "fixup_Hexagon_B13_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
116  { "fixup_Hexagon_B9_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
117  { "fixup_Hexagon_B7_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
118  { "fixup_Hexagon_16_X", 0, 32, 0 },
119  { "fixup_Hexagon_12_X", 0, 32, 0 },
120  { "fixup_Hexagon_11_X", 0, 32, 0 },
121  { "fixup_Hexagon_10_X", 0, 32, 0 },
122  { "fixup_Hexagon_9_X", 0, 32, 0 },
123  { "fixup_Hexagon_8_X", 0, 32, 0 },
124  { "fixup_Hexagon_7_X", 0, 32, 0 },
125  { "fixup_Hexagon_6_X", 0, 32, 0 },
126  { "fixup_Hexagon_32_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
127  { "fixup_Hexagon_COPY", 0, 32, 0 },
128  { "fixup_Hexagon_GLOB_DAT", 0, 32, 0 },
129  { "fixup_Hexagon_JMP_SLOT", 0, 32, 0 },
130  { "fixup_Hexagon_RELATIVE", 0, 32, 0 },
131  { "fixup_Hexagon_PLT_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
132  { "fixup_Hexagon_GOTREL_LO16", 0, 32, 0 },
133  { "fixup_Hexagon_GOTREL_HI16", 0, 32, 0 },
134  { "fixup_Hexagon_GOTREL_32", 0, 32, 0 },
135  { "fixup_Hexagon_GOT_LO16", 0, 32, 0 },
136  { "fixup_Hexagon_GOT_HI16", 0, 32, 0 },
137  { "fixup_Hexagon_GOT_32", 0, 32, 0 },
138  { "fixup_Hexagon_GOT_16", 0, 32, 0 },
139  { "fixup_Hexagon_DTPMOD_32", 0, 32, 0 },
140  { "fixup_Hexagon_DTPREL_LO16", 0, 32, 0 },
141  { "fixup_Hexagon_DTPREL_HI16", 0, 32, 0 },
142  { "fixup_Hexagon_DTPREL_32", 0, 32, 0 },
143  { "fixup_Hexagon_DTPREL_16", 0, 32, 0 },
144  { "fixup_Hexagon_GD_PLT_B22_PCREL",0, 32, MCFixupKindInfo::FKF_IsPCRel },
145  { "fixup_Hexagon_LD_PLT_B22_PCREL",0, 32, MCFixupKindInfo::FKF_IsPCRel },
146  { "fixup_Hexagon_GD_GOT_LO16", 0, 32, 0 },
147  { "fixup_Hexagon_GD_GOT_HI16", 0, 32, 0 },
148  { "fixup_Hexagon_GD_GOT_32", 0, 32, 0 },
149  { "fixup_Hexagon_GD_GOT_16", 0, 32, 0 },
150  { "fixup_Hexagon_LD_GOT_LO16", 0, 32, 0 },
151  { "fixup_Hexagon_LD_GOT_HI16", 0, 32, 0 },
152  { "fixup_Hexagon_LD_GOT_32", 0, 32, 0 },
153  { "fixup_Hexagon_LD_GOT_16", 0, 32, 0 },
154  { "fixup_Hexagon_IE_LO16", 0, 32, 0 },
155  { "fixup_Hexagon_IE_HI16", 0, 32, 0 },
156  { "fixup_Hexagon_IE_32", 0, 32, 0 },
157  { "fixup_Hexagon_IE_16", 0, 32, 0 },
158  { "fixup_Hexagon_IE_GOT_LO16", 0, 32, 0 },
159  { "fixup_Hexagon_IE_GOT_HI16", 0, 32, 0 },
160  { "fixup_Hexagon_IE_GOT_32", 0, 32, 0 },
161  { "fixup_Hexagon_IE_GOT_16", 0, 32, 0 },
162  { "fixup_Hexagon_TPREL_LO16", 0, 32, 0 },
163  { "fixup_Hexagon_TPREL_HI16", 0, 32, 0 },
164  { "fixup_Hexagon_TPREL_32", 0, 32, 0 },
165  { "fixup_Hexagon_TPREL_16", 0, 32, 0 },
166  { "fixup_Hexagon_6_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
167  { "fixup_Hexagon_GOTREL_32_6_X", 0, 32, 0 },
168  { "fixup_Hexagon_GOTREL_16_X", 0, 32, 0 },
169  { "fixup_Hexagon_GOTREL_11_X", 0, 32, 0 },
170  { "fixup_Hexagon_GOT_32_6_X", 0, 32, 0 },
171  { "fixup_Hexagon_GOT_16_X", 0, 32, 0 },
172  { "fixup_Hexagon_GOT_11_X", 0, 32, 0 },
173  { "fixup_Hexagon_DTPREL_32_6_X", 0, 32, 0 },
174  { "fixup_Hexagon_DTPREL_16_X", 0, 32, 0 },
175  { "fixup_Hexagon_DTPREL_11_X", 0, 32, 0 },
176  { "fixup_Hexagon_GD_GOT_32_6_X", 0, 32, 0 },
177  { "fixup_Hexagon_GD_GOT_16_X", 0, 32, 0 },
178  { "fixup_Hexagon_GD_GOT_11_X", 0, 32, 0 },
179  { "fixup_Hexagon_LD_GOT_32_6_X", 0, 32, 0 },
180  { "fixup_Hexagon_LD_GOT_16_X", 0, 32, 0 },
181  { "fixup_Hexagon_LD_GOT_11_X", 0, 32, 0 },
182  { "fixup_Hexagon_IE_32_6_X", 0, 32, 0 },
183  { "fixup_Hexagon_IE_16_X", 0, 32, 0 },
184  { "fixup_Hexagon_IE_GOT_32_6_X", 0, 32, 0 },
185  { "fixup_Hexagon_IE_GOT_16_X", 0, 32, 0 },
186  { "fixup_Hexagon_IE_GOT_11_X", 0, 32, 0 },
187  { "fixup_Hexagon_TPREL_32_6_X", 0, 32, 0 },
188  { "fixup_Hexagon_TPREL_16_X", 0, 32, 0 },
189  { "fixup_Hexagon_TPREL_11_X", 0, 32, 0 },
190  { "fixup_Hexagon_GD_PLT_B22_PCREL_X",0, 32, MCFixupKindInfo::FKF_IsPCRel },
191  { "fixup_Hexagon_GD_PLT_B32_PCREL_X",0, 32, MCFixupKindInfo::FKF_IsPCRel },
192  { "fixup_Hexagon_LD_PLT_B22_PCREL_X",0, 32, MCFixupKindInfo::FKF_IsPCRel },
193  { "fixup_Hexagon_LD_PLT_B32_PCREL_X",0, 32, MCFixupKindInfo::FKF_IsPCRel }
194  };
195 
196  if (Kind < FirstTargetFixupKind)
197  return MCAsmBackend::getFixupKindInfo(Kind);
198 
199  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
200  "Invalid kind!");
201  return Infos[Kind - FirstTargetFixupKind];
202  }
203 
204  bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
205  const MCValue &Target) override {
206  MCFixupKind Kind = Fixup.getKind();
207 
208  switch((unsigned)Kind) {
209  default:
210  llvm_unreachable("Unknown Fixup Kind!");
211 
212  case fixup_Hexagon_LO16:
213  case fixup_Hexagon_HI16:
214  case fixup_Hexagon_16:
215  case fixup_Hexagon_8:
220  case fixup_Hexagon_HL16:
222  case fixup_Hexagon_16_X:
223  case fixup_Hexagon_12_X:
224  case fixup_Hexagon_11_X:
225  case fixup_Hexagon_10_X:
226  case fixup_Hexagon_9_X:
227  case fixup_Hexagon_8_X:
228  case fixup_Hexagon_7_X:
229  case fixup_Hexagon_6_X:
230  case fixup_Hexagon_COPY:
259  case fixup_Hexagon_IE_32:
260  case fixup_Hexagon_IE_16:
300  // These relocations should always have a relocation recorded
301  return true;
302 
304  //IsResolved = false;
305  break;
306 
317  if (DisableFixup)
318  return true;
319  break;
320 
321  case FK_Data_1:
322  case FK_Data_2:
323  case FK_Data_4:
324  case FK_PCRel_4:
325  case fixup_Hexagon_32:
326  // Leave these relocations alone as they are used for EH.
327  return false;
328  }
329  return false;
330  }
331 
332  /// getFixupKindNumBytes - The number of bytes the fixup may change.
333  static unsigned getFixupKindNumBytes(unsigned Kind) {
334  switch (Kind) {
335  default:
336  return 0;
337 
338  case FK_Data_1:
339  return 1;
340  case FK_Data_2:
341  return 2;
342  case FK_Data_4: // this later gets mapped to R_HEX_32
343  case FK_PCRel_4: // this later gets mapped to R_HEX_32_PCREL
344  case fixup_Hexagon_32:
358  return 4;
359  }
360  }
361 
362  // Make up for left shift when encoding the operand.
363  static uint64_t adjustFixupValue(MCFixupKind Kind, uint64_t Value) {
364  switch((unsigned)Kind) {
365  default:
366  break;
367 
373  Value >>= 2;
374  break;
375 
381  Value &= 0x3f;
382  break;
383 
387  Value >>= 6;
388  break;
389  }
390  return (Value);
391  }
392 
393  void HandleFixupError(const int bits, const int align_bits,
394  const int64_t FixupValue, const char *fixupStr) const {
395  // Error: value 1124 out of range: -1024-1023 when resolving
396  // symbol in file xprtsock.S
397  const APInt IntMin = APInt::getSignedMinValue(bits+align_bits);
398  const APInt IntMax = APInt::getSignedMaxValue(bits+align_bits);
399  std::stringstream errStr;
400  errStr << "\nError: value " <<
401  FixupValue <<
402  " out of range: " <<
403  IntMin.getSExtValue() <<
404  "-" <<
405  IntMax.getSExtValue() <<
406  " when resolving " <<
407  fixupStr <<
408  " fixup\n";
409  llvm_unreachable(errStr.str().c_str());
410  }
411 
412  /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided
413  /// data fragment, at the offset specified by the fixup and following the
414  /// fixup kind as appropriate.
415  void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
416  const MCValue &Target, MutableArrayRef<char> Data,
417  uint64_t FixupValue, bool IsResolved,
418  const MCSubtargetInfo *STI) const override {
419 
420  // When FixupValue is 0 the relocation is external and there
421  // is nothing for us to do.
422  if (!FixupValue) return;
423 
424  MCFixupKind Kind = Fixup.getKind();
425  uint64_t Value;
426  uint32_t InstMask;
427  uint32_t Reloc;
428 
429  // LLVM gives us an encoded value, we have to convert it back
430  // to a real offset before we can use it.
431  uint32_t Offset = Fixup.getOffset();
432  unsigned NumBytes = getFixupKindNumBytes(Kind);
433  assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
434  char *InstAddr = Data.data() + Offset;
435 
436  Value = adjustFixupValue(Kind, FixupValue);
437  if(!Value)
438  return;
439  int sValue = (int)Value;
440 
441  switch((unsigned)Kind) {
442  default:
443  return;
444 
446  if (!(isIntN(7, sValue)))
447  HandleFixupError(7, 2, (int64_t)FixupValue, "B7_PCREL");
450  InstMask = 0x00001f18; // Word32_B7
451  Reloc = (((Value >> 2) & 0x1f) << 8) | // Value 6-2 = Target 12-8
452  ((Value & 0x3) << 3); // Value 1-0 = Target 4-3
453  break;
454 
456  if (!(isIntN(9, sValue)))
457  HandleFixupError(9, 2, (int64_t)FixupValue, "B9_PCREL");
460  InstMask = 0x003000fe; // Word32_B9
461  Reloc = (((Value >> 7) & 0x3) << 20) | // Value 8-7 = Target 21-20
462  ((Value & 0x7f) << 1); // Value 6-0 = Target 7-1
463  break;
464 
465  // Since the existing branches that use this relocation cannot be
466  // extended, they should only be fixed up if the target is within range.
468  if (!(isIntN(13, sValue)))
469  HandleFixupError(13, 2, (int64_t)FixupValue, "B13_PCREL");
472  InstMask = 0x00202ffe; // Word32_B13
473  Reloc = (((Value >> 12) & 0x1) << 21) | // Value 12 = Target 21
474  (((Value >> 11) & 0x1) << 13) | // Value 11 = Target 13
475  ((Value & 0x7ff) << 1); // Value 10-0 = Target 11-1
476  break;
477 
479  if (!(isIntN(15, sValue)))
480  HandleFixupError(15, 2, (int64_t)FixupValue, "B15_PCREL");
483  InstMask = 0x00df20fe; // Word32_B15
484  Reloc = (((Value >> 13) & 0x3) << 22) | // Value 14-13 = Target 23-22
485  (((Value >> 8) & 0x1f) << 16) | // Value 12-8 = Target 20-16
486  (((Value >> 7) & 0x1) << 13) | // Value 7 = Target 13
487  ((Value & 0x7f) << 1); // Value 6-0 = Target 7-1
488  break;
489 
491  if (!(isIntN(22, sValue)))
492  HandleFixupError(22, 2, (int64_t)FixupValue, "B22_PCREL");
495  InstMask = 0x01ff3ffe; // Word32_B22
496  Reloc = (((Value >> 13) & 0x1ff) << 16) | // Value 21-13 = Target 24-16
497  ((Value & 0x1fff) << 1); // Value 12-0 = Target 13-1
498  break;
499 
501  InstMask = 0x0fff3fff; // Word32_X26
502  Reloc = (((Value >> 14) & 0xfff) << 16) | // Value 25-14 = Target 27-16
503  (Value & 0x3fff); // Value 13-0 = Target 13-0
504  break;
505 
506  case FK_Data_1:
507  case FK_Data_2:
508  case FK_Data_4:
509  case fixup_Hexagon_32:
510  InstMask = 0xffffffff; // Word32
511  Reloc = Value;
512  break;
513  }
514 
515  LLVM_DEBUG(dbgs() << "Name=" << getFixupKindInfo(Kind).Name << "("
516  << (unsigned)Kind << ")\n");
517  LLVM_DEBUG(
518  uint32_t OldData = 0; for (unsigned i = 0; i < NumBytes; i++) OldData |=
519  (InstAddr[i] << (i * 8)) & (0xff << (i * 8));
520  dbgs() << "\tBValue=0x"; dbgs().write_hex(Value) << ": AValue=0x";
521  dbgs().write_hex(FixupValue)
522  << ": Offset=" << Offset << ": Size=" << Data.size() << ": OInst=0x";
523  dbgs().write_hex(OldData) << ": Reloc=0x"; dbgs().write_hex(Reloc););
524 
525  // For each byte of the fragment that the fixup touches, mask in the
526  // bits from the fixup value. The Value has been "split up" into the
527  // appropriate bitfields above.
528  for (unsigned i = 0; i < NumBytes; i++){
529  InstAddr[i] &= uint8_t(~InstMask >> (i * 8)) & 0xff; // Clear reloc bits
530  InstAddr[i] |= uint8_t(Reloc >> (i * 8)) & 0xff; // Apply new reloc
531  }
532 
533  LLVM_DEBUG(uint32_t NewData = 0;
534  for (unsigned i = 0; i < NumBytes; i++) NewData |=
535  (InstAddr[i] << (i * 8)) & (0xff << (i * 8));
536  dbgs() << ": NInst=0x"; dbgs().write_hex(NewData) << "\n";);
537  }
538 
539  bool isInstRelaxable(MCInst const &HMI) const {
540  const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(*MCII, HMI);
541  bool Relaxable = false;
542  // Branches and loop-setup insns are handled as necessary by relaxation.
545  MCID.isBranch()) ||
547  MCID.isBranch()) ||
549  HMI.getOpcode() != Hexagon::C4_addipc))
550  if (HexagonMCInstrInfo::isExtendable(*MCII, HMI)) {
551  Relaxable = true;
552  MCOperand const &Operand =
555  Relaxable = false;
556  }
557 
558  return Relaxable;
559  }
560 
561  /// MayNeedRelaxation - Check whether the given instruction may need
562  /// relaxation.
563  ///
564  /// \param Inst - The instruction to test.
565  bool mayNeedRelaxation(MCInst const &Inst,
566  const MCSubtargetInfo &STI) const override {
567  return true;
568  }
569 
570  /// fixupNeedsRelaxation - Target specific predicate for whether a given
571  /// fixup requires the associated instruction to be relaxed.
572  bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
573  uint64_t Value,
574  const MCRelaxableFragment *DF,
575  const MCAsmLayout &Layout,
576  const bool WasForced) const override {
577  MCInst const &MCB = DF->getInst();
579 
580  *RelaxTarget = nullptr;
581  MCInst &MCI = const_cast<MCInst &>(HexagonMCInstrInfo::instruction(
582  MCB, Fixup.getOffset() / HEXAGON_INSTR_SIZE));
583  bool Relaxable = isInstRelaxable(MCI);
584  if (Relaxable == false)
585  return false;
586  // If we cannot resolve the fixup value, it requires relaxation.
587  if (!Resolved) {
588  switch ((unsigned)Fixup.getKind()) {
590  // GetFixupCount assumes B22 won't relax
592  default:
593  return false;
594  break;
598  case fixup_Hexagon_B7_PCREL: {
600  ++relaxedCnt;
601  *RelaxTarget = &MCI;
602  setExtender(Layout.getAssembler().getContext());
603  return true;
604  } else {
605  return false;
606  }
607  break;
608  }
609  }
610  }
611 
612  MCFixupKind Kind = Fixup.getKind();
613  int64_t sValue = Value;
614  int64_t maxValue;
615 
616  switch ((unsigned)Kind) {
618  maxValue = 1 << 8;
619  break;
621  maxValue = 1 << 10;
622  break;
624  maxValue = 1 << 16;
625  break;
627  maxValue = 1 << 23;
628  break;
629  default:
630  maxValue = INT64_MAX;
631  break;
632  }
633 
634  bool isFarAway = -maxValue > sValue || sValue > maxValue - 1;
635 
636  if (isFarAway) {
638  ++relaxedCnt;
639  *RelaxTarget = &MCI;
640  setExtender(Layout.getAssembler().getContext());
641  return true;
642  }
643  }
644 
645  return false;
646  }
647 
648  /// Simple predicate for targets where !Resolved implies requiring relaxation
649  bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
650  const MCRelaxableFragment *DF,
651  const MCAsmLayout &Layout) const override {
652  llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
653  }
654 
655  void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
656  MCInst &Res) const override {
658  "Hexagon relaxInstruction only works on bundles");
659 
660  Res.setOpcode(Hexagon::BUNDLE);
662  // Copy the results into the bundle.
663  bool Update = false;
664  for (auto &I : HexagonMCInstrInfo::bundleInstructions(Inst)) {
665  MCInst &CrntHMI = const_cast<MCInst &>(*I.getInst());
666 
667  // if immediate extender needed, add it in
668  if (*RelaxTarget == &CrntHMI) {
669  Update = true;
671  "No room to insert extender for relaxation");
672 
673  MCInst *HMIx = takeExtender();
675  *MCII, CrntHMI,
678  *RelaxTarget = nullptr;
679  }
680  // now copy over the original instruction(the one we may have extended)
681  Res.addOperand(MCOperand::createInst(I.getInst()));
682  }
683  (void)Update;
684  assert(Update && "Didn't find relaxation target");
685  }
686 
687  bool writeNopData(raw_ostream &OS, uint64_t Count) const override {
688  static const uint32_t Nopcode = 0x7f000000, // Hard-coded NOP.
689  ParseIn = 0x00004000, // In packet parse-bits.
690  ParseEnd = 0x0000c000; // End of packet parse-bits.
691 
692  while(Count % HEXAGON_INSTR_SIZE) {
693  LLVM_DEBUG(dbgs() << "Alignment not a multiple of the instruction size:"
694  << Count % HEXAGON_INSTR_SIZE << "/"
695  << HEXAGON_INSTR_SIZE << "\n");
696  --Count;
697  OS << '\0';
698  }
699 
700  while(Count) {
701  Count -= HEXAGON_INSTR_SIZE;
702  // Close the packet whenever a multiple of the maximum packet size remains
703  uint32_t ParseBits = (Count % (HEXAGON_PACKET_SIZE * HEXAGON_INSTR_SIZE))?
704  ParseIn: ParseEnd;
705  support::endian::write<uint32_t>(OS, Nopcode | ParseBits, Endian);
706  }
707  return true;
708  }
709 
710  void finishLayout(MCAssembler const &Asm,
711  MCAsmLayout &Layout) const override {
712  for (auto I : Layout.getSectionOrder()) {
713  auto &Fragments = I->getFragmentList();
714  for (auto &J : Fragments) {
715  switch (J.getKind()) {
716  default:
717  break;
718  case MCFragment::FT_Align: {
719  auto Size = Asm.computeFragmentSize(Layout, J);
720  for (auto K = J.getIterator();
721  K != Fragments.begin() && Size >= HEXAGON_PACKET_SIZE;) {
722  --K;
723  switch (K->getKind()) {
724  default:
725  break;
726  case MCFragment::FT_Align: {
727  // Don't pad before other alignments
728  Size = 0;
729  break;
730  }
732  MCContext &Context = Asm.getContext();
733  auto &RF = cast<MCRelaxableFragment>(*K);
734  auto &Inst = const_cast<MCInst &>(RF.getInst());
735  while (Size > 0 && HexagonMCInstrInfo::bundleSize(Inst) < 4) {
736  MCInst *Nop = new (Context) MCInst;
737  Nop->setOpcode(Hexagon::A2_nop);
739  Size -= 4;
740  if (!HexagonMCChecker(
741  Context, *MCII, *RF.getSubtargetInfo(), Inst,
742  *Context.getRegisterInfo(), false)
743  .check()) {
744  Inst.erase(Inst.end() - 1);
745  Size = 0;
746  }
747  }
748  bool Error = HexagonMCShuffle(Context, true, *MCII,
749  *RF.getSubtargetInfo(), Inst);
750  //assert(!Error);
751  (void)Error;
752  ReplaceInstruction(Asm.getEmitter(), RF, Inst);
753  Layout.invalidateFragmentsFrom(&RF);
754  Size = 0; // Only look back one instruction
755  break;
756  }
757  }
758  }
759  }
760  }
761  }
762  }
763  }
764 }; // class HexagonAsmBackend
765 
766 } // namespace
767 
768 // MCAsmBackend
770  const MCSubtargetInfo &STI,
771  MCRegisterInfo const & /*MRI*/,
772  const MCTargetOptions &Options) {
773  const Triple &TT = STI.getTargetTriple();
774  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
775 
776  StringRef CPUString = Hexagon_MC::selectHexagonCPU(STI.getCPU());
777  return new HexagonAsmBackend(T, TT, OSABI, CPUString);
778 }
static MCInstrInfo * createMCInstrInfo()
iterator end()
Definition: MCInst.h:196
LLVMContext & Context
This class represents lattice values for constants.
Definition: AllocatorList.h:24
This represents an "assembler immediate".
Definition: MCValue.h:40
#define LLVM_FALLTHROUGH
Definition: Compiler.h:86
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:299
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:164
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
bool isBundle(MCInst const &MCI)
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:510
demanded bits
#define HEXAGON_INSTR_SIZE
MCInst deriveExtender(MCInstrInfo const &MCII, MCInst const &Inst, MCOperand const &MO)
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
Definition: APInt.h:535
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
Definition: MCInstrDesc.h:277
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:74
const Triple & getTargetTriple() const
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
MCContext & getContext() const
Definition: MCAssembler.h:285
amdgpu Simplify well known AMD library false Value Value const Twine & Name
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:29
MCCodeEmitter & getEmitter() const
Definition: MCAssembler.h:295
virtual void encodeInstruction(const MCInst &Inst, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
EncodeInstruction - Encode the given Inst to bytes on the output stream OS.
void erase(iterator I)
Definition: MCInst.h:192
#define INT64_MAX
Definition: DataTypes.h:77
MCAsmBackend * createHexagonAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
MCOperand const & getExtendableOperand(MCInstrInfo const &MCII, MCInst const &MCI)
iterator_range< Hexagon::PacketIterator > bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI)
A four-byte fixup.
Definition: MCFixup.h:26
Context object for machine code objects.
Definition: MCContext.h:63
static cl::opt< bool > DisableFixup("mno-fixup", cl::desc("Disable fixing up resolved relocations for Hexagon"))
MCInst const & instruction(MCInst const &MCB, size_t Index)
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1575
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
MCAssembler & getAssembler() const
Get the assembler object this is a layout for.
Definition: MCAsmLayout.h:51
const MCExpr * getExpr() const
Definition: MCInst.h:96
bool HexagonMCShuffle(MCContext &Context, bool Fatal, MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &MCB)
SmallVectorImpl< char > & getContents()
Definition: MCFragment.h:198
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
StringRef selectHexagonCPU(StringRef CPU)
static unsigned getFixupKindNumBytes(unsigned Kind)
The number of bytes the fixup may change.
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: MCFragment.h:271
int64_t getImm() const
Definition: MCInst.h:76
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:291
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void invalidateFragmentsFrom(MCFragment *F)
Invalidate the fragments starting with F because it has been resized.
Definition: MCFragment.cpp:52
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:22
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:23
static uint64_t adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, uint64_t Value, MCContext &Ctx, const Triple &TheTriple, bool IsResolved)
SmallVectorImpl< MCFixup > & getFixups()
Definition: MCFragment.h:224
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
llvm::SmallVectorImpl< MCSection * > & getSectionOrder()
Definition: MCAsmLayout.h:66
uint32_t getOffset() const
Definition: MCFixup.h:125
Definition for classes that emit Hexagon machine code from MCInsts.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:398
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A one-byte fixup.
Definition: MCFixup.h:24
unsigned short getExtendableOp(MCInstrInfo const &MCII, MCInst const &MCI)
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
void setOpcode(unsigned Op)
Definition: MCInst.h:173
bool isExtendable(MCInstrInfo const &MCII, MCInst const &MCI)
A four-byte pc relative fixup.
Definition: MCFixup.h:30
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
std::unique_ptr< MCObjectTargetWriter > createHexagonELFObjectWriter(uint8_t OSABI, StringRef CPU)
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:182
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
StringRef getCPU() const
Target - Wrapper for Target specific information.
Class for arbitrary precision integers.
Definition: APInt.h:70
const MCSubtargetInfo * getSubtargetInfo() const
Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
Definition: MCFragment.h:174
static MCOperand createInst(const MCInst *Val)
Definition: MCInst.h:144
const MCInst & getInst() const
Definition: MCFragment.h:282
#define I(x, y, z)
Definition: MD5.cpp:58
Generic base class for all target subtargets.
uint32_t Size
Definition: Profile.cpp:47
uint64_t computeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const
Compute the effective fragment size assuming it is laid out at the given SectionAddress and FragmentO...
size_t bundleSize(MCInst const &MCI)
T * data() const
Definition: ArrayRef.h:329
Target independent information on a fixup kind.
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
Definition: APInt.h:545
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:295
#define HEXAGON_PACKET_SIZE
LLVM Value Representation.
Definition: Value.h:73
Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:42
static const unsigned Nop
Instruction opcodes emitted via means other than CodeGen.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
Check for a valid bundle.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
void addOperand(const MCOperand &Op)
Definition: MCInst.h:186
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
Return the Hexagon ISA class for the insn.
unsigned getOpcode() const
Definition: MCInst.h:174
#define LLVM_DEBUG(X)
Definition: Debug.h:123
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:35
bool mustNotExtend(MCExpr const &Expr)
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:123
A two-byte fixup.
Definition: MCFixup.h:25
void setInst(const MCInst &Value)
Definition: MCFragment.h:283
MCFixupKind getKind() const
Definition: MCFixup.h:123