Coverage Report

Created: 2026-07-25 06:13

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
27.3k
                                 MCContext *Ctx = nullptr) {
35
36
27.3k
  unsigned Kind = Fixup.getKind();
37
38
  // Add/subtract and shift
39
27.3k
  switch (Kind) {
40
318
  default:
41
318
    return 0;
42
98
  case FK_Data_2:
43
110
  case FK_GPRel_4:
44
21.1k
  case FK_Data_4:
45
21.3k
  case FK_Data_8:
46
22.0k
  case Mips::fixup_Mips_LO16:
47
22.0k
  case Mips::fixup_Mips_GPREL16:
48
22.0k
  case Mips::fixup_Mips_GPOFF_HI:
49
22.0k
  case Mips::fixup_Mips_GPOFF_LO:
50
22.0k
  case Mips::fixup_Mips_GOT_PAGE:
51
22.0k
  case Mips::fixup_Mips_GOT_OFST:
52
22.0k
  case Mips::fixup_Mips_GOT_DISP:
53
22.0k
  case Mips::fixup_Mips_GOT_LO16:
54
22.0k
  case Mips::fixup_Mips_CALL_LO16:
55
22.0k
  case Mips::fixup_MICROMIPS_LO16:
56
22.0k
  case Mips::fixup_MICROMIPS_GOT_PAGE:
57
22.0k
  case Mips::fixup_MICROMIPS_GOT_OFST:
58
22.0k
  case Mips::fixup_MICROMIPS_GOT_DISP:
59
22.0k
  case Mips::fixup_MIPS_PCLO16:
60
22.0k
    break;
61
2.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
2.71k
    Value = (int64_t)Value / 4;
65
    // We now check if Value can be encoded as a 16-bit signed immediate.
66
2.71k
    if (!isInt<16>(Value) && Ctx) {
67
123
      Ctx->reportError(Fixup.getLoc(), "out of range PC16 fixup");
68
123
      return 0;
69
123
    }
70
2.59k
    break;
71
2.59k
  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.39k
  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.39k
    Value >>= 2;
85
1.39k
    break;
86
898
  case Mips::fixup_Mips_HI16:
87
898
  case Mips::fixup_Mips_GOT_Local:
88
898
  case Mips::fixup_Mips_GOT_HI16:
89
898
  case Mips::fixup_Mips_CALL_HI16:
90
898
  case Mips::fixup_MICROMIPS_HI16:
91
898
  case Mips::fixup_MIPS_PCHI16:
92
    // Get the 2nd 16-bits. Also add 1 if bit 15 is 1.
93
898
    Value = ((Value + 0x8000) >> 16) & 0xffff;
94
898
    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
6
  case Mips::fixup_MIPS_PC26_S2:
155
    // Forcing a signed division because Value can be negative.
156
6
    Value = (int64_t) Value / 4;
157
    // We now check if Value can be encoded as a 26-bit signed immediate.
158
6
    if (!isInt<26>(Value) && Ctx) {
159
1
      Ctx->reportError(Fixup.getLoc(), "out of range PC26 fixup");
160
1
      return 0;
161
1
    }
162
5
    break;
163
27.3k
  }
164
165
26.8k
  return Value;
166
27.3k
}
167
168
MCObjectWriter *
169
6.57k
MipsAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
170
6.57k
  return createMipsELFObjectWriter(OS,
171
6.57k
    MCELFObjectTargetWriter::getOSABI(OSType), IsLittle, Is64Bit);
172
6.57k
}
173
174
// Little-endian fixup data byte ordering:
175
//   mips32r2:   a | b | x | x
176
//   microMIPS:  x | x | a | b
177
178
12.1k
static bool needsMMLEByteOrder(unsigned Kind) {
179
12.1k
  return Kind != Mips::fixup_MICROMIPS_PC10_S1 &&
180
12.1k
         Kind >= Mips::fixup_MICROMIPS_26_S1 &&
181
0
         Kind < Mips::LastTargetFixupKind;
182
12.1k
}
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
13.6k
                                bool IsPCRel, unsigned int &KsError) const {
197
13.6k
  MCFixupKind Kind = Fixup.getKind();
198
13.6k
  Value = adjustFixupValue(Fixup, Value);
199
200
13.6k
  if (!Value)
201
1.52k
    return; // Doesn't change encoding.
202
203
  // Where do we start in the object
204
12.1k
  unsigned Offset = Fixup.getOffset();
205
  // Number of bytes we need to fixup
206
12.1k
  unsigned NumBytes = (getFixupKindInfo(Kind).TargetSize + 7) / 8;
207
  // Used to point to big endian bytes
208
12.1k
  unsigned FullSize;
209
210
12.1k
  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
77
  case FK_Data_8:
217
77
  case Mips::fixup_Mips_64:
218
77
    FullSize = 8;
219
77
    break;
220
10.0k
  case FK_Data_4:
221
12.0k
  default:
222
12.0k
    FullSize = 4;
223
12.0k
    break;
224
12.1k
  }
