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
15#include "MCTargetDesc/MipsFixupKinds.h"
16#include "MCTargetDesc/MipsAsmBackend.h"
17#include "MCTargetDesc/MipsMCExpr.h"
18#include "MCTargetDesc/MipsMCTargetDesc.h"
19#include "llvm/MC/MCAsmBackend.h"
20#include "llvm/MC/MCAssembler.h"
21#include "llvm/MC/MCContext.h"
22#include "llvm/MC/MCDirectives.h"
23#include "llvm/MC/MCELFObjectWriter.h"
24#include "llvm/MC/MCFixupKindInfo.h"
25#include "llvm/MC/MCObjectWriter.h"
26#include "llvm/MC/MCSubtargetInfo.h"
27#include "llvm/MC/MCValue.h"
28#include "llvm/Support/ErrorHandling.h"
29#include "llvm/Support/Format.h"
30#include "llvm/Support/MathExtras.h"
31#include "llvm/Support/raw_ostream.h"
32
33using namespace llvm;
34
35// Prepare value for the target space for it
36static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
37                                 MCContext *Ctx = nullptr) {
38
39  unsigned Kind = Fixup.getKind();
40
41  // Add/subtract and shift
42  switch (Kind) {
43  default:
44    return 0;
45  case FK_Data_2:
46  case Mips::fixup_Mips_LO16:
47  case Mips::fixup_Mips_GPREL16:
48  case Mips::fixup_Mips_GPOFF_HI:
49  case Mips::fixup_Mips_GPOFF_LO:
50  case Mips::fixup_Mips_GOT_PAGE:
51  case Mips::fixup_Mips_GOT_OFST:
52  case Mips::fixup_Mips_GOT_DISP:
53  case Mips::fixup_Mips_GOT_LO16:
54  case Mips::fixup_Mips_CALL_LO16:
55  case Mips::fixup_MICROMIPS_LO16:
56  case Mips::fixup_MICROMIPS_GOT_PAGE:
57  case Mips::fixup_MICROMIPS_GOT_OFST:
58  case Mips::fixup_MICROMIPS_GOT_DISP:
59  case Mips::fixup_MIPS_PCLO16:
60    Value &= 0xffff;
61    break;
62  case FK_GPRel_4:
63  case FK_Data_4:
64  case FK_Data_8:
65    break;
66  case Mips::fixup_Mips_PC16:
67    // The displacement is then divided by 4 to give us an 18 bit
68    // address range. Forcing a signed division because Value can be negative.
69    Value = (int64_t)Value / 4;
70    // We now check if Value can be encoded as a 16-bit signed immediate.
71    if (!isInt<16>(Value) && Ctx) {
72      Ctx->reportError(Fixup.getLoc(), "out of range PC16 fixup");
73      return 0;
74    }
75    break;
76  case Mips::fixup_MIPS_PC19_S2:
77  case Mips::fixup_MICROMIPS_PC19_S2:
78    // 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 19-bit signed immediate.
81    if (!isInt<19>(Value) && Ctx) {
82      Ctx->reportError(Fixup.getLoc(), "out of range PC19 fixup");
83      return 0;
84    }
85    break;
86  case Mips::fixup_Mips_26:
87    // So far we are only using this type for jumps.
88    // The displacement is then divided by 4 to give us an 28 bit
89    // address range.
90    Value >>= 2;
91    break;
92  case Mips::fixup_Mips_HI16:
93  case Mips::fixup_Mips_GOT:
94  case Mips::fixup_MICROMIPS_GOT16:
95  case Mips::fixup_Mips_GOT_HI16:
96  case Mips::fixup_Mips_CALL_HI16:
97  case Mips::fixup_MICROMIPS_HI16:
98  case Mips::fixup_MIPS_PCHI16:
99    // Get the 2nd 16-bits. Also add 1 if bit 15 is 1.
100    Value = ((Value + 0x8000) >> 16) & 0xffff;
101    break;
102  case Mips::fixup_Mips_HIGHER:
103    // Get the 3rd 16-bits.
104    Value = ((Value + 0x80008000LL) >> 32) & 0xffff;
105    break;
106  case Mips::fixup_Mips_HIGHEST:
107    // Get the 4th 16-bits.
108    Value = ((Value + 0x800080008000LL) >> 48) & 0xffff;
109    break;
110  case Mips::fixup_MICROMIPS_26_S1:
111    Value >>= 1;
112    break;
113  case Mips::fixup_MICROMIPS_PC7_S1:
114    Value -= 4;
115    // Forcing a signed division because Value can be negative.
116    Value = (int64_t) Value / 2;
117    // We now check if Value can be encoded as a 7-bit signed immediate.
118    if (!isInt<7>(Value) && Ctx) {
119      Ctx->reportError(Fixup.getLoc(), "out of range PC7 fixup");
120      return 0;
121    }
122    break;
123  case Mips::fixup_MICROMIPS_PC10_S1:
124    Value -= 2;
125    // Forcing a signed division because Value can be negative.
126    Value = (int64_t) Value / 2;
127    // We now check if Value can be encoded as a 10-bit signed immediate.
128    if (!isInt<10>(Value) && Ctx) {
129      Ctx->reportError(Fixup.getLoc(), "out of range PC10 fixup");
130      return 0;
131    }
132    break;
133  case Mips::fixup_MICROMIPS_PC16_S1:
134    Value -= 4;
135    // Forcing a signed division because Value can be negative.
136    Value = (int64_t)Value / 2;
137    // We now check if Value can be encoded as a 16-bit signed immediate.
138    if (!isInt<16>(Value) && Ctx) {
139      Ctx->reportError(Fixup.getLoc(), "out of range PC16 fixup");
140      return 0;
141    }
142    break;
143  case Mips::fixup_MIPS_PC18_S3:
144    // Forcing a signed division because Value can be negative.
145    Value = (int64_t)Value / 8;
146    // We now check if Value can be encoded as a 18-bit signed immediate.
147    if (!isInt<18>(Value) && Ctx) {
148      Ctx->reportError(Fixup.getLoc(), "out of range PC18 fixup");
149      return 0;
150    }
151    break;
152  case Mips::fixup_MICROMIPS_PC18_S3:
153    // Check alignment.
154    if ((Value & 7) && Ctx) {
155      Ctx->reportError(Fixup.getLoc(), "out of range PC18 fixup");
156    }
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) && Ctx) {
161      Ctx->reportError(Fixup.getLoc(), "out of range PC18 fixup");
162      return 0;
163    }
164    break;
165  case Mips::fixup_MIPS_PC21_S2:
166    // Forcing a signed division because Value can be negative.
167    Value = (int64_t) Value / 4;
168    // We now check if Value can be encoded as a 21-bit signed immediate.
169    if (!isInt<21>(Value) && Ctx) {
170      Ctx->reportError(Fixup.getLoc(), "out of range PC21 fixup");
171      return 0;
172    }
173    break;
174  case Mips::fixup_MIPS_PC26_S2:
175    // Forcing a signed division because Value can be negative.
176    Value = (int64_t) Value / 4;
177    // We now check if Value can be encoded as a 26-bit signed immediate.
178    if (!isInt<26>(Value) && Ctx) {
179      Ctx->reportError(Fixup.getLoc(), "out of range PC26 fixup");
180      return 0;
181    }
182    break;
183  case Mips::fixup_MICROMIPS_PC26_S1:
184    // Forcing a signed division because Value can be negative.
185    Value = (int64_t)Value / 2;
186    // We now check if Value can be encoded as a 26-bit signed immediate.
187    if (!isInt<26>(Value) && Ctx) {
188      Ctx->reportFatalError(Fixup.getLoc(), "out of range PC26 fixup");
189      return 0;
190    }
191    break;
192  case Mips::fixup_MICROMIPS_PC21_S1:
193    // Forcing a signed division because Value can be negative.
194    Value = (int64_t)Value / 2;
195    // We now check if Value can be encoded as a 21-bit signed immediate.
196    if (!isInt<21>(Value) && Ctx) {
197      Ctx->reportError(Fixup.getLoc(), "out of range PC21 fixup");
198      return 0;
199    }
200    break;
201  }
202
203  return Value;
204}
205
206MCObjectWriter *
207MipsAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
208  return createMipsELFObjectWriter(OS,
209    MCELFObjectTargetWriter::getOSABI(OSType), IsLittle, Is64Bit);
210}
211
212// Little-endian fixup data byte ordering:
213//   mips32r2:   a | b | x | x
214//   microMIPS:  x | x | a | b
215
216static bool needsMMLEByteOrder(unsigned Kind) {
217  return Kind != Mips::fixup_MICROMIPS_PC10_S1 &&
218         Kind >= Mips::fixup_MICROMIPS_26_S1 &&
219         Kind < Mips::LastTargetFixupKind;
220}
221
222// Calculate index for microMIPS specific little endian byte order
223static unsigned calculateMMLEIndex(unsigned i) {
224  assert(i <= 3 && "Index out of range!");
225
226  return (1 - i / 2) * 2 + i % 2;
227}
228
229/// ApplyFixup - Apply the \p Value for given \p Fixup into the provided
230/// data fragment, at the offset specified by the fixup and following the
231/// fixup kind as appropriate.
232void MipsAsmBackend::applyFixup(const MCFixup &Fixup, char *Data,
233                                unsigned DataSize, uint64_t Value,
234                                bool IsPCRel) const {
235  MCFixupKind Kind = Fixup.getKind();
236  Value = adjustFixupValue(Fixup, Value);
237
238  if (!Value)
239    return; // Doesn't change encoding.
240
241  // Where do we start in the object
242  unsigned Offset = Fixup.getOffset();
243  // Number of bytes we need to fixup
244  unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8;
245  // Used to point to big endian bytes
246  unsigned FullSize;
247
248  switch ((unsigned)Kind) {
249  case FK_Data_2:
250  case Mips::fixup_Mips_16:
251  case Mips::fixup_MICROMIPS_PC10_S1:
252    FullSize = 2;
253    break;
254  case FK_Data_8:
255  case Mips::fixup_Mips_64:
256    FullSize = 8;
257    break;
258  case FK_Data_4:
259  default:
260    FullSize = 4;
261    break;
262  }
263
264  // Grab current value, if any, from bits.
265  uint64_t CurVal = 0;
266
267  bool microMipsLEByteOrder = needsMMLEByteOrder((unsigned) Kind);
268
269  for (unsigned i = 0; i != NumBytes; ++i) {
270    unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i)
271                                                    : i)
272                            : (FullSize - 1 - i);
273    CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8);
274  }
275
276  uint64_t Mask = ((uint64_t)(-1) >>
277                    (64 - getFixupKindInfo(Kind).TargetSize));
278  CurVal |= Value & Mask;
279
280  // Write out the fixed up bytes back to the code/data bits.
281  for (unsigned i = 0; i != NumBytes; ++i) {
282    unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i)
283                                                    : i)
284                            : (FullSize - 1 - i);
285    Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff);
286  }
287}
288
289Optional<MCFixupKind> MipsAsmBackend::getFixupKind(StringRef Name) const {
290  return StringSwitch<Optional<MCFixupKind>>(Name)
291      .Case("R_MIPS_NONE", (MCFixupKind)Mips::fixup_Mips_NONE)
292      .Case("R_MIPS_32", FK_Data_4)
293      .Default(MCAsmBackend::getFixupKind(Name));
294}
295
296const MCFixupKindInfo &MipsAsmBackend::
297getFixupKindInfo(MCFixupKind Kind) const {
298  const static MCFixupKindInfo LittleEndianInfos[Mips::NumTargetFixupKinds] = {
299    // This table *must* be in same the order of fixup_* kinds in
300    // MipsFixupKinds.h.
301    //
302    // name                    offset  bits  flags
303    { "fixup_Mips_NONE",         0,      0,   0 },
304    { "fixup_Mips_16",           0,     16,   0 },
305    { "fixup_Mips_32",           0,     32,   0 },
306    { "fixup_Mips_REL32",        0,     32,   0 },
307    { "fixup_Mips_26",           0,     26,   0 },
308    { "fixup_Mips_HI16",         0,     16,   0 },
309    { "fixup_Mips_LO16",         0,     16,   0 },
310    { "fixup_Mips_GPREL16",      0,     16,   0 },
311    { "fixup_Mips_LITERAL",      0,     16,   0 },
312    { "fixup_Mips_GOT",          0,     16,   0 },
313    { "fixup_Mips_PC16",         0,     16,  MCFixupKindInfo::FKF_IsPCRel },
314    { "fixup_Mips_CALL16",       0,     16,   0 },
315    { "fixup_Mips_GPREL32",      0,     32,   0 },
316    { "fixup_Mips_SHIFT5",       6,      5,   0 },
317    { "fixup_Mips_SHIFT6",       6,      5,   0 },
318    { "fixup_Mips_64",           0,     64,   0 },
319    { "fixup_Mips_TLSGD",        0,     16,   0 },
320    { "fixup_Mips_GOTTPREL",     0,     16,   0 },
321    { "fixup_Mips_TPREL_HI",     0,     16,   0 },
322    { "fixup_Mips_TPREL_LO",     0,     16,   0 },
323    { "fixup_Mips_TLSLDM",       0,     16,   0 },
324    { "fixup_Mips_DTPREL_HI",    0,     16,   0 },
325    { "fixup_Mips_DTPREL_LO",    0,     16,   0 },
326    { "fixup_Mips_Branch_PCRel", 0,     16,  MCFixupKindInfo::FKF_IsPCRel },
327    { "fixup_Mips_GPOFF_HI",     0,     16,   0 },
328    { "fixup_Mips_GPOFF_LO",     0,     16,   0 },
329    { "fixup_Mips_GOT_PAGE",     0,     16,   0 },
330    { "fixup_Mips_GOT_OFST",     0,     16,   0 },
331    { "fixup_Mips_GOT_DISP",     0,     16,   0 },
332    { "fixup_Mips_HIGHER",       0,     16,   0 },
333    { "fixup_Mips_HIGHEST",      0,     16,   0 },
334    { "fixup_Mips_GOT_HI16",     0,     16,   0 },
335    { "fixup_Mips_GOT_LO16",     0,     16,   0 },
336    { "fixup_Mips_CALL_HI16",    0,     16,   0 },
337    { "fixup_Mips_CALL_LO16",    0,     16,   0 },
338    { "fixup_Mips_PC18_S3",      0,     18,  MCFixupKindInfo::FKF_IsPCRel },
339    { "fixup_MIPS_PC19_S2",      0,     19,  MCFixupKindInfo::FKF_IsPCRel },
340    { "fixup_MIPS_PC21_S2",      0,     21,  MCFixupKindInfo::FKF_IsPCRel },
341    { "fixup_MIPS_PC26_S2",      0,     26,  MCFixupKindInfo::FKF_IsPCRel },
342    { "fixup_MIPS_PCHI16",       0,     16,  MCFixupKindInfo::FKF_IsPCRel },
343    { "fixup_MIPS_PCLO16",       0,     16,  MCFixupKindInfo::FKF_IsPCRel },
344    { "fixup_MICROMIPS_26_S1",   0,     26,   0 },
345    { "fixup_MICROMIPS_HI16",    0,     16,   0 },
346    { "fixup_MICROMIPS_LO16",    0,     16,   0 },
347    { "fixup_MICROMIPS_GOT16",   0,     16,   0 },
348    { "fixup_MICROMIPS_PC7_S1",  0,      7,   MCFixupKindInfo::FKF_IsPCRel },
349    { "fixup_MICROMIPS_PC10_S1", 0,     10,   MCFixupKindInfo::FKF_IsPCRel },
350    { "fixup_MICROMIPS_PC16_S1", 0,     16,   MCFixupKindInfo::FKF_IsPCRel },
351    { "fixup_MICROMIPS_PC26_S1", 0,     26,   MCFixupKindInfo::FKF_IsPCRel },
352    { "fixup_MICROMIPS_PC19_S2", 0,     19,   MCFixupKindInfo::FKF_IsPCRel },
353    { "fixup_MICROMIPS_PC18_S3", 0,     18,   MCFixupKindInfo::FKF_IsPCRel },
354    { "fixup_MICROMIPS_PC21_S1", 0,     21,   MCFixupKindInfo::FKF_IsPCRel },
355    { "fixup_MICROMIPS_CALL16",  0,     16,   0 },
356    { "fixup_MICROMIPS_GOT_DISP",        0,     16,   0 },
357    { "fixup_MICROMIPS_GOT_PAGE",        0,     16,   0 },
358    { "fixup_MICROMIPS_GOT_OFST",        0,     16,   0 },
359    { "fixup_MICROMIPS_TLS_GD",          0,     16,   0 },
360    { "fixup_MICROMIPS_TLS_LDM",         0,     16,   0 },
361    { "fixup_MICROMIPS_TLS_DTPREL_HI16", 0,     16,   0 },
362    { "fixup_MICROMIPS_TLS_DTPREL_LO16", 0,     16,   0 },
363    { "fixup_MICROMIPS_TLS_TPREL_HI16",  0,     16,   0 },
364    { "fixup_MICROMIPS_TLS_TPREL_LO16",  0,     16,   0 }
365  };
366
367  const static MCFixupKindInfo BigEndianInfos[Mips::NumTargetFixupKinds] = {
368    // This table *must* be in same the order of fixup_* kinds in
369    // MipsFixupKinds.h.
370    //
371    // name                    offset  bits  flags
372    { "fixup_Mips_NONE",         0,      0,   0 },
373    { "fixup_Mips_16",          16,     16,   0 },
374    { "fixup_Mips_32",           0,     32,   0 },
375    { "fixup_Mips_REL32",        0,     32,   0 },
376    { "fixup_Mips_26",           6,     26,   0 },
377    { "fixup_Mips_HI16",        16,     16,   0 },
378    { "fixup_Mips_LO16",        16,     16,   0 },
379    { "fixup_Mips_GPREL16",     16,     16,   0 },
380    { "fixup_Mips_LITERAL",     16,     16,   0 },
381    { "fixup_Mips_GOT",         16,     16,   0 },
382    { "fixup_Mips_PC16",        16,     16,  MCFixupKindInfo::FKF_IsPCRel },
383    { "fixup_Mips_CALL16",      16,     16,   0 },
384    { "fixup_Mips_GPREL32",      0,     32,   0 },
385    { "fixup_Mips_SHIFT5",      21,      5,   0 },
386    { "fixup_Mips_SHIFT6",      21,      5,   0 },
387    { "fixup_Mips_64",           0,     64,   0 },
388    { "fixup_Mips_TLSGD",       16,     16,   0 },
389    { "fixup_Mips_GOTTPREL",    16,     16,   0 },
390    { "fixup_Mips_TPREL_HI",    16,     16,   0 },
391    { "fixup_Mips_TPREL_LO",    16,     16,   0 },
392    { "fixup_Mips_TLSLDM",      16,     16,   0 },
393    { "fixup_Mips_DTPREL_HI",   16,     16,   0 },
394    { "fixup_Mips_DTPREL_LO",   16,     16,   0 },
395    { "fixup_Mips_Branch_PCRel",16,     16,  MCFixupKindInfo::FKF_IsPCRel },
396    { "fixup_Mips_GPOFF_HI",    16,     16,   0 },
397    { "fixup_Mips_GPOFF_LO",    16,     16,   0 },
398    { "fixup_Mips_GOT_PAGE",    16,     16,   0 },
399    { "fixup_Mips_GOT_OFST",    16,     16,   0 },
400    { "fixup_Mips_GOT_DISP",    16,     16,   0 },
401    { "fixup_Mips_HIGHER",      16,     16,   0 },
402    { "fixup_Mips_HIGHEST",     16,     16,   0 },
403    { "fixup_Mips_GOT_HI16",    16,     16,   0 },
404    { "fixup_Mips_GOT_LO16",    16,     16,   0 },
405    { "fixup_Mips_CALL_HI16",   16,     16,   0 },
406    { "fixup_Mips_CALL_LO16",   16,     16,   0 },
407    { "fixup_Mips_PC18_S3",     14,     18,  MCFixupKindInfo::FKF_IsPCRel },
408    { "fixup_MIPS_PC19_S2",     13,     19,  MCFixupKindInfo::FKF_IsPCRel },
409    { "fixup_MIPS_PC21_S2",     11,     21,  MCFixupKindInfo::FKF_IsPCRel },
410    { "fixup_MIPS_PC26_S2",      6,     26,  MCFixupKindInfo::FKF_IsPCRel },
411    { "fixup_MIPS_PCHI16",      16,     16,  MCFixupKindInfo::FKF_IsPCRel },
412    { "fixup_MIPS_PCLO16",      16,     16,  MCFixupKindInfo::FKF_IsPCRel },
413    { "fixup_MICROMIPS_26_S1",   6,     26,   0 },
414    { "fixup_MICROMIPS_HI16",   16,     16,   0 },
415    { "fixup_MICROMIPS_LO16",   16,     16,   0 },
416    { "fixup_MICROMIPS_GOT16",  16,     16,   0 },
417    { "fixup_MICROMIPS_PC7_S1",  9,      7,   MCFixupKindInfo::FKF_IsPCRel },
418    { "fixup_MICROMIPS_PC10_S1", 6,     10,   MCFixupKindInfo::FKF_IsPCRel },
419    { "fixup_MICROMIPS_PC16_S1",16,     16,   MCFixupKindInfo::FKF_IsPCRel },
420    { "fixup_MICROMIPS_PC26_S1", 6,     26,   MCFixupKindInfo::FKF_IsPCRel },
421    { "fixup_MICROMIPS_PC19_S2",13,     19,   MCFixupKindInfo::FKF_IsPCRel },
422    { "fixup_MICROMIPS_PC18_S3",14,     18,   MCFixupKindInfo::FKF_IsPCRel },
423    { "fixup_MICROMIPS_PC21_S1",11,     21,   MCFixupKindInfo::FKF_IsPCRel },
424    { "fixup_MICROMIPS_CALL16", 16,     16,   0 },
425    { "fixup_MICROMIPS_GOT_DISP",        16,     16,   0 },
426    { "fixup_MICROMIPS_GOT_PAGE",        16,     16,   0 },
427    { "fixup_MICROMIPS_GOT_OFST",        16,     16,   0 },
428    { "fixup_MICROMIPS_TLS_GD",          16,     16,   0 },
429    { "fixup_MICROMIPS_TLS_LDM",         16,     16,   0 },
430    { "fixup_MICROMIPS_TLS_DTPREL_HI16", 16,     16,   0 },
431    { "fixup_MICROMIPS_TLS_DTPREL_LO16", 16,     16,   0 },
432    { "fixup_MICROMIPS_TLS_TPREL_HI16",  16,     16,   0 },
433    { "fixup_MICROMIPS_TLS_TPREL_LO16",  16,     16,   0 }
434  };
435
436  if (Kind < FirstTargetFixupKind)
437    return MCAsmBackend::getFixupKindInfo(Kind);
438
439  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
440          "Invalid kind!");
441
442  if (IsLittle)
443    return LittleEndianInfos[Kind - FirstTargetFixupKind];
444  return BigEndianInfos[Kind - FirstTargetFixupKind];
445}
446
447/// WriteNopData - Write an (optimal) nop sequence of Count bytes
448/// to the given output. If the target cannot generate such a sequence,
449/// it should return an error.
450///
451/// \return - True on success.
452bool MipsAsmBackend::writeNopData(uint64_t Count, MCObjectWriter *OW) const {
453  // Check for a less than instruction size number of bytes
454  // FIXME: 16 bit instructions are not handled yet here.
455  // We shouldn't be using a hard coded number for instruction size.
456
457  // If the count is not 4-byte aligned, we must be writing data into the text
458  // section (otherwise we have unaligned instructions, and thus have far
459  // bigger problems), so just write zeros instead.
460  OW->WriteZeros(Count);
461  return true;
462}
463
464/// processFixupValue - Target hook to process the literal value of a fixup
465/// if necessary.
466void MipsAsmBackend::processFixupValue(const MCAssembler &Asm,
467                                       const MCAsmLayout &Layout,
468                                       const MCFixup &Fixup,
469                                       const MCFragment *DF,
470                                       const MCValue &Target,
471                                       uint64_t &Value,
472                                       bool &IsResolved) {
473  // At this point we'll ignore the value returned by adjustFixupValue as
474  // we are only checking if the fixup can be applied correctly. We have
475  // access to MCContext from here which allows us to report a fatal error
476  // with *possibly* a source code location.
477  // The caller will also ignore any changes we make to Value
478  // (recordRelocation() overwrites it with it's own calculation).
479  (void)adjustFixupValue(Fixup, Value, &Asm.getContext());
480}
481
482// MCAsmBackend
483MCAsmBackend *llvm::createMipsAsmBackendEL32(const Target &T,
484                                             const MCRegisterInfo &MRI,
485                                             const Triple &TT, StringRef CPU) {
486  return new MipsAsmBackend(T, TT.getOS(), /*IsLittle*/ true,
487                            /*Is64Bit*/ false);
488}
489
490MCAsmBackend *llvm::createMipsAsmBackendEB32(const Target &T,
491                                             const MCRegisterInfo &MRI,
492                                             const Triple &TT, StringRef CPU) {
493  return new MipsAsmBackend(T, TT.getOS(), /*IsLittle*/ false,
494                            /*Is64Bit*/ false);
495}
496
497MCAsmBackend *llvm::createMipsAsmBackendEL64(const Target &T,
498                                             const MCRegisterInfo &MRI,
499                                             const Triple &TT, StringRef CPU) {
500  return new MipsAsmBackend(T, TT.getOS(), /*IsLittle*/ true, /*Is64Bit*/ true);
501}
502
503MCAsmBackend *llvm::createMipsAsmBackendEB64(const Target &T,
504                                             const MCRegisterInfo &MRI,
505                                             const Triple &TT, StringRef CPU) {
506  return new MipsAsmBackend(T, TT.getOS(), /*IsLittle*/ false,
507                            /*Is64Bit*/ true);
508}
509