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