LLVM  3.7.0
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"
12 #include "HexagonMCTargetDesc.h"
15 #include "llvm/MC/MCAsmBackend.h"
16 #include "llvm/MC/MCAssembler.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/Support/Debug.h"
22 
23 using namespace llvm;
24 using namespace Hexagon;
25 
26 #define DEBUG_TYPE "hexagon-asm-backend"
27 
28 namespace {
29 
30 class HexagonAsmBackend : public MCAsmBackend {
31  uint8_t OSABI;
32  StringRef CPU;
33  mutable uint64_t relaxedCnt;
34  std::unique_ptr <MCInstrInfo> MCII;
35  std::unique_ptr <MCInst *> RelaxTarget;
36 public:
37  HexagonAsmBackend(Target const &T, uint8_t OSABI, StringRef CPU) :
38  OSABI(OSABI), MCII (T.createMCInstrInfo()), RelaxTarget(new MCInst *){}
39 
40  MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override {
41  return createHexagonELFObjectWriter(OS, OSABI, CPU);
42  }
43 
44  unsigned getNumFixupKinds() const override {
46  }
47 
48  const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
49  const static MCFixupKindInfo Infos[Hexagon::NumTargetFixupKinds] = {
50  // This table *must* be in same the order of fixup_* kinds in
51  // HexagonFixupKinds.h.
52  //
53  // namei offset bits flags
54  {"fixup_Hexagon_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
55  {"fixup_Hexagon_B15_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
56  {"fixup_Hexagon_B7_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
57  {"fixup_Hexagon_LO16", 0, 32, 0},
58  {"fixup_Hexagon_HI16", 0, 32, 0},
59  {"fixup_Hexagon_32", 0, 32, 0},
60  {"fixup_Hexagon_16", 0, 32, 0},
61  {"fixup_Hexagon_8", 0, 32, 0},
62  {"fixup_Hexagon_GPREL16_0", 0, 32, 0},
63  {"fixup_Hexagon_GPREL16_1", 0, 32, 0},
64  {"fixup_Hexagon_GPREL16_2", 0, 32, 0},
65  {"fixup_Hexagon_GPREL16_3", 0, 32, 0},
66  {"fixup_Hexagon_HL16", 0, 32, 0},
67  {"fixup_Hexagon_B13_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
68  {"fixup_Hexagon_B9_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
69  {"fixup_Hexagon_B32_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
70  {"fixup_Hexagon_32_6_X", 0, 32, 0},
71  {"fixup_Hexagon_B22_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
72  {"fixup_Hexagon_B15_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
73  {"fixup_Hexagon_B13_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
74  {"fixup_Hexagon_B9_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
75  {"fixup_Hexagon_B7_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
76  {"fixup_Hexagon_16_X", 0, 32, 0},
77  {"fixup_Hexagon_12_X", 0, 32, 0},
78  {"fixup_Hexagon_11_X", 0, 32, 0},
79  {"fixup_Hexagon_10_X", 0, 32, 0},
80  {"fixup_Hexagon_9_X", 0, 32, 0},
81  {"fixup_Hexagon_8_X", 0, 32, 0},
82  {"fixup_Hexagon_7_X", 0, 32, 0},
83  {"fixup_Hexagon_6_X", 0, 32, 0},
84  {"fixup_Hexagon_32_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
85  {"fixup_Hexagon_COPY", 0, 32, 0},
86  {"fixup_Hexagon_GLOB_DAT", 0, 32, 0},
87  {"fixup_Hexagon_JMP_SLOT", 0, 32, 0},
88  {"fixup_Hexagon_RELATIVE", 0, 32, 0},
89  {"fixup_Hexagon_PLT_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
90  {"fixup_Hexagon_GOTREL_LO16", 0, 32, 0},
91  {"fixup_Hexagon_GOTREL_HI16", 0, 32, 0},
92  {"fixup_Hexagon_GOTREL_32", 0, 32, 0},
93  {"fixup_Hexagon_GOT_LO16", 0, 32, 0},
94  {"fixup_Hexagon_GOT_HI16", 0, 32, 0},
95  {"fixup_Hexagon_GOT_32", 0, 32, 0},
96  {"fixup_Hexagon_GOT_16", 0, 32, 0},
97  {"fixup_Hexagon_DTPMOD_32", 0, 32, 0},
98  {"fixup_Hexagon_DTPREL_LO16", 0, 32, 0},
99  {"fixup_Hexagon_DTPREL_HI16", 0, 32, 0},
100  {"fixup_Hexagon_DTPREL_32", 0, 32, 0},
101  {"fixup_Hexagon_DTPREL_16", 0, 32, 0},
102  {"fixup_Hexagon_GD_PLT_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
103  {"fixup_Hexagon_LD_PLT_B22_PCREL", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
104  {"fixup_Hexagon_GD_GOT_LO16", 0, 32, 0},
105  {"fixup_Hexagon_GD_GOT_HI16", 0, 32, 0},
106  {"fixup_Hexagon_GD_GOT_32", 0, 32, 0},
107  {"fixup_Hexagon_GD_GOT_16", 0, 32, 0},
108  {"fixup_Hexagon_LD_GOT_LO16", 0, 32, 0},
109  {"fixup_Hexagon_LD_GOT_HI16", 0, 32, 0},
110  {"fixup_Hexagon_LD_GOT_32", 0, 32, 0},
111  {"fixup_Hexagon_LD_GOT_16", 0, 32, 0},
112  {"fixup_Hexagon_IE_LO16", 0, 32, 0},
113  {"fixup_Hexagon_IE_HI16", 0, 32, 0},
114  {"fixup_Hexagon_IE_32", 0, 32, 0},
115  {"fixup_Hexagon_IE_16", 0, 32, 0},
116  {"fixup_Hexagon_IE_GOT_LO16", 0, 32, 0},
117  {"fixup_Hexagon_IE_GOT_HI16", 0, 32, 0},
118  {"fixup_Hexagon_IE_GOT_32", 0, 32, 0},
119  {"fixup_Hexagon_IE_GOT_16", 0, 32, 0},
120  {"fixup_Hexagon_TPREL_LO16", 0, 32, 0},
121  {"fixup_Hexagon_TPREL_HI16", 0, 32, 0},
122  {"fixup_Hexagon_TPREL_32", 0, 32, 0},
123  {"fixup_Hexagon_TPREL_16", 0, 32, 0},
124  {"fixup_Hexagon_6_PCREL_X", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
125  {"fixup_Hexagon_GOTREL_32_6_X", 0, 32, 0},
126  {"fixup_Hexagon_GOTREL_16_X", 0, 32, 0},
127  {"fixup_Hexagon_GOTREL_11_X", 0, 32, 0},
128  {"fixup_Hexagon_GOT_32_6_X", 0, 32, 0},
129  {"fixup_Hexagon_GOT_16_X", 0, 32, 0},
130  {"fixup_Hexagon_GOT_11_X", 0, 32, 0},
131  {"fixup_Hexagon_DTPREL_32_6_X", 0, 32, 0},
132  {"fixup_Hexagon_DTPREL_16_X", 0, 32, 0},
133  {"fixup_Hexagon_DTPREL_11_X", 0, 32, 0},
134  {"fixup_Hexagon_GD_GOT_32_6_X", 0, 32, 0},
135  {"fixup_Hexagon_GD_GOT_16_X", 0, 32, 0},
136  {"fixup_Hexagon_GD_GOT_11_X", 0, 32, 0},
137  {"fixup_Hexagon_LD_GOT_32_6_X", 0, 32, 0},
138  {"fixup_Hexagon_LD_GOT_16_X", 0, 32, 0},
139  {"fixup_Hexagon_LD_GOT_11_X", 0, 32, 0},
140  {"fixup_Hexagon_IE_32_6_X", 0, 32, 0},
141  {"fixup_Hexagon_IE_16_X", 0, 32, 0},
142  {"fixup_Hexagon_IE_GOT_32_6_X", 0, 32, 0},
143  {"fixup_Hexagon_IE_GOT_16_X", 0, 32, 0},
144  {"fixup_Hexagon_IE_GOT_11_X", 0, 32, 0},
145  {"fixup_Hexagon_TPREL_32_6_X", 0, 32, 0},
146  {"fixup_Hexagon_TPREL_16_X", 0, 32, 0},
147  {"fixup_Hexagon_TPREL_11_X", 0, 32, 0}};
148 
149  if (Kind < FirstTargetFixupKind) {
150  return MCAsmBackend::getFixupKindInfo(Kind);
151  }
152 
153  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
154  "Invalid kind!");
155  return Infos[Kind - FirstTargetFixupKind];
156  }
157 
158  void applyFixup(MCFixup const & /*Fixup*/, char * /*Data*/,
159  unsigned /*DataSize*/, uint64_t /*Value*/,
160  bool /*IsPCRel*/) const override {
161  return;
162  }
163 
164  bool isInstRelaxable(MCInst const &HMI) const {
165  const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(*MCII, HMI);
166  bool Relaxable = false;
167  // Branches and loop-setup insns are handled as necessary by relaxation.
170  MCID.isBranch()) ||
172  HMI.getOpcode() != Hexagon::C4_addipc))
173  if (HexagonMCInstrInfo::isExtendable(*MCII, HMI))
174  Relaxable = true;
175 
176  return Relaxable;
177  }
178 
179  /// MayNeedRelaxation - Check whether the given instruction may need
180  /// relaxation.
181  ///
182  /// \param Inst - The instruction to test.
183  bool mayNeedRelaxation(MCInst const &Inst) const override {
184  assert(HexagonMCInstrInfo::isBundle(Inst));
185  bool PreviousIsExtender = false;
186  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(Inst)) {
187  auto const &Inst = *I.getInst();
188  if (!PreviousIsExtender) {
189  if (isInstRelaxable(Inst))
190  return true;
191  }
192  PreviousIsExtender = HexagonMCInstrInfo::isImmext(Inst);
193  }
194  return false;
195  }
196 
197  /// fixupNeedsRelaxation - Target specific predicate for whether a given
198  /// fixup requires the associated instruction to be relaxed.
199  bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved,
200  uint64_t Value,
201  const MCRelaxableFragment *DF,
202  const MCAsmLayout &Layout) const override {
203  MCInst const &MCB = DF->getInst();
204  assert(HexagonMCInstrInfo::isBundle(MCB));
205 
206  *RelaxTarget = nullptr;
207  MCInst &MCI = const_cast<MCInst &>(HexagonMCInstrInfo::instruction(
208  MCB, Fixup.getOffset() / HEXAGON_INSTR_SIZE));
209  // If we cannot resolve the fixup value, it requires relaxation.
210  if (!Resolved) {
211  switch ((unsigned)Fixup.getKind()) {
213  // GetFixupCount assumes B22 won't relax
214  // Fallthrough
215  default:
216  return false;
217  break;
221  case fixup_Hexagon_B7_PCREL: {
223  ++relaxedCnt;
224  *RelaxTarget = &MCI;
225  return true;
226  } else {
227  return false;
228  }
229  break;
230  }
231  }
232  }
233  bool Relaxable = isInstRelaxable(MCI);
234  if (Relaxable == false)
235  return false;
236 
237  MCFixupKind Kind = Fixup.getKind();
238  int64_t sValue = Value;
239  int64_t maxValue;
240 
241  switch ((unsigned)Kind) {
243  maxValue = 1 << 8;
244  break;
246  maxValue = 1 << 10;
247  break;
249  maxValue = 1 << 16;
250  break;
252  maxValue = 1 << 23;
253  break;
254  default:
255  maxValue = INT64_MAX;
256  break;
257  }
258 
259  bool isFarAway = -maxValue > sValue || sValue > maxValue - 1;
260 
261  if (isFarAway) {
263  ++relaxedCnt;
264  *RelaxTarget = &MCI;
265  return true;
266  }
267  }
268 
269  return false;
270  }
271 
272  /// Simple predicate for targets where !Resolved implies requiring relaxation
273  bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
274  const MCRelaxableFragment *DF,
275  const MCAsmLayout &Layout) const override {
276  llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
277  }
278 
279  void relaxInstruction(MCInst const & /*Inst*/,
280  MCInst & /*Res*/) const override {
281  llvm_unreachable("relaxInstruction() unimplemented");
282  }
283 
284  bool writeNopData(uint64_t Count,
285  MCObjectWriter * OW) const override {
286  static const uint32_t Nopcode = 0x7f000000, // Hard-coded NOP.
287  ParseIn = 0x00004000, // In packet parse-bits.
288  ParseEnd = 0x0000c000; // End of packet parse-bits.
289 
290  while(Count % HEXAGON_INSTR_SIZE) {
291  DEBUG(dbgs() << "Alignment not a multiple of the instruction size:" <<
292  Count % HEXAGON_INSTR_SIZE << "/" << HEXAGON_INSTR_SIZE << "\n");
293  --Count;
294  OW->write8(0);
295  }
296 
297  while(Count) {
298  Count -= HEXAGON_INSTR_SIZE;
299  // Close the packet whenever a multiple of the maximum packet size remains
300  uint32_t ParseBits = (Count % (HEXAGON_PACKET_SIZE * HEXAGON_INSTR_SIZE))?
301  ParseIn: ParseEnd;
302  OW->write32(Nopcode | ParseBits);
303  }
304  return true;
305  }
306 };
307 } // end anonymous namespace
308 
309 namespace llvm {
311  MCRegisterInfo const & /*MRI*/,
312  const Triple &TT, StringRef CPU) {
313  uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
314  return new HexagonAsmBackend(T, OSABI, CPU);
315 }
316 }
OSType getOS() const
getOS - Get the parsed operating system type of this triple.
Definition: Triple.h:251
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:138
bool isBundle(MCInst const &MCI)
Defines the object file and target independent interfaces used by the assembler backend to write nati...
void write8(uint8_t Value)
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:62
const MCInst & getInst() const
Definition: MCAssembler.h:275
Is this fixup kind PCrelative? This is used by the assembler backend to evaluate fixup values in a ta...
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
bool isImmext(MCInst const &MCI)
MCInst const & instruction(MCInst const &MCB, size_t Index)
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:29
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
#define HEXAGON_PACKET_SIZE
Definition: Hexagon.h:33
bool isBranch() const
Returns true if this is a conditional, unconditional, or indirect branch.
Definition: MCInstrDesc.h:233
MCAsmBackend * createHexagonAsmBackend(Target const &T, MCRegisterInfo const &, const Triple &TT, StringRef CPU)
uint32_t getOffset() const
Definition: MCFixup.h:91
MCObjectWriter * createHexagonELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI, StringRef CPU)
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
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)
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:23
iterator_range< MCInst::const_iterator > bundleInstructions(MCInst const &MCI)
MCFixupKind getKind() const
Definition: MCFixup.h:89
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
PowerPC TLS Dynamic Call Fixup
bool isExtendable(MCInstrInfo const &MCII, MCInst const &MCI)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:123
unsigned getOpcode() const
Definition: MCInst.h:159
Target - Wrapper for Target specific information.
#define I(x, y, z)
Definition: MD5.cpp:54
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
size_t bundleSize(MCInst const &MCI)
Target independent information on a fixup kind.
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:321
const ARM::ArchExtKind Kind
#define HEXAGON_INSTR_SIZE
Definition: Hexagon.h:30
LLVM Value Representation.
Definition: Value.h:69
Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:34
#define DEBUG(X)
Definition: Debug.h:92
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
unsigned getType(MCInstrInfo const &MCII, MCInst const &MCI)
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.