LLVM  9.0.0svn
MipsAsmBackend.cpp
Go to the documentation of this file.
1 //===-- MipsAsmBackend.cpp - Mips Asm Backend ----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the MipsAsmBackend class.
10 //
11 //===----------------------------------------------------------------------===//
12 //
13 
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/MC/MCAsmBackend.h"
21 #include "llvm/MC/MCAssembler.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCDirectives.h"
26 #include "llvm/MC/MCObjectWriter.h"
29 #include "llvm/MC/MCValue.h"
31 #include "llvm/Support/Format.h"
34 
35 using namespace llvm;
36 
37 // Prepare value for the target space for it
38 static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
39  MCContext &Ctx) {
40 
41  unsigned Kind = Fixup.getKind();
42 
43  // Add/subtract and shift
44  switch (Kind) {
45  default:
46  return 0;
47  case FK_Data_2:
64  Value &= 0xffff;
65  break;
66  case FK_DTPRel_4:
67  case FK_DTPRel_8:
68  case FK_TPRel_4:
69  case FK_TPRel_8:
70  case FK_GPRel_4:
71  case FK_Data_4:
72  case FK_Data_8:
75  break;
77  // The displacement is then divided by 4 to give us an 18 bit
78  // address range. Forcing a signed division because Value can be negative.
79  Value = (int64_t)Value / 4;
80  // We now check if Value can be encoded as a 16-bit signed immediate.
81  if (!isInt<16>(Value)) {
82  Ctx.reportError(Fixup.getLoc(), "out of range PC16 fixup");
83  return 0;
84  }
85  break;
88  // Forcing a signed division because Value can be negative.
89  Value = (int64_t)Value / 4;
90  // We now check if Value can be encoded as a 19-bit signed immediate.
91  if (!isInt<19>(Value)) {
92  Ctx.reportError(Fixup.getLoc(), "out of range PC19 fixup");
93  return 0;
94  }
95  break;
97  // So far we are only using this type for jumps.
98  // The displacement is then divided by 4 to give us an 28 bit
99  // address range.
100  Value >>= 2;
101  break;
109  // Get the 2nd 16-bits. Also add 1 if bit 15 is 1.
110  Value = ((Value + 0x8000) >> 16) & 0xffff;
111  break;
114  // Get the 3rd 16-bits.
115  Value = ((Value + 0x80008000LL) >> 32) & 0xffff;
116  break;
119  // Get the 4th 16-bits.
120  Value = ((Value + 0x800080008000LL) >> 48) & 0xffff;
121  break;
123  Value >>= 1;
124  break;
126  Value -= 4;
127  // Forcing a signed division because Value can be negative.
128  Value = (int64_t) Value / 2;
129  // We now check if Value can be encoded as a 7-bit signed immediate.
130  if (!isInt<7>(Value)) {
131  Ctx.reportError(Fixup.getLoc(), "out of range PC7 fixup");
132  return 0;
133  }
134  break;
136  Value -= 2;
137  // Forcing a signed division because Value can be negative.
138  Value = (int64_t) Value / 2;
139  // We now check if Value can be encoded as a 10-bit signed immediate.
140  if (!isInt<10>(Value)) {
141  Ctx.reportError(Fixup.getLoc(), "out of range PC10 fixup");
142  return 0;
143  }
144  break;
146  Value -= 4;
147  // Forcing a signed division because Value can be negative.
148  Value = (int64_t)Value / 2;
149  // We now check if Value can be encoded as a 16-bit signed immediate.
150  if (!isInt<16>(Value)) {
151  Ctx.reportError(Fixup.getLoc(), "out of range PC16 fixup");
152  return 0;
153  }
154  break;
156  // Forcing a signed division because Value can be negative.
157  Value = (int64_t)Value / 8;
158  // We now check if Value can be encoded as a 18-bit signed immediate.
159  if (!isInt<18>(Value)) {
160  Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup");
161  return 0;
162  }
163  break;
165  // Check alignment.
166  if ((Value & 7)) {
167  Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup");
168  }
169  // Forcing a signed division because Value can be negative.
170  Value = (int64_t)Value / 8;
171  // We now check if Value can be encoded as a 18-bit signed immediate.
172  if (!isInt<18>(Value)) {
173  Ctx.reportError(Fixup.getLoc(), "out of range PC18 fixup");
174  return 0;
175  }
176  break;
178  // Forcing a signed division because Value can be negative.
179  Value = (int64_t) Value / 4;
180  // We now check if Value can be encoded as a 21-bit signed immediate.
181  if (!isInt<21>(Value)) {
182  Ctx.reportError(Fixup.getLoc(), "out of range PC21 fixup");
183  return 0;
184  }
185  break;
187  // Forcing a signed division because Value can be negative.
188  Value = (int64_t) Value / 4;
189  // We now check if Value can be encoded as a 26-bit signed immediate.
190  if (!isInt<26>(Value)) {
191  Ctx.reportError(Fixup.getLoc(), "out of range PC26 fixup");
192  return 0;
193  }
194  break;
196  // Forcing a signed division because Value can be negative.
197  Value = (int64_t)Value / 2;
198  // We now check if Value can be encoded as a 26-bit signed immediate.
199  if (!isInt<26>(Value)) {
200  Ctx.reportFatalError(Fixup.getLoc(), "out of range PC26 fixup");
201  return 0;
202  }
203  break;
205  // Forcing a signed division because Value can be negative.
206  Value = (int64_t)Value / 2;
207  // We now check if Value can be encoded as a 21-bit signed immediate.
208  if (!isInt<21>(Value)) {
209  Ctx.reportError(Fixup.getLoc(), "out of range PC21 fixup");
210  return 0;
211  }
212  break;
213  }
214 
215  return Value;
216 }
217 
218 std::unique_ptr<MCObjectTargetWriter>
220  return createMipsELFObjectWriter(TheTriple, IsN32);
221 }
222 
223 // Little-endian fixup data byte ordering:
224 // mips32r2: a | b | x | x
225 // microMIPS: x | x | a | b
226 
227 static bool needsMMLEByteOrder(unsigned Kind) {
228  return Kind != Mips::fixup_MICROMIPS_PC10_S1 &&
229  Kind >= Mips::fixup_MICROMIPS_26_S1 &&
231 }
232 
233 // Calculate index for microMIPS specific little endian byte order
234 static unsigned calculateMMLEIndex(unsigned i) {
235  assert(i <= 3 && "Index out of range!");
236 
237  return (1 - i / 2) * 2 + i % 2;
238 }
239 
240 /// ApplyFixup - Apply the \p Value for given \p Fixup into the provided
241 /// data fragment, at the offset specified by the fixup and following the
242 /// fixup kind as appropriate.
244  const MCValue &Target,
245  MutableArrayRef<char> Data, uint64_t Value,
246  bool IsResolved,
247  const MCSubtargetInfo *STI) const {
248  MCFixupKind Kind = Fixup.getKind();
249  MCContext &Ctx = Asm.getContext();
250  Value = adjustFixupValue(Fixup, Value, Ctx);
251 
252  if (!Value)
253  return; // Doesn't change encoding.
254 
255  // Where do we start in the object
256  unsigned Offset = Fixup.getOffset();
257  // Number of bytes we need to fixup
258  unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8;
259  // Used to point to big endian bytes
260  unsigned FullSize;
261 
262  switch ((unsigned)Kind) {
263  case FK_Data_2:
264  case Mips::fixup_Mips_16:
266  FullSize = 2;
267  break;
268  case FK_Data_8:
269  case Mips::fixup_Mips_64:
270  FullSize = 8;
271  break;
272  case FK_Data_4:
273  default:
274  FullSize = 4;
275  break;
276  }
277 
278  // Grab current value, if any, from bits.
279  uint64_t CurVal = 0;
280 
281  bool microMipsLEByteOrder = needsMMLEByteOrder((unsigned) Kind);
282 
283  for (unsigned i = 0; i != NumBytes; ++i) {
284  unsigned Idx = Endian == support::little
285  ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i)
286  : (FullSize - 1 - i);
287  CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8);
288  }
289 
290  uint64_t Mask = ((uint64_t)(-1) >>
291  (64 - getFixupKindInfo(Kind).TargetSize));
292  CurVal |= Value & Mask;
293 
294  // Write out the fixed up bytes back to the code/data bits.
295  for (unsigned i = 0; i != NumBytes; ++i) {
296  unsigned Idx = Endian == support::little
297  ? (microMipsLEByteOrder ? calculateMMLEIndex(i) : i)
298  : (FullSize - 1 - i);
299  Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff);
300  }
301 }
302 
305  .Case("R_MIPS_NONE", FK_NONE)
306  .Case("R_MIPS_32", FK_Data_4)
307  .Case("R_MIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_Mips_GOT_PAGE)
308  .Case("R_MIPS_CALL_HI16", (MCFixupKind)Mips::fixup_Mips_CALL_HI16)
309  .Case("R_MIPS_CALL_LO16", (MCFixupKind)Mips::fixup_Mips_CALL_LO16)
310  .Case("R_MIPS_CALL16", (MCFixupKind)Mips::fixup_Mips_CALL16)
311  .Case("R_MIPS_GOT16", (MCFixupKind)Mips::fixup_Mips_GOT)
312  .Case("R_MIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_Mips_GOT_PAGE)
313  .Case("R_MIPS_GOT_OFST", (MCFixupKind)Mips::fixup_Mips_GOT_OFST)
314  .Case("R_MIPS_GOT_DISP", (MCFixupKind)Mips::fixup_Mips_GOT_DISP)
315  .Case("R_MIPS_GOT_HI16", (MCFixupKind)Mips::fixup_Mips_GOT_HI16)
316  .Case("R_MIPS_GOT_LO16", (MCFixupKind)Mips::fixup_Mips_GOT_LO16)
317  .Case("R_MIPS_TLS_GOTTPREL", (MCFixupKind)Mips::fixup_Mips_GOTTPREL)
318  .Case("R_MIPS_TLS_DTPREL_HI16", (MCFixupKind)Mips::fixup_Mips_DTPREL_HI)
319  .Case("R_MIPS_TLS_DTPREL_LO16", (MCFixupKind)Mips::fixup_Mips_DTPREL_LO)
320  .Case("R_MIPS_TLS_GD", (MCFixupKind)Mips::fixup_Mips_TLSGD)
321  .Case("R_MIPS_TLS_LDM", (MCFixupKind)Mips::fixup_Mips_TLSLDM)
322  .Case("R_MIPS_TLS_TPREL_HI16", (MCFixupKind)Mips::fixup_Mips_TPREL_HI)
323  .Case("R_MIPS_TLS_TPREL_LO16", (MCFixupKind)Mips::fixup_Mips_TPREL_LO)
324  .Case("R_MICROMIPS_CALL16", (MCFixupKind)Mips::fixup_MICROMIPS_CALL16)
325  .Case("R_MICROMIPS_GOT_DISP", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_DISP)
326  .Case("R_MICROMIPS_GOT_PAGE", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_PAGE)
327  .Case("R_MICROMIPS_GOT_OFST", (MCFixupKind)Mips::fixup_MICROMIPS_GOT_OFST)
328  .Case("R_MICROMIPS_GOT16", (MCFixupKind)Mips::fixup_MICROMIPS_GOT16)
329  .Case("R_MICROMIPS_TLS_GOTTPREL",
331  .Case("R_MICROMIPS_TLS_DTPREL_HI16",
333  .Case("R_MICROMIPS_TLS_DTPREL_LO16",
335  .Case("R_MICROMIPS_TLS_GD", (MCFixupKind)Mips::fixup_MICROMIPS_TLS_GD)
336  .Case("R_MICROMIPS_TLS_LDM", (MCFixupKind)Mips::fixup_MICROMIPS_TLS_LDM)
337  .Case("R_MICROMIPS_TLS_TPREL_HI16",
339  .Case("R_MICROMIPS_TLS_TPREL_LO16",
341  .Case("R_MIPS_JALR", (MCFixupKind)Mips::fixup_Mips_JALR)
342  .Case("R_MICROMIPS_JALR", (MCFixupKind)Mips::fixup_MICROMIPS_JALR)
344 }
345 
348  const static MCFixupKindInfo LittleEndianInfos[] = {
349  // This table *must* be in same the order of fixup_* kinds in
350  // MipsFixupKinds.h.
351  //
352  // name offset bits flags
353  { "fixup_Mips_16", 0, 16, 0 },
354  { "fixup_Mips_32", 0, 32, 0 },
355  { "fixup_Mips_REL32", 0, 32, 0 },
356  { "fixup_Mips_26", 0, 26, 0 },
357  { "fixup_Mips_HI16", 0, 16, 0 },
358  { "fixup_Mips_LO16", 0, 16, 0 },
359  { "fixup_Mips_GPREL16", 0, 16, 0 },
360  { "fixup_Mips_LITERAL", 0, 16, 0 },
361  { "fixup_Mips_GOT", 0, 16, 0 },
362  { "fixup_Mips_PC16", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
363  { "fixup_Mips_CALL16", 0, 16, 0 },
364  { "fixup_Mips_GPREL32", 0, 32, 0 },
365  { "fixup_Mips_SHIFT5", 6, 5, 0 },
366  { "fixup_Mips_SHIFT6", 6, 5, 0 },
367  { "fixup_Mips_64", 0, 64, 0 },
368  { "fixup_Mips_TLSGD", 0, 16, 0 },
369  { "fixup_Mips_GOTTPREL", 0, 16, 0 },
370  { "fixup_Mips_TPREL_HI", 0, 16, 0 },
371  { "fixup_Mips_TPREL_LO", 0, 16, 0 },
372  { "fixup_Mips_TLSLDM", 0, 16, 0 },
373  { "fixup_Mips_DTPREL_HI", 0, 16, 0 },
374  { "fixup_Mips_DTPREL_LO", 0, 16, 0 },
375  { "fixup_Mips_Branch_PCRel", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
376  { "fixup_Mips_GPOFF_HI", 0, 16, 0 },
377  { "fixup_MICROMIPS_GPOFF_HI",0, 16, 0 },
378  { "fixup_Mips_GPOFF_LO", 0, 16, 0 },
379  { "fixup_MICROMIPS_GPOFF_LO",0, 16, 0 },
380  { "fixup_Mips_GOT_PAGE", 0, 16, 0 },
381  { "fixup_Mips_GOT_OFST", 0, 16, 0 },
382  { "fixup_Mips_GOT_DISP", 0, 16, 0 },
383  { "fixup_Mips_HIGHER", 0, 16, 0 },
384  { "fixup_MICROMIPS_HIGHER", 0, 16, 0 },
385  { "fixup_Mips_HIGHEST", 0, 16, 0 },
386  { "fixup_MICROMIPS_HIGHEST", 0, 16, 0 },
387  { "fixup_Mips_GOT_HI16", 0, 16, 0 },
388  { "fixup_Mips_GOT_LO16", 0, 16, 0 },
389  { "fixup_Mips_CALL_HI16", 0, 16, 0 },
390  { "fixup_Mips_CALL_LO16", 0, 16, 0 },
391  { "fixup_Mips_PC18_S3", 0, 18, MCFixupKindInfo::FKF_IsPCRel },
392  { "fixup_MIPS_PC19_S2", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
393  { "fixup_MIPS_PC21_S2", 0, 21, MCFixupKindInfo::FKF_IsPCRel },
394  { "fixup_MIPS_PC26_S2", 0, 26, MCFixupKindInfo::FKF_IsPCRel },
395  { "fixup_MIPS_PCHI16", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
396  { "fixup_MIPS_PCLO16", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
397  { "fixup_MICROMIPS_26_S1", 0, 26, 0 },
398  { "fixup_MICROMIPS_HI16", 0, 16, 0 },
399  { "fixup_MICROMIPS_LO16", 0, 16, 0 },
400  { "fixup_MICROMIPS_GOT16", 0, 16, 0 },
401  { "fixup_MICROMIPS_PC7_S1", 0, 7, MCFixupKindInfo::FKF_IsPCRel },
402  { "fixup_MICROMIPS_PC10_S1", 0, 10, MCFixupKindInfo::FKF_IsPCRel },
403  { "fixup_MICROMIPS_PC16_S1", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
404  { "fixup_MICROMIPS_PC26_S1", 0, 26, MCFixupKindInfo::FKF_IsPCRel },
405  { "fixup_MICROMIPS_PC19_S2", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
406  { "fixup_MICROMIPS_PC18_S3", 0, 18, MCFixupKindInfo::FKF_IsPCRel },
407  { "fixup_MICROMIPS_PC21_S1", 0, 21, MCFixupKindInfo::FKF_IsPCRel },
408  { "fixup_MICROMIPS_CALL16", 0, 16, 0 },
409  { "fixup_MICROMIPS_GOT_DISP", 0, 16, 0 },
410  { "fixup_MICROMIPS_GOT_PAGE", 0, 16, 0 },
411  { "fixup_MICROMIPS_GOT_OFST", 0, 16, 0 },
412  { "fixup_MICROMIPS_TLS_GD", 0, 16, 0 },
413  { "fixup_MICROMIPS_TLS_LDM", 0, 16, 0 },
414  { "fixup_MICROMIPS_TLS_DTPREL_HI16", 0, 16, 0 },
415  { "fixup_MICROMIPS_TLS_DTPREL_LO16", 0, 16, 0 },
416  { "fixup_MICROMIPS_GOTTPREL", 0, 16, 0 },
417  { "fixup_MICROMIPS_TLS_TPREL_HI16", 0, 16, 0 },
418  { "fixup_MICROMIPS_TLS_TPREL_LO16", 0, 16, 0 },
419  { "fixup_Mips_SUB", 0, 64, 0 },
420  { "fixup_MICROMIPS_SUB", 0, 64, 0 },
421  { "fixup_Mips_JALR", 0, 32, 0 },
422  { "fixup_MICROMIPS_JALR", 0, 32, 0 }
423  };
424  static_assert(array_lengthof(LittleEndianInfos) == Mips::NumTargetFixupKinds,
425  "Not all MIPS little endian fixup kinds added!");
426 
427  const static MCFixupKindInfo BigEndianInfos[] = {
428  // This table *must* be in same the order of fixup_* kinds in
429  // MipsFixupKinds.h.
430  //
431  // name offset bits flags
432  { "fixup_Mips_16", 16, 16, 0 },
433  { "fixup_Mips_32", 0, 32, 0 },
434  { "fixup_Mips_REL32", 0, 32, 0 },
435  { "fixup_Mips_26", 6, 26, 0 },
436  { "fixup_Mips_HI16", 16, 16, 0 },
437  { "fixup_Mips_LO16", 16, 16, 0 },
438  { "fixup_Mips_GPREL16", 16, 16, 0 },
439  { "fixup_Mips_LITERAL", 16, 16, 0 },
440  { "fixup_Mips_GOT", 16, 16, 0 },
441  { "fixup_Mips_PC16", 16, 16, MCFixupKindInfo::FKF_IsPCRel },
442  { "fixup_Mips_CALL16", 16, 16, 0 },
443  { "fixup_Mips_GPREL32", 0, 32, 0 },
444  { "fixup_Mips_SHIFT5", 21, 5, 0 },
445  { "fixup_Mips_SHIFT6", 21, 5, 0 },
446  { "fixup_Mips_64", 0, 64, 0 },
447  { "fixup_Mips_TLSGD", 16, 16, 0 },
448  { "fixup_Mips_GOTTPREL", 16, 16, 0 },
449  { "fixup_Mips_TPREL_HI", 16, 16, 0 },
450  { "fixup_Mips_TPREL_LO", 16, 16, 0 },
451  { "fixup_Mips_TLSLDM", 16, 16, 0 },
452  { "fixup_Mips_DTPREL_HI", 16, 16, 0 },
453  { "fixup_Mips_DTPREL_LO", 16, 16, 0 },
454  { "fixup_Mips_Branch_PCRel",16, 16, MCFixupKindInfo::FKF_IsPCRel },
455  { "fixup_Mips_GPOFF_HI", 16, 16, 0 },
456  { "fixup_MICROMIPS_GPOFF_HI", 16, 16, 0 },
457  { "fixup_Mips_GPOFF_LO", 16, 16, 0 },
458  { "fixup_MICROMIPS_GPOFF_LO", 16, 16, 0 },
459  { "fixup_Mips_GOT_PAGE", 16, 16, 0 },
460  { "fixup_Mips_GOT_OFST", 16, 16, 0 },
461  { "fixup_Mips_GOT_DISP", 16, 16, 0 },
462  { "fixup_Mips_HIGHER", 16, 16, 0 },
463  { "fixup_MICROMIPS_HIGHER", 16, 16, 0 },
464  { "fixup_Mips_HIGHEST", 16, 16, 0 },
465  { "fixup_MICROMIPS_HIGHEST",16, 16, 0 },
466  { "fixup_Mips_GOT_HI16", 16, 16, 0 },
467  { "fixup_Mips_GOT_LO16", 16, 16, 0 },
468  { "fixup_Mips_CALL_HI16", 16, 16, 0 },
469  { "fixup_Mips_CALL_LO16", 16, 16, 0 },
470  { "fixup_Mips_PC18_S3", 14, 18, MCFixupKindInfo::FKF_IsPCRel },
471  { "fixup_MIPS_PC19_S2", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
472  { "fixup_MIPS_PC21_S2", 11, 21, MCFixupKindInfo::FKF_IsPCRel },
473  { "fixup_MIPS_PC26_S2", 6, 26, MCFixupKindInfo::FKF_IsPCRel },
474  { "fixup_MIPS_PCHI16", 16, 16, MCFixupKindInfo::FKF_IsPCRel },
475  { "fixup_MIPS_PCLO16", 16, 16, MCFixupKindInfo::FKF_IsPCRel },
476  { "fixup_MICROMIPS_26_S1", 6, 26, 0 },
477  { "fixup_MICROMIPS_HI16", 16, 16, 0 },
478  { "fixup_MICROMIPS_LO16", 16, 16, 0 },
479  { "fixup_MICROMIPS_GOT16", 16, 16, 0 },
480  { "fixup_MICROMIPS_PC7_S1", 9, 7, MCFixupKindInfo::FKF_IsPCRel },
481  { "fixup_MICROMIPS_PC10_S1", 6, 10, MCFixupKindInfo::FKF_IsPCRel },
482  { "fixup_MICROMIPS_PC16_S1",16, 16, MCFixupKindInfo::FKF_IsPCRel },
483  { "fixup_MICROMIPS_PC26_S1", 6, 26, MCFixupKindInfo::FKF_IsPCRel },
484  { "fixup_MICROMIPS_PC19_S2",13, 19, MCFixupKindInfo::FKF_IsPCRel },
485  { "fixup_MICROMIPS_PC18_S3",14, 18, MCFixupKindInfo::FKF_IsPCRel },
486  { "fixup_MICROMIPS_PC21_S1",11, 21, MCFixupKindInfo::FKF_IsPCRel },
487  { "fixup_MICROMIPS_CALL16", 16, 16, 0 },
488  { "fixup_MICROMIPS_GOT_DISP", 16, 16, 0 },
489  { "fixup_MICROMIPS_GOT_PAGE", 16, 16, 0 },
490  { "fixup_MICROMIPS_GOT_OFST", 16, 16, 0 },
491  { "fixup_MICROMIPS_TLS_GD", 16, 16, 0 },
492  { "fixup_MICROMIPS_TLS_LDM", 16, 16, 0 },
493  { "fixup_MICROMIPS_TLS_DTPREL_HI16", 16, 16, 0 },
494  { "fixup_MICROMIPS_TLS_DTPREL_LO16", 16, 16, 0 },
495  { "fixup_MICROMIPS_GOTTPREL", 16, 16, 0 },
496  { "fixup_MICROMIPS_TLS_TPREL_HI16", 16, 16, 0 },
497  { "fixup_MICROMIPS_TLS_TPREL_LO16", 16, 16, 0 },
498  { "fixup_Mips_SUB", 0, 64, 0 },
499  { "fixup_MICROMIPS_SUB", 0, 64, 0 },
500  { "fixup_Mips_JALR", 0, 32, 0 },
501  { "fixup_MICROMIPS_JALR", 0, 32, 0 }
502  };
503  static_assert(array_lengthof(BigEndianInfos) == Mips::NumTargetFixupKinds,
504  "Not all MIPS big endian fixup kinds added!");
505 
506  if (Kind < FirstTargetFixupKind)
507  return MCAsmBackend::getFixupKindInfo(Kind);
508 
509  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
510  "Invalid kind!");
511 
512  if (Endian == support::little)
513  return LittleEndianInfos[Kind - FirstTargetFixupKind];
514  return BigEndianInfos[Kind - FirstTargetFixupKind];
515 }
516 
517 /// WriteNopData - Write an (optimal) nop sequence of Count bytes
518 /// to the given output. If the target cannot generate such a sequence,
519 /// it should return an error.
520 ///
521 /// \return - True on success.
522 bool MipsAsmBackend::writeNopData(raw_ostream &OS, uint64_t Count) const {
523  // Check for a less than instruction size number of bytes
524  // FIXME: 16 bit instructions are not handled yet here.
525  // We shouldn't be using a hard coded number for instruction size.
526 
527  // If the count is not 4-byte aligned, we must be writing data into the text
528  // section (otherwise we have unaligned instructions, and thus have far
529  // bigger problems), so just write zeros instead.
530  OS.write_zeros(Count);
531  return true;
532 }
533 
535  const MCFixup &Fixup,
536  const MCValue &Target) {
537  const unsigned FixupKind = Fixup.getKind();
538  switch (FixupKind) {
539  default:
540  return false;
541  // All these relocations require special processing
542  // at linking time. Delegate this work to a linker.
573  return true;
574  }
575 }
576 
577 bool MipsAsmBackend::isMicroMips(const MCSymbol *Sym) const {
578  if (const auto *ElfSym = dyn_cast<const MCSymbolELF>(Sym)) {
579  if (ElfSym->getOther() & ELF::STO_MIPS_MICROMIPS)
580  return true;
581  }
582  return false;
583 }
584 
586  const MCSubtargetInfo &STI,
587  const MCRegisterInfo &MRI,
588  const MCTargetOptions &Options) {
590  return new MipsAsmBackend(T, MRI, STI.getTargetTriple(), STI.getCPU(), ABI.IsN32());
591 }
static bool needsMMLEByteOrder(unsigned Kind)
A eight-byte dtp relative fixup.
Definition: MCFixup.h:37
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef< char > Data, uint64_t Value, bool IsResolved, const MCSubtargetInfo *STI) const override
ApplyFixup - Apply the Value for given Fixup into the provided data fragment, at the offset specified...
This class represents lattice values for constants.
Definition: AllocatorList.h:23
This represents an "assembler immediate".
Definition: MCValue.h:39
const support::endianness Endian
Definition: MCAsmBackend.h:52
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
std::unique_ptr< MCObjectTargetWriter > createMipsELFObjectWriter(const Triple &TT, bool IsN32)
raw_ostream & write_zeros(unsigned NumZeros)
write_zeros - Insert &#39;NumZeros&#39; nulls.
virtual const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:305
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target) override
Hook to check if a relocation is needed for some target specific reason.
static Lanai::Fixups FixupKind(const MCExpr *Expr)
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:67
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:284
const MCFixupKindInfo & getFixupKindInfo(MCFixupKind Kind) const override
Get information on a fixup kind.
A four-byte tp relative fixup.
Definition: MCFixup.h:38
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:181
bool IsN32() const
Definition: MipsABIInfo.h:42
A four-byte fixup.
Definition: MCFixup.h:26
unsigned getNumFixupKinds() const override
Get the number of target specific fixup kinds.
MCAsmBackend * createMipsAsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Context object for machine code objects.
Definition: MCContext.h:64
MipsAsmBackend(const Target &T, const MCRegisterInfo &MRI, const Triple &TT, StringRef CPU, bool N32)
A four-byte gp relative fixup.
Definition: MCFixup.h:34
std::unique_ptr< MCObjectTargetWriter > createObjectTargetWriter() const override
LLVM_ATTRIBUTE_NORETURN void reportFatalError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:693
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
A four-byte dtp relative fixup.
Definition: MCFixup.h:36
unsigned const MachineRegisterInfo * MRI
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:290
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:22
bool writeNopData(raw_ostream &OS, uint64_t Count) const override
WriteNopData - Write an (optimal) nop sequence of Count bytes to the given output.
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:679
uint32_t getOffset() const
Definition: MCFixup.h:125
A eight-byte tp relative fixup.
Definition: MCFixup.h:39
SMLoc getLoc() const
Definition: MCFixup.h:166
A no-op fixup.
Definition: MCFixup.h:23
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:1050
virtual Optional< MCFixupKind > getFixupKind(StringRef Name) const
Map a relocation name used in .reloc to a fixup kind.
unsigned TargetSize
The number of bits written by this fixup.
StringRef getCPU() const
Target - Wrapper for Target specific information.
bool isMicroMips(const MCSymbol *Sym) const override
Check whether a given symbol has been flagged with MICROMIPS flag.
Generic base class for all target subtargets.
A eight-byte fixup.
Definition: MCFixup.h:27
Optional< MCFixupKind > getFixupKind(StringRef Name) const override
Map a relocation name used in .reloc to a fixup kind.
Target independent information on a fixup kind.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static MipsABIInfo computeTargetABI(const Triple &TT, StringRef CPU, const MCTargetOptions &Options)
Definition: MipsABIInfo.cpp:56
LLVM Value Representation.
Definition: Value.h:72
Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:41
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:80
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, MCContext &Ctx)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
static unsigned calculateMMLEIndex(unsigned i)
A two-byte fixup.
Definition: MCFixup.h:25
MCFixupKind getKind() const
Definition: MCFixup.h:123