Coverage Report

Created: 2026-06-14 07:58

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