225
226
  // Grab current value, if any, from bits.
227
12.1k
  uint64_t CurVal = 0;
228
229
12.1k
  bool microMipsLEByteOrder = needsMMLEByteOrder((unsigned) Kind);
230
231
58.2k
  for (unsigned i = 0; i != NumBytes; ++i) {
232
46.1k
    unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i)
233
46.0k
                                                    : i)
234
46.1k
                            : (FullSize - 1 - i);
235
46.1k
    CurVal |= (uint64_t)((uint8_t)Data[Offset + Idx]) << (i*8);
236
46.1k
  }
237
238
12.1k
  uint64_t Mask = ((uint64_t)(-1) >>
239
12.1k
                    (64 - getFixupKindInfo(Kind).TargetSize));
240
12.1k
  CurVal |= Value & Mask;
241
242
  // Write out the fixed up bytes back to the code/data bits.
243
58.2k
  for (unsigned i = 0; i != NumBytes; ++i) {
244
46.1k
    unsigned Idx = IsLittle ? (microMipsLEByteOrder ? calculateMMLEIndex(i)
245
46.0k
                                                    : i)
246
46.1k
                            : (FullSize - 1 - i);
247
46.1k
    Data[Offset + Idx] = (uint8_t)((CurVal >> (i*8)) & 0xff);
248
46.1k
  }
249
12.1k
}
250
251
236
Optional<MCFixupKind> MipsAsmBackend::getFixupKind(StringRef Name) const {
252
236
  return StringSwitch<Optional<MCFixupKind>>(Name)
253
236
      .Case("R_MIPS_NONE", (MCFixupKind)Mips::fixup_Mips_NONE)
254
236
      .Case("R_MIPS_32", FK_Data_4)
255
236
      .Default(MCAsmBackend::getFixupKind(Name));
256
236
}
257
258
const MCFixupKindInfo &MipsAsmBackend::
259
66.0k
getFixupKindInfo(MCFixupKind Kind) const {
260
66.0k
  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
66.0k
    { "fixup_Mips_NONE",         0,      0,   0 },
266
66.0k
    { "fixup_Mips_16",           0,     16,   0 },
267
66.0k
    { "fixup_Mips_32",           0,     32,   0 },
268
66.0k
    { "fixup_Mips_REL32",        0,     32,   0 },
269
66.0k
    { "fixup_Mips_26",           0,     26,   0 },
270
66.0k
    { "fixup_Mips_HI16",         0,     16,   0 },
271
66.0k
    { "fixup_Mips_LO16",         0,     16,   0 },
272
66.0k
    { "fixup_Mips_GPREL16",      0,     16,   0 },
273
66.0k
    { "fixup_Mips_LITERAL",      0,     16,   0 },
274
66.0k
    { "fixup_Mips_GOT_Global",   0,     16,   0 },
275
66.0k
    { "fixup_Mips_GOT_Local",    0,     16,   0 },
276
66.0k
    { "fixup_Mips_PC16",         0,     16,  MCFixupKindInfo::FKF_IsPCRel },
277
66.0k
    { "fixup_Mips_CALL16",       0,     16,   0 },
278
66.0k
    { "fixup_Mips_GPREL32",      0,     32,   0 },
279
66.0k
    { "fixup_Mips_SHIFT5",       6,      5,   0 },
280
66.0k
    { "fixup_Mips_SHIFT6",       6,      5,   0 },
281
66.0k
    { "fixup_Mips_64",           0,     64,   0 },
282
66.0k
    { "fixup_Mips_TLSGD",        0,     16,   0 },
283
66.0k
    { "fixup_Mips_GOTTPREL",     0,     16,   0 },
284
66.0k
    { "fixup_Mips_TPREL_HI",     0,     16,   0 },
285
66.0k
    { "fixup_Mips_TPREL_LO",     0,     16,   0 },
286
66.0k
    { "fixup_Mips_TLSLDM",       0,     16,   0 },
287
66.0k
    { "fixup_Mips_DTPREL_HI",    0,     16,   0 },
288
66.0k
    { "fixup_Mips_DTPREL_LO",    0,     16,   0 },
289
66.0k
    { "fixup_Mips_Branch_PCRel", 0,     16,  MCFixupKindInfo::FKF_IsPCRel },
290
66.0k
    { "fixup_Mips_GPOFF_HI",     0,     16,   0 },
291
66.0k
    { "fixup_Mips_GPOFF_LO",     0,     16,   0 },
292
66.0k
    { "fixup_Mips_GOT_PAGE",     0,     16,   0 },
293
66.0k
    { "fixup_Mips_GOT_OFST",     0,     16,   0 },
294
66.0k
    { "fixup_Mips_GOT_DISP",     0,     16,   0 },
295
66.0k
    { "fixup_Mips_HIGHER",       0,     16,   0 },
296
66.0k
    { "fixup_Mips_HIGHEST",      0,     16,   0 },
297
66.0k
    { "fixup_Mips_GOT_HI16",     0,     16,   0 },
298
66.0k
    { "fixup_Mips_GOT_LO16",     0,     16,   0 },
299
66.0k
    { "fixup_Mips_CALL_HI16",    0,     16,   0 },
300
66.0k
    { "fixup_Mips_CALL_LO16",    0,     16,   0 },
301
66.0k
    { "fixup_Mips_PC18_S3",      0,     18,  MCFixupKindInfo::FKF_IsPCRel },
302
66.0k
    { "fixup_MIPS_PC19_S2",      0,     19,  MCFixupKindInfo::FKF_IsPCRel },
303
66.0k
    { "fixup_MIPS_PC21_S2",      0,     21,  MCFixupKindInfo::FKF_IsPCRel },
304
66.0k
    { "fixup_MIPS_PC26_S2",      0,     26,  MCFixupKindInfo::FKF_IsPCRel },
305
66.0k
    { "fixup_MIPS_PCHI16",       0,     16,  MCFixupKindInfo::FKF_IsPCRel },
306
66.0k
    { "fixup_MIPS_PCLO16",       0,     16,  MCFixupKindInfo::FKF_IsPCRel },
307
66.0k
    { "fixup_MICROMIPS_26_S1",   0,     26,   0 },
308
66.0k
    { "fixup_MICROMIPS_HI16",    0,     16,   0 },
309
66.0k
    { "fixup_MICROMIPS_LO16",    0,     16,   0 },
310
66.0k
    { "fixup_MICROMIPS_GOT16",   0,     16,   0 },
311
66.0k
    { "fixup_MICROMIPS_PC7_S1",  0,      7,   MCFixupKindInfo::FKF_IsPCRel },
312
66.0k
    { "fixup_MICROMIPS_PC10_S1", 0,     10,   MCFixupKindInfo::FKF_IsPCRel },
313
66.0k
    { "fixup_MICROMIPS_PC16_S1", 0,     16,   MCFixupKindInfo::FKF_IsPCRel },
314
66.0k
    { "fixup_MICROMIPS_CALL16",  0,     16,   0 },
315
66.0k
    { "fixup_MICROMIPS_GOT_DISP",        0,     16,   0 },
316
66.0k
    { "fixup_MICROMIPS_GOT_PAGE",        0,     16,   0 },
317
66.0k
    { "fixup_MICROMIPS_GOT_OFST",        0,     16,   0 },
318
66.0k
    { "fixup_MICROMIPS_TLS_GD",          0,     16,   0 },
319
66.0k
    { "fixup_MICROMIPS_TLS_LDM",         0,     16,   0 },
320
66.0k
    { "fixup_MICROMIPS_TLS_DTPREL_HI16", 0,     16,   0 },
321
66.0k
    { "fixup_MICROMIPS_TLS_DTPREL_LO16", 0,     16,   0 },
322
66.0k
    { "fixup_MICROMIPS_TLS_TPREL_HI16",  0,     16,   0 },
323
66.0k
    { "fixup_MICROMIPS_TLS_TPREL_LO16",  0,     16,   0 }
324
66.0k
  };
325
326
66.0k
  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
66.0k
    { "fixup_Mips_NONE",         0,      0,   0 },
332
66.0k
    { "fixup_Mips_16",          16,     16,   0 },
333
66.0k
    { "fixup_Mips_32",           0,     32,   0 },
334
66.0k
    { "fixup_Mips_REL32",        0,     32,   0 },
335
66.0k
    { "fixup_Mips_26",           6,     26,   0 },
336
66.0k
    { "fixup_Mips_HI16",        16,     16,   0 },
337
66.0k
    { "fixup_Mips_LO16",        16,     16,   0 },
338
66.0k
    { "fixup_Mips_GPREL16",     16,     16,   0 },
339
66.0k
    { "fixup_Mips_LITERAL",     16,     16,   0 },
340
66.0k
    { "fixup_Mips_GOT_Global",  16,     16,   0 },
341
66.0k
    { "fixup_Mips_GOT_Local",   16,     16,   0 },
342
66.0k
    { "fixup_Mips_PC16",        16,     16,  MCFixupKindInfo::FKF_IsPCRel },
343
66.0k
    { "fixup_Mips_CALL16",      16,     16,   0 },
344
66.0k
    { "fixup_Mips_GPREL32",      0,     32,   0 },
345
66.0k
    { "fixup_Mips_SHIFT5",      21,      5,   0 },
346
66.0k
    { "fixup_Mips_SHIFT6",      21,      5,   0 },
347
66.0k
    { "fixup_Mips_64",           0,     64,   0 },
348
66.0k
    { "fixup_Mips_TLSGD",       16,     16,   0 },
349
66.0k
    { "fixup_Mips_GOTTPREL",    16,     16,   0 },
350
66.0k
    { "fixup_Mips_TPREL_HI",    16,     16,   0 },
351
66.0k
    { "fixup_Mips_TPREL_LO",    16,     16,   0 },
352
66.0k
    { "fixup_Mips_TLSLDM",      16,     16,   0 },
353
66.0k
    { "fixup_Mips_DTPREL_HI",   16,     16,   0 },
354
66.0k
    { "fixup_Mips_DTPREL_LO",   16,     16,   0 },
355
66.0k
    { "fixup_Mips_Branch_PCRel",16,     16,  MCFixupKindInfo::FKF_IsPCRel },
356
66.0k
    { "fixup_Mips_GPOFF_HI",    16,     16,   0 },
357
66.0k
    { "fixup_Mips_GPOFF_LO",    16,     16,   0 },
358
66.0k
    { "fixup_Mips_GOT_PAGE",    16,     16,   0 },
359
66.0k
    { "fixup_Mips_GOT_OFST",    16,     16,   0 },
360
66.0k
    { "fixup_Mips_GOT_DISP",    16,     16,   0 },
361
66.0k
    { "fixup_Mips_HIGHER",      16,     16,   0 },
362
66.0k
    { "fixup_Mips_HIGHEST",     16,     16,   0 },
363
66.0k
    { "fixup_Mips_GOT_HI16",    16,     16,   0 },
364
66.0k
    { "fixup_Mips_GOT_LO16",    16,     16,   0 },
365
66.0k
    { "fixup_Mips_CALL_HI16",   16,     16,   0 },
366
66.0k
    { "fixup_Mips_CALL_LO16",   16,     16,   0 },
367
66.0k
    { "fixup_Mips_PC18_S3",     14,     18,  MCFixupKindInfo::FKF_IsPCRel },
368
66.0k
    { "fixup_MIPS_PC19_S2",     13,     19,  MCFixupKindInfo::FKF_IsPCRel },
369
66.0k
    { "fixup_MIPS_PC21_S2",     11,     21,  MCFixupKindInfo::FKF_IsPCRel },
370
66.0k
    { "fixup_MIPS_PC26_S2",      6,     26,  MCFixupKindInfo::FKF_IsPCRel },
371
66.0k
    { "fixup_MIPS_PCHI16",      16,     16,  MCFixupKindInfo::FKF_IsPCRel },
372
66.0k
    { "fixup_MIPS_PCLO16",      16,     16,  MCFixupKindInfo::FKF_IsPCRel },
373
66.0k
    { "fixup_MICROMIPS_26_S1",   6,     26,   0 },
374
66.0k
    { "fixup_MICROMIPS_HI16",   16,     16,   0 },
375
66.0k
    { "fixup_MICROMIPS_LO16",   16,     16,   0 },
376
66.0k
    { "fixup_MICROMIPS_GOT16",  16,     16,   0 },
377
66.0k
    { "fixup_MICROMIPS_PC7_S1",  9,      7,   MCFixupKindInfo::FKF_IsPCRel },
378
66.0k
    { "fixup_MICROMIPS_PC10_S1", 6,     10,   MCFixupKindInfo::FKF_IsPCRel },
379
66.0k
    { "fixup_MICROMIPS_PC16_S1",16,     16,   MCFixupKindInfo::FKF_IsPCRel },
380
66.0k
    { "fixup_MICROMIPS_CALL16", 16,     16,   0 },
381
66.0k
    { "fixup_MICROMIPS_GOT_DISP",        16,     16,   0 },
382
66.0k
    { "fixup_MICROMIPS_GOT_PAGE",        16,     16,   0 },
383
66.0k
    { "fixup_MICROMIPS_GOT_OFST",        16,     16,   0 },
384
66.0k
    { "fixup_MICROMIPS_TLS_GD",          16,     16,   0 },
385
66.0k
    { "fixup_MICROMIPS_TLS_LDM",         16,     16,   0 },
386
66.0k
    { "fixup_MICROMIPS_TLS_DTPREL_HI16", 16,     16,   0 },
387
66.0k
    { "fixup_MICROMIPS_TLS_DTPREL_LO16", 16,     16,   0 },
388
66.0k
    { "fixup_MICROMIPS_TLS_TPREL_HI16",  16,     16,   0 },
389
66.0k
    { "fixup_MICROMIPS_TLS_TPREL_LO16",  16,     16,   0 }
390
66.0k
  };
391
392
66.0k
  if (Kind < FirstTargetFixupKind)
393
52.5k
    return MCAsmBackend::getFixupKindInfo(Kind);
394
395
66.0k
  assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
396
13.5k
          "Invalid kind!");
397
398
13.5k
  if (IsLittle)
399
13.3k
    return LittleEndianInfos[Kind - FirstTargetFixupKind];
400
205
  return BigEndianInfos[Kind - FirstTargetFixupKind];
401
13.5k
}
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
3.45k
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
3.45k
  OW->WriteZeros(Count);
417
3.45k
  return true;
418
3.45k
}
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
13.6k
                                       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
13.6k
  (void)adjustFixupValue(Fixup, Value, &Asm.getContext());
434
13.6k
}
435
436
// MCAsmBackend
437
MCAsmBackend *llvm_ks::createMipsAsmBackendEL32(const Target &T,
438
                                             const MCRegisterInfo &MRI,
439
351
                                             const Triple &TT, StringRef CPU) {
440
351
  return new MipsAsmBackend(T, TT.getOS(), /*IsLittle*/ true,
441
351
                            /*Is64Bit*/ false);
442
351
}
443
444
MCAsmBackend *llvm_ks::createMipsAsmBackendEB32(const Target &T,
445
                                             const MCRegisterInfo &MRI,
446
759
                                             const Triple &TT, StringRef CPU) {
447
759
  return new MipsAsmBackend(T, TT.getOS(), /*IsLittle*/ false,
448
759
                            /*Is64Bit*/ false);
449
759
}
450
451
MCAsmBackend *llvm_ks::createMipsAsmBackendEL64(const Target &T,
452
                                             const MCRegisterInfo &MRI,
453
5.32k
                                             const Triple &TT, StringRef CPU) {
454
5.32k
  return new MipsAsmBackend(T, TT.getOS(), /*IsLittle*/ true, /*Is64Bit*/ true);
455
5.32k
}
456
457
MCAsmBackend *llvm_ks::createMipsAsmBackendEB64(const Target &T,
458
                                             const MCRegisterInfo &MRI,
459
140
                                             const Triple &TT, StringRef CPU) {
460
140
  return new MipsAsmBackend(T, TT.getOS(), /*IsLittle*/ false,
461
140
                            /*Is64Bit*/ true);
462
140
}