Coverage Report

Created: 2026-04-01 07:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/keystone/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
Line
Count
Source
1
//===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===//
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 MipsMCCodeEmitter class.
11
//
12
//===----------------------------------------------------------------------===//
13
//
14
15
#include "MipsMCCodeEmitter.h"
16
#include "MCTargetDesc/MipsFixupKinds.h"
17
#include "MCTargetDesc/MipsMCExpr.h"
18
#include "MCTargetDesc/MipsMCTargetDesc.h"
19
#include "llvm/ADT/APFloat.h"
20
#include "llvm/ADT/SmallVector.h"
21
#include "llvm/MC/MCContext.h"
22
#include "llvm/MC/MCExpr.h"
23
#include "llvm/MC/MCFixup.h"
24
#include "llvm/MC/MCInst.h"
25
#include "llvm/MC/MCInstrInfo.h"
26
#include "llvm/MC/MCRegisterInfo.h"
27
#include "llvm/MC/MCSubtargetInfo.h"
28
#include "llvm/Support/raw_ostream.h"
29
30
#define DEBUG_TYPE "mccodeemitter"
31
32
#define GET_INSTRMAP_INFO
33
#include "MipsGenInstrInfo.inc"
34
#undef GET_INSTRMAP_INFO
35
36
namespace llvm_ks {
37
MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
38
                                         const MCRegisterInfo &MRI,
39
761
                                         MCContext &Ctx) {
40
761
  return new MipsMCCodeEmitter(MCII, Ctx, false);
41
761
}
42
43
MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
44
                                         const MCRegisterInfo &MRI,
45
5.01k
                                         MCContext &Ctx) {
46
5.01k
  return new MipsMCCodeEmitter(MCII, Ctx, true);
47
5.01k
}
48
} // End of namespace llvm_ks.
49
50
// If the D<shift> instruction has a shift amount that is greater
51
// than 31 (checked in calling routine), lower it to a D<shift>32 instruction
52
579
static void LowerLargeShift(MCInst& Inst) {
53
54
579
  assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
55
579
  assert(Inst.getOperand(2).isImm());
56
57
579
  int64_t Shift = Inst.getOperand(2).getImm();
58
579
  if (Shift <= 31)
59
491
    return; // Do nothing
60
88
  Shift -= 32;
61
62
  // saminus32
63
88
  Inst.getOperand(2).setImm(Shift);
64
65
88
  switch (Inst.getOpcode()) {
66
0
  default:
67
    // Calling function is not synchronized
68
0
    llvm_unreachable("Unexpected shift instruction");
69
88
  case Mips::DSLL:
70
88
    Inst.setOpcode(Mips::DSLL32);
71
88
    return;
72
0
  case Mips::DSRL:
73
0
    Inst.setOpcode(Mips::DSRL32);
74
0
    return;
75
0
  case Mips::DSRA:
76
0
    Inst.setOpcode(Mips::DSRA32);
77
0
    return;
78
0
  case Mips::DROTR:
79
0
    Inst.setOpcode(Mips::DROTR32);
80
0
    return;
81
88
  }
82
88
}
83
84
// Pick a DEXT or DINS instruction variant based on the pos and size operands
85
0
static void LowerDextDins(MCInst& InstIn) {
86
0
  int Opcode = InstIn.getOpcode();
87
88
0
  if (Opcode == Mips::DEXT)
89
0
    assert(InstIn.getNumOperands() == 4 &&
90
0
           "Invalid no. of machine operands for DEXT!");
91
0
  else // Only DEXT and DINS are possible
92
0
    assert(InstIn.getNumOperands() == 5 &&
93
0
           "Invalid no. of machine operands for DINS!");
94
95
0
  assert(InstIn.getOperand(2).isImm());
96
0
  int64_t pos = InstIn.getOperand(2).getImm();
97
0
  assert(InstIn.getOperand(3).isImm());
98
0
  int64_t size = InstIn.getOperand(3).getImm();
99
100
0
  if (size <= 32) {
101
0
    if (pos < 32)  // DEXT/DINS, do nothing
102
0
      return;
103
    // DEXTU/DINSU
104
0
    InstIn.getOperand(2).setImm(pos - 32);
105
0
    InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
106
0
    return;
107
0
  }
108
  // DEXTM/DINSM
109
0
  assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
110
0
  InstIn.getOperand(3).setImm(size - 32);
111
0
  InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
112
0
  return;
113
0
}
114
115
41.8k
bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const {
116
41.8k
  return STI.getFeatureBits()[Mips::FeatureMicroMips];
117
41.8k
}
118
119
0
bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const {
120
0
  return STI.getFeatureBits()[Mips::FeatureMips32r6];
121
0
}
122
123
95.9k
void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const {
124
95.9k
  OS << (char)C;
125
95.9k
}
126
127
void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size,
128
                                        const MCSubtargetInfo &STI,
129
23.9k
                                        raw_ostream &OS) const {
130
  // Output the instruction encoding in little endian byte order.
131
  // Little-endian byte ordering:
132
  //   mips32r2:   4 | 3 | 2 | 1
133
  //   microMIPS:  2 | 1 | 4 | 3
134
23.9k
  if (IsLittleEndian && Size == 4 && isMicroMips(STI)) {
135
0
    EmitInstruction(Val >> 16, 2, STI, OS);
136
0
    EmitInstruction(Val, 2, STI, OS);
137
23.9k
  } else {
138
119k
    for (unsigned i = 0; i < Size; ++i) {
139
95.9k
      unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
140
95.9k
      EmitByte((Val >> Shift) & 0xff, OS);
141
95.9k
    }
142
23.9k
  }
143
23.9k
}
144
145
/// encodeInstruction - Emit the instruction.
146
/// Size the instruction with Desc.getSize().
147
void MipsMCCodeEmitter::
148
encodeInstruction(MCInst &MI, raw_ostream &OS,
149
                  SmallVectorImpl<MCFixup> &Fixups,
150
                  const MCSubtargetInfo &STI,
151
                  unsigned int &KsError) const
152
23.9k
{
153
23.9k
  KsError = 0;
154
  // Non-pseudo instructions that get changed for direct object
155
  // only based on operand values.
156
  // If this list of instructions get much longer we will move
157
  // the check to a function call. Until then, this is more efficient.
158
23.9k
  MCInst TmpInst = MI;
159
23.9k
  switch (MI.getOpcode()) {
160
  // If shift amount is >= 32 it the inst needs to be lowered further
161
579
  case Mips::DSLL:
162
579
  case Mips::DSRL:
163
579
  case Mips::DSRA:
164
579
  case Mips::DROTR:
165
579
    LowerLargeShift(TmpInst);
166
579
    break;
167
    // Double extract instruction is chosen by pos and size operands
168
0
  case Mips::DEXT:
169
0
  case Mips::DINS:
170
0
    LowerDextDins(TmpInst);
171
23.9k
  }
172
173
23.9k
  unsigned long N = Fixups.size();
174
23.9k
  uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
175
176
  // Check for unimplemented opcodes.
177
  // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
178
  // so we have to special check for them.
179
23.9k
  unsigned Opcode = TmpInst.getOpcode();
180
23.9k
  if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) &&
181
14.3k
      (Opcode != Mips::SLL_MM) && !Binary)
182
0
    llvm_unreachable("unimplemented opcode in encodeInstruction()");
183
184
23.9k
  int NewOpcode = -1;
185
23.9k
  if (isMicroMips(STI)) {
186
0
    if (isMips32r6(STI)) {
187
0
      NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6);
188
0
      if (NewOpcode == -1)
189
0
        NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6);
190
0
    }
191
0
    else
192
0
      NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips);
193
194
    // Check whether it is Dsp instruction.
195
0
    if (NewOpcode == -1)
196
0
      NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp);
197
198
0
    if (NewOpcode != -1) {
199
0
      if (Fixups.size() > N)
200
0
        Fixups.pop_back();
201
202
0
      Opcode = NewOpcode;
203
0
      TmpInst.setOpcode (NewOpcode);
204
0
      Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
205
0
    }
206
0
  }
207
208
23.9k
  const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
209
210
  // Get byte count of instruction
211
23.9k
  unsigned Size = Desc.getSize();
212
23.9k
  if (!Size)
213
0
    llvm_unreachable("Desc.getSize() returns 0");
214
215
23.9k
  EmitInstruction(Binary, Size, STI, OS);
216
217
  // Keystone: update Inst.Address to point to the next instruction
218
23.9k
  MI.setAddress(MI.getAddress() + Size);
219
23.9k
}
220
221
/// getBranchTargetOpValue - Return binary encoding of the branch
222
/// target operand. If the machine operand requires relocation,
223
/// record the relocation and return zero.
224
unsigned MipsMCCodeEmitter::
225
getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
226
                       SmallVectorImpl<MCFixup> &Fixups,
227
6.35k
                       const MCSubtargetInfo &STI) const {
228
229
6.35k
  const MCOperand &MO = MI.getOperand(OpNo);
230
231
  // If the destination is an immediate, divide by 4.
232
6.35k
  if (MO.isImm()) return (MO.getImm() - MI.getAddress() - 4) >> 2;
233
234
6.35k
  assert(MO.isExpr() &&
235
6.25k
         "getBranchTargetOpValue expects only expressions or immediates");
236
237
6.25k
  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
238
6.25k
      MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
239
6.25k
  Fixups.push_back(MCFixup::create(0, FixupExpression,
240
6.25k
                                   MCFixupKind(Mips::fixup_Mips_PC16)));
241
6.25k
  return 0;
242
6.25k
}
243
244
/// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch
245
/// target operand. If the machine operand requires relocation,
246
/// record the relocation and return zero.
247
unsigned MipsMCCodeEmitter::
248
getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo,
249
                          SmallVectorImpl<MCFixup> &Fixups,
250
0
                          const MCSubtargetInfo &STI) const {
251
252
0
  const MCOperand &MO = MI.getOperand(OpNo);
253
254
  // If the destination is an immediate, divide by 2.
255
0
  if (MO.isImm()) return MO.getImm() >> 1;
256
257
0
  assert(MO.isExpr() &&
258
0
         "getBranchTargetOpValueMM expects only expressions or immediates");
259
260
0
  const MCExpr *Expr = MO.getExpr();
261
0
  Fixups.push_back(MCFixup::create(0, Expr,
262
0
                                   MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1)));
263
0
  return 0;
264
0
}
265
266
/// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS
267
/// 10-bit branch target operand. If the machine operand requires relocation,
268
/// record the relocation and return zero.
269
unsigned MipsMCCodeEmitter::
270
getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo,
271
                             SmallVectorImpl<MCFixup> &Fixups,
272
0
                             const MCSubtargetInfo &STI) const {
273
274
0
  const MCOperand &MO = MI.getOperand(OpNo);
275
276
  // If the destination is an immediate, divide by 2.
277
0
  if (MO.isImm()) return MO.getImm() >> 1;
278
279
0
  assert(MO.isExpr() &&
280
0
         "getBranchTargetOpValuePC10 expects only expressions or immediates");
281
282
0
  const MCExpr *Expr = MO.getExpr();
283
0
  Fixups.push_back(MCFixup::create(0, Expr,
284
0
                   MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1)));
285
0
  return 0;
286
0
}
287
288
/// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
289
/// target operand. If the machine operand requires relocation,
290
/// record the relocation and return zero.
291
unsigned MipsMCCodeEmitter::
292
getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
293
                         SmallVectorImpl<MCFixup> &Fixups,
294
0
                         const MCSubtargetInfo &STI) const {
295
296
0
  const MCOperand &MO = MI.getOperand(OpNo);
297
298
  // If the destination is an immediate, divide by 2.
299
0
  if (MO.isImm()) return MO.getImm() >> 1;
300
301
0
  assert(MO.isExpr() &&
302
0
         "getBranchTargetOpValueMM expects only expressions or immediates");
303
304
0
  const MCExpr *Expr = MO.getExpr();
305
0
  Fixups.push_back(MCFixup::create(0, Expr,
306
0
                   MCFixupKind(Mips::
307
0
                               fixup_MICROMIPS_PC16_S1)));
308
0
  return 0;
309
0
}
310
311
/// getBranchTarget21OpValue - Return binary encoding of the branch
312
/// target operand. If the machine operand requires relocation,
313
/// record the relocation and return zero.
314
unsigned MipsMCCodeEmitter::
315
getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
316
                         SmallVectorImpl<MCFixup> &Fixups,
317
0
                         const MCSubtargetInfo &STI) const {
318
319
0
  const MCOperand &MO = MI.getOperand(OpNo);
320
321
  // If the destination is an immediate, divide by 4.
322
0
  if (MO.isImm()) return MO.getImm() >> 2;
323
324
0
  assert(MO.isExpr() &&
325
0
         "getBranchTarget21OpValue expects only expressions or immediates");
326
327
0
  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
328
0
      MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
329
0
  Fixups.push_back(MCFixup::create(0, FixupExpression,
330
0
                                   MCFixupKind(Mips::fixup_MIPS_PC21_S2)));
331
0
  return 0;
332
0
}
333
334
/// getBranchTarget26OpValue - Return binary encoding of the branch
335
/// target operand. If the machine operand requires relocation,
336
/// record the relocation and return zero.
337
unsigned MipsMCCodeEmitter::
338
getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
339
                         SmallVectorImpl<MCFixup> &Fixups,
340
13
                         const MCSubtargetInfo &STI) const {
341
342
13
  const MCOperand &MO = MI.getOperand(OpNo);
343
344
  // If the destination is an immediate, divide by 4.
345
13
  if (MO.isImm()) return MO.getImm() >> 2;
346
347
13
  assert(MO.isExpr() &&
348
9
         "getBranchTarget26OpValue expects only expressions or immediates");
349
350
9
  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
351
9
      MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
352
9
  Fixups.push_back(MCFixup::create(0, FixupExpression,
353
9
                                   MCFixupKind(Mips::fixup_MIPS_PC26_S2)));
354
9
  return 0;
355
9
}
356
357
/// getBranchTarget26OpValueMM - Return binary encoding of the branch
358
/// target operand. If the machine operand requires relocation,
359
/// record the relocation and return zero.
360
unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM(
361
    const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
362
0
    const MCSubtargetInfo &STI) const {
363
364
0
  const MCOperand &MO = MI.getOperand(OpNo);
365
366
  // If the destination is an immediate, divide by 2.
367
0
  if (MO.isImm())
368
0
    return MO.getImm() >> 1;
369
370
  // TODO: Push 26 PC fixup.
371
0
  return 0;
372
0
}
373
374
/// getJumpOffset16OpValue - Return binary encoding of the jump
375
/// target operand. If the machine operand requires relocation,
376
/// record the relocation and return zero.
377
unsigned MipsMCCodeEmitter::
378
getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo,
379
                       SmallVectorImpl<MCFixup> &Fixups,
380
0
                       const MCSubtargetInfo &STI) const {
381
382
0
  const MCOperand &MO = MI.getOperand(OpNo);
383
384
0
  if (MO.isImm()) return MO.getImm();
385
386
0
  assert(MO.isExpr() &&
387
0
         "getJumpOffset16OpValue expects only expressions or an immediate");
388
389
   // TODO: Push fixup.
390
0
   return 0;
391
0
}
392
393
/// getJumpTargetOpValue - Return binary encoding of the jump
394
/// target operand. If the machine operand requires relocation,
395
/// record the relocation and return zero.
396
unsigned MipsMCCodeEmitter::
397
getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
398
                     SmallVectorImpl<MCFixup> &Fixups,
399
3.03k
                     const MCSubtargetInfo &STI) const {
400
401
3.03k
  const MCOperand &MO = MI.getOperand(OpNo);
402
  // If the destination is an immediate, divide by 4.
403
3.03k
  if (MO.isImm()) return MO.getImm()>>2;
404
405
3.03k
  assert(MO.isExpr() &&
406
2.02k
         "getJumpTargetOpValue expects only expressions or an immediate");
407
408
2.02k
  const MCExpr *Expr = MO.getExpr();
409
2.02k
  Fixups.push_back(MCFixup::create(0, Expr,
410
2.02k
                                   MCFixupKind(Mips::fixup_Mips_26)));
411
2.02k
  return 0;
412
2.02k
}
413
414
unsigned MipsMCCodeEmitter::
415
getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
416
                       SmallVectorImpl<MCFixup> &Fixups,
417
0
                       const MCSubtargetInfo &STI) const {
418
419
0
  const MCOperand &MO = MI.getOperand(OpNo);
420
  // If the destination is an immediate, divide by 2.
421
0
  if (MO.isImm()) return MO.getImm() >> 1;
422
423
0
  assert(MO.isExpr() &&
424
0
         "getJumpTargetOpValueMM expects only expressions or an immediate");
425
426
0
  const MCExpr *Expr = MO.getExpr();
427
0
  Fixups.push_back(MCFixup::create(0, Expr,
428
0
                                   MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
429
0
  return 0;
430
0
}
431
432
unsigned MipsMCCodeEmitter::
433
getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo,
434
                     SmallVectorImpl<MCFixup> &Fixups,
435
0
                     const MCSubtargetInfo &STI) const {
436
437
0
  const MCOperand &MO = MI.getOperand(OpNo);
438
0
  if (MO.isImm()) {
439
    // The immediate is encoded as 'immediate << 2'.
440
0
    unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
441
0
    assert((Res & 3) == 0);
442
0
    return Res >> 2;
443
0
  }
444
445
0
  assert(MO.isExpr() &&
446
0
         "getUImm5Lsl2Encoding expects only expressions or an immediate");
447
448
0
  return 0;
449
0
}
450
451
unsigned MipsMCCodeEmitter::
452
getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo,
453
                  SmallVectorImpl<MCFixup> &Fixups,
454
0
                  const MCSubtargetInfo &STI) const {
455
456
0
  const MCOperand &MO = MI.getOperand(OpNo);
457
0
  if (MO.isImm()) {
458
0
    int Value = MO.getImm();
459
0
    return Value >> 2;
460
0
  }
461
462
0
  return 0;
463
0
}
464
465
unsigned MipsMCCodeEmitter::
466
getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo,
467
                     SmallVectorImpl<MCFixup> &Fixups,
468
0
                     const MCSubtargetInfo &STI) const {
469
470
0
  const MCOperand &MO = MI.getOperand(OpNo);
471
0
  if (MO.isImm()) {
472
0
    unsigned Value = MO.getImm();
473
0
    return Value >> 2;
474
0
  }
475
476
0
  return 0;
477
0
}
478
479
unsigned MipsMCCodeEmitter::
480
getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
481
                     SmallVectorImpl<MCFixup> &Fixups,
482
0
                     const MCSubtargetInfo &STI) const {
483
484
0
  const MCOperand &MO = MI.getOperand(OpNo);
485
0
  if (MO.isImm()) {
486
0
    unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff;
487
0
    return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff));
488
0
  }
489
490
0
  return 0;
491
0
}
492
493
unsigned MipsMCCodeEmitter::
494
getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
495
11.6k
               const MCSubtargetInfo &STI) const {
496
11.6k
  int64_t Res;
497
498
11.6k
  if (Expr->evaluateAsAbsolute(Res))
499
1.75k
    return Res;
500
501
9.90k
  MCExpr::ExprKind Kind = Expr->getKind();
502
9.90k
  if (Kind == MCExpr::Constant) {
503
0
    return cast<MCConstantExpr>(Expr)->getValue();
504
0
  }
505
506
9.90k
  if (Kind == MCExpr::Binary) {
507
5.41k
    unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
508
5.41k
    Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
509
5.41k
    return Res;
510
5.41k
  }
511
512
4.49k
  if (Kind == MCExpr::Target) {
513
368
    const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
514
515
368
    Mips::Fixups FixupKind = Mips::Fixups(0);
516
368
    switch (MipsExpr->getKind()) {
517
0
    default: llvm_unreachable("Unsupported fixup kind for target expression!");
518
16
    case MipsMCExpr::VK_Mips_HIGHEST:
519
16
      FixupKind = Mips::fixup_Mips_HIGHEST;
520
16
      break;
521
16
    case MipsMCExpr::VK_Mips_HIGHER:
522
16
      FixupKind = Mips::fixup_Mips_HIGHER;
523
16
      break;
524
168
    case MipsMCExpr::VK_Mips_HI:
525
168
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
526
168
                                   : Mips::fixup_Mips_HI16;
527
168
      break;
528
168
    case MipsMCExpr::VK_Mips_LO:
529
168
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
530
168
                                   : Mips::fixup_Mips_LO16;
531
168
      break;
532
368
    }
533
368
    Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind)));
534
368
    return 0;
535
368
  }
536
537
4.12k
  if (Kind == MCExpr::SymbolRef) {
538
3.54k
    Mips::Fixups FixupKind = Mips::Fixups(0);
539
540
3.54k
    switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
541
0
    default: llvm_unreachable("Unknown fixup kind!");
542
0
      break;
543
1.47k
    case MCSymbolRefExpr::VK_None:
544
1.47k
      FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64.
545
1.47k
      break;
546
0
    case MCSymbolRefExpr::VK_Mips_GPOFF_HI :
547
0
      FixupKind = Mips::fixup_Mips_GPOFF_HI;
548
0
      break;
549
0
    case MCSymbolRefExpr::VK_Mips_GPOFF_LO :
550
0
      FixupKind = Mips::fixup_Mips_GPOFF_LO;
551
0
      break;
552
0
    case MCSymbolRefExpr::VK_Mips_GOT_PAGE :
553
0
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE
554
0
                              : Mips::fixup_Mips_GOT_PAGE;
555
0
      break;
556
0
    case MCSymbolRefExpr::VK_Mips_GOT_OFST :
557
0
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST
558
0
                              : Mips::fixup_Mips_GOT_OFST;
559
0
      break;
560
7
    case MCSymbolRefExpr::VK_Mips_GOT_DISP :
561
7
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP
562
7
                              : Mips::fixup_Mips_GOT_DISP;
563
7
      break;
564
0
    case MCSymbolRefExpr::VK_Mips_GPREL:
565
0
      FixupKind = Mips::fixup_Mips_GPREL16;
566
0
      break;
567
3
    case MCSymbolRefExpr::VK_Mips_GOT_CALL:
568
3
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16
569
3
                              : Mips::fixup_Mips_CALL16;
570
3
      break;
571
0
    case MCSymbolRefExpr::VK_Mips_GOT16:
572
0
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
573
0
                              : Mips::fixup_Mips_GOT_Global;
574
0
      break;
575
0
    case MCSymbolRefExpr::VK_Mips_GOT:
576
0
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
577
0
                              : Mips::fixup_Mips_GOT_Local;
578
0
      break;
579
1.03k
    case MCSymbolRefExpr::VK_Mips_ABS_HI:
580
1.03k
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
581
1.03k
                              : Mips::fixup_Mips_HI16;
582
1.03k
      break;
583
1.03k
    case MCSymbolRefExpr::VK_Mips_ABS_LO:
584
1.03k
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
585
1.03k
                              : Mips::fixup_Mips_LO16;
586
1.03k
      break;
587
0
    case MCSymbolRefExpr::VK_Mips_TLSGD:
588
0
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD
589
0
                              : Mips::fixup_Mips_TLSGD;
590
0
      break;
591
0
    case MCSymbolRefExpr::VK_Mips_TLSLDM:
592
0
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM
593
0
                              : Mips::fixup_Mips_TLSLDM;
594
0
      break;
595
0
    case MCSymbolRefExpr::VK_Mips_DTPREL_HI:
596
0
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
597
0
                              : Mips::fixup_Mips_DTPREL_HI;
598
0
      break;
599
0
    case MCSymbolRefExpr::VK_Mips_DTPREL_LO:
600
0
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
601
0
                              : Mips::fixup_Mips_DTPREL_LO;
602
0
      break;
603
0
    case MCSymbolRefExpr::VK_Mips_GOTTPREL:
604
0
      FixupKind = Mips::fixup_Mips_GOTTPREL;
605
0
      break;
606
0
    case MCSymbolRefExpr::VK_Mips_TPREL_HI:
607
0
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
608
0
                              : Mips::fixup_Mips_TPREL_HI;
609
0
      break;
610
0
    case MCSymbolRefExpr::VK_Mips_TPREL_LO:
611
0
      FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
612
0
                              : Mips::fixup_Mips_TPREL_LO;
613
0
      break;
614
0
    case MCSymbolRefExpr::VK_Mips_HIGHER:
615
0
      FixupKind = Mips::fixup_Mips_HIGHER;
616
0
      break;
617
0
    case MCSymbolRefExpr::VK_Mips_HIGHEST:
618
0
      FixupKind = Mips::fixup_Mips_HIGHEST;
619
0
      break;
620
0
    case MCSymbolRefExpr::VK_Mips_GOT_HI16:
621
0
      FixupKind = Mips::fixup_Mips_GOT_HI16;
622
0
      break;
623
0
    case MCSymbolRefExpr::VK_Mips_GOT_LO16:
624
0
      FixupKind = Mips::fixup_Mips_GOT_LO16;
625
0
      break;
626
0
    case MCSymbolRefExpr::VK_Mips_CALL_HI16:
627
0
      FixupKind = Mips::fixup_Mips_CALL_HI16;
628
0
      break;
629
0
    case MCSymbolRefExpr::VK_Mips_CALL_LO16:
630
0
      FixupKind = Mips::fixup_Mips_CALL_LO16;
631
0
      break;
632
0
    case MCSymbolRefExpr::VK_Mips_PCREL_HI16:
633
0
      FixupKind = Mips::fixup_MIPS_PCHI16;
634
0
      break;
635
0
    case MCSymbolRefExpr::VK_Mips_PCREL_LO16:
636
0
      FixupKind = Mips::fixup_MIPS_PCLO16;
637
0
      break;
638
3.54k
    } // switch
639
640
3.54k
    Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
641
3.54k
    return 0;
642
3.54k
  }
643
575
  return 0;
644
4.12k
}
645
646
/// getMachineOpValue - Return binary encoding of operand. If the machine
647
/// operand requires relocation, record the relocation and return zero.
648
unsigned MipsMCCodeEmitter::
649
getMachineOpValue(const MCInst &MI, const MCOperand &MO,
650
                  SmallVectorImpl<MCFixup> &Fixups,
651
54.7k
                  const MCSubtargetInfo &STI) const {
652
54.7k
  if (MO.isReg()) {
653
41.6k
    unsigned Reg = MO.getReg();
654
41.6k
    unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
655
41.6k
    return RegNo;
656
41.6k
  } else if (MO.isImm()) {
657
12.3k
    return static_cast<unsigned>(MO.getImm());
658
12.3k
  } else if (MO.isFPImm()) {
659
0
    return static_cast<unsigned>(APFloat(MO.getFPImm())
660
0
        .bitcastToAPInt().getHiBits(32).getLimitedValue());
661
0
  }
662
  // MO must be an Expr.
663
54.7k
  assert(MO.isExpr());
664
836
  return getExprOpValue(MO.getExpr(),Fixups, STI);
665
836
}
666
667
/// getMSAMemEncoding - Return binary encoding of memory operand for LD/ST
668
/// instructions.
669
unsigned
670
MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo,
671
                                     SmallVectorImpl<MCFixup> &Fixups,
672
0
                                     const MCSubtargetInfo &STI) const {
673
  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
674
0
  assert(MI.getOperand(OpNo).isReg());
675
0
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
676
0
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
677
678
  // The immediate field of an LD/ST instruction is scaled which means it must
679
  // be divided (when encoding) by the size (in bytes) of the instructions'
680
  // data format.
681
  // .b - 1 byte
682
  // .h - 2 bytes
683
  // .w - 4 bytes
684
  // .d - 8 bytes
685
0
  switch(MI.getOpcode())
686
0
  {
687
0
  default:
688
0
    assert (0 && "Unexpected instruction");
689
0
    break;
690
0
  case Mips::LD_B:
691
0
  case Mips::ST_B:
692
    // We don't need to scale the offset in this case
693
0
    break;
694
0
  case Mips::LD_H:
695
0
  case Mips::ST_H:
696
0
    OffBits >>= 1;
697
0
    break;
698
0
  case Mips::LD_W:
699
0
  case Mips::ST_W:
700
0
    OffBits >>= 2;
701
0
    break;
702
0
  case Mips::LD_D:
703
0
  case Mips::ST_D:
704
0
    OffBits >>= 3;
705
0
    break;
706
0
  }
707
708
0
  return (OffBits & 0xFFFF) | RegBits;
709
0
}
710
711
/// getMemEncoding - Return binary encoding of memory related operand.
712
/// If the offset operand requires relocation, record the relocation.
713
unsigned
714
MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
715
                                  SmallVectorImpl<MCFixup> &Fixups,
716
681
                                  const MCSubtargetInfo &STI) const {
717
  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
718
681
  assert(MI.getOperand(OpNo).isReg());
719
681
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
720
681
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
721
722
681
  return (OffBits & 0xFFFF) | RegBits;
723
681
}
724
725
unsigned MipsMCCodeEmitter::
726
getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo,
727
                     SmallVectorImpl<MCFixup> &Fixups,
728
0
                     const MCSubtargetInfo &STI) const {
729
  // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
730
0
  assert(MI.getOperand(OpNo).isReg());
731
0
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
732
0
                                       Fixups, STI) << 4;
733
0
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
734
0
                                       Fixups, STI);
735
736
0
  return (OffBits & 0xF) | RegBits;
737
0
}
738
739
unsigned MipsMCCodeEmitter::
740
getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo,
741
                         SmallVectorImpl<MCFixup> &Fixups,
742
0
                         const MCSubtargetInfo &STI) const {
743
  // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
744
0
  assert(MI.getOperand(OpNo).isReg());
745
0
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
746
0
                                       Fixups, STI) << 4;
747
0
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
748
0
                                       Fixups, STI) >> 1;
749
750
0
  return (OffBits & 0xF) | RegBits;
751
0
}
752
753
unsigned MipsMCCodeEmitter::
754
getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo,
755
                         SmallVectorImpl<MCFixup> &Fixups,
756
0
                         const MCSubtargetInfo &STI) const {
757
  // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
758
0
  assert(MI.getOperand(OpNo).isReg());
759
0
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
760
0
                                       Fixups, STI) << 4;
761
0
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
762
0
                                       Fixups, STI) >> 2;
763
764
0
  return (OffBits & 0xF) | RegBits;
765
0
}
766
767
unsigned MipsMCCodeEmitter::
768
getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
769
                           SmallVectorImpl<MCFixup> &Fixups,
770
0
                           const MCSubtargetInfo &STI) const {
771
  // Register is encoded in bits 9-5, offset is encoded in bits 4-0.
772
0
  assert(MI.getOperand(OpNo).isReg() &&
773
0
         (MI.getOperand(OpNo).getReg() == Mips::SP ||
774
0
         MI.getOperand(OpNo).getReg() == Mips::SP_64) &&
775
0
         "Unexpected base register!");
776
0
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
777
0
                                       Fixups, STI) >> 2;
778
779
0
  return OffBits & 0x1F;
780
0
}
781
782
unsigned MipsMCCodeEmitter::
783
getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
784
                           SmallVectorImpl<MCFixup> &Fixups,
785
0
                           const MCSubtargetInfo &STI) const {
786
  // Register is encoded in bits 9-7, offset is encoded in bits 6-0.
787
0
  assert(MI.getOperand(OpNo).isReg() &&
788
0
         MI.getOperand(OpNo).getReg() == Mips::GP &&
789
0
         "Unexpected base register!");
790
791
0
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
792
0
                                       Fixups, STI) >> 2;
793
794
0
  return OffBits & 0x7F;
795
0
}
796
797
unsigned MipsMCCodeEmitter::
798
getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo,
799
                     SmallVectorImpl<MCFixup> &Fixups,
800
0
                     const MCSubtargetInfo &STI) const {
801
  // Base register is encoded in bits 20-16, offset is encoded in bits 8-0.
802
0
  assert(MI.getOperand(OpNo).isReg());
803
0
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
804
0
                                       STI) << 16;
805
0
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI);
806
807
0
  return (OffBits & 0x1FF) | RegBits;
808
0
}
809
810
unsigned MipsMCCodeEmitter::
811
getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
812
                      SmallVectorImpl<MCFixup> &Fixups,
813
0
                      const MCSubtargetInfo &STI) const {
814
  // opNum can be invalid if instruction had reglist as operand.
815
  // MemOperand is always last operand of instruction (base + offset).
816
0
  switch (MI.getOpcode()) {
817
0
  default:
818
0
    break;
819
0
  case Mips::SWM32_MM:
820
0
  case Mips::LWM32_MM:
821
0
    OpNo = MI.getNumOperands() - 2;
822
0
    break;
823
0
  }
824
825
  // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
826
0
  assert(MI.getOperand(OpNo).isReg());
827
0
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
828
0
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
829
830
0
  return (OffBits & 0x0FFF) | RegBits;
831
0
}
832
833
unsigned MipsMCCodeEmitter::
834
getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo,
835
                      SmallVectorImpl<MCFixup> &Fixups,
836
0
                      const MCSubtargetInfo &STI) const {
837
  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
838
0
  assert(MI.getOperand(OpNo).isReg());
839
0
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
840
0
                                       STI) << 16;
841
0
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
842
843
0
  return (OffBits & 0xFFFF) | RegBits;
844
0
}
845
846
unsigned MipsMCCodeEmitter::
847
getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
848
                       SmallVectorImpl<MCFixup> &Fixups,
849
0
                       const MCSubtargetInfo &STI) const {
850
  // opNum can be invalid if instruction had reglist as operand
851
  // MemOperand is always last operand of instruction (base + offset)
852
0
  switch (MI.getOpcode()) {
853
0
  default:
854
0
    break;
855
0
  case Mips::SWM16_MM:
856
0
  case Mips::SWM16_MMR6:
857
0
  case Mips::LWM16_MM:
858
0
  case Mips::LWM16_MMR6:
859
0
    OpNo = MI.getNumOperands() - 2;
860
0
    break;
861
0
  }
862
863
  // Offset is encoded in bits 4-0.
864
0
  assert(MI.getOperand(OpNo).isReg());
865
  // Base register is always SP - thus it is not encoded.
866
0
  assert(MI.getOperand(OpNo+1).isImm());
867
0
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
868
869
0
  return ((OffBits >> 2) & 0x0F);
870
0
}
871
872
// FIXME: should be called getMSBEncoding
873
//
874
unsigned
875
MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
876
                                      SmallVectorImpl<MCFixup> &Fixups,
877
0
                                      const MCSubtargetInfo &STI) const {
878
0
  assert(MI.getOperand(OpNo-1).isImm());
879
0
  assert(MI.getOperand(OpNo).isImm());
880
0
  unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI);
881
0
  unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
882
883
0
  return Position + Size - 1;
884
0
}
885
886
template <unsigned Bits, int Offset>
887
unsigned
888
MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo,
889
                                             SmallVectorImpl<MCFixup> &Fixups,
890
0
                                             const MCSubtargetInfo &STI) const {
891
0
  assert(MI.getOperand(OpNo).isImm());
892
0
  unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
893
0
  Value -= Offset;
894
0
  return Value;
895
0
}
Unexecuted instantiation: unsigned int llvm_ks::MipsMCCodeEmitter::getUImmWithOffsetEncoding<2u, 1>(llvm_ks::MCInst const&, unsigned int, llvm_ks::SmallVectorImpl<llvm_ks::MCFixup>&, llvm_ks::MCSubtargetInfo const&) const
Unexecuted instantiation: unsigned int llvm_ks::MipsMCCodeEmitter::getUImmWithOffsetEncoding<5u, 1>(llvm_ks::MCInst const&, unsigned int, llvm_ks::SmallVectorImpl<llvm_ks::MCFixup>&, llvm_ks::MCSubtargetInfo const&) const
896
897
unsigned
898
MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
899
                                         SmallVectorImpl<MCFixup> &Fixups,
900
0
                                         const MCSubtargetInfo &STI) const {
901
0
  const MCOperand &MO = MI.getOperand(OpNo);
902
0
  if (MO.isImm()) {
903
    // The immediate is encoded as 'immediate << 2'.
904
0
    unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
905
0
    assert((Res & 3) == 0);
906
0
    return Res >> 2;
907
0
  }
908
909
0
  assert(MO.isExpr() &&
910
0
         "getSimm19Lsl2Encoding expects only expressions or an immediate");
911
912
0
  const MCExpr *Expr = MO.getExpr();
913
0
  Fixups.push_back(MCFixup::create(0, Expr,
914
0
                                   MCFixupKind(Mips::fixup_MIPS_PC19_S2)));
915
0
  return 0;
916
0
}
917
918
unsigned
919
MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
920
                                         SmallVectorImpl<MCFixup> &Fixups,
921
0
                                         const MCSubtargetInfo &STI) const {
922
0
  const MCOperand &MO = MI.getOperand(OpNo);
923
0
  if (MO.isImm()) {
924
    // The immediate is encoded as 'immediate << 3'.
925
0
    unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
926
0
    assert((Res & 7) == 0);
927
0
    return Res >> 3;
928
0
  }
929
930
0
  assert(MO.isExpr() &&
931
0
         "getSimm18Lsl2Encoding expects only expressions or an immediate");
932
933
0
  const MCExpr *Expr = MO.getExpr();
934
0
  Fixups.push_back(MCFixup::create(0, Expr,
935
0
                                   MCFixupKind(Mips::fixup_MIPS_PC18_S3)));
936
0
  return 0;
937
0
}
938
939
unsigned
940
MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
941
                                        SmallVectorImpl<MCFixup> &Fixups,
942
0
                                        const MCSubtargetInfo &STI) const {
943
0
  assert(MI.getOperand(OpNo).isImm());
944
0
  const MCOperand &MO = MI.getOperand(OpNo);
945
0
  return MO.getImm() % 8;
946
0
}
947
948
unsigned
949
MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo,
950
                                    SmallVectorImpl<MCFixup> &Fixups,
951
0
                                    const MCSubtargetInfo &STI) const {
952
0
  assert(MI.getOperand(OpNo).isImm());
953
0
  const MCOperand &MO = MI.getOperand(OpNo);
954
0
  unsigned Value = MO.getImm();
955
0
  switch (Value) {
956
0
    case 128:   return 0x0;
957
0
    case 1:     return 0x1;
958
0
    case 2:     return 0x2;
959
0
    case 3:     return 0x3;
960
0
    case 4:     return 0x4;
961
0
    case 7:     return 0x5;
962
0
    case 8:     return 0x6;
963
0
    case 15:    return 0x7;
964
0
    case 16:    return 0x8;
965
0
    case 31:    return 0x9;
966
0
    case 32:    return 0xa;
967
0
    case 63:    return 0xb;
968
0
    case 64:    return 0xc;
969
0
    case 255:   return 0xd;
970
0
    case 32768: return 0xe;
971
0
    case 65535: return 0xf;
972
0
  }
973
0
  llvm_unreachable("Unexpected value");
974
0
}
975
976
unsigned
977
MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo,
978
                                          SmallVectorImpl<MCFixup> &Fixups,
979
0
                                          const MCSubtargetInfo &STI) const {
980
0
  unsigned res = 0;
981
982
  // Register list operand is always first operand of instruction and it is
983
  // placed before memory operand (register + imm).
984
985
0
  for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) {
986
0
    unsigned Reg = MI.getOperand(I).getReg();
987
0
    unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
988
0
    if (RegNo != 31)
989
0
      res++;
990
0
    else
991
0
      res |= 0x10;
992
0
  }
993
0
  return res;
994
0
}
995
996
unsigned
997
MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
998
                                            SmallVectorImpl<MCFixup> &Fixups,
999
0
                                            const MCSubtargetInfo &STI) const {
1000
0
  return (MI.getNumOperands() - 4);
1001
0
}
1002
1003
unsigned
1004
MipsMCCodeEmitter::getRegisterPairOpValue(const MCInst &MI, unsigned OpNo,
1005
                                          SmallVectorImpl<MCFixup> &Fixups,
1006
0
                                          const MCSubtargetInfo &STI) const {
1007
0
  return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
1008
0
}
1009
1010
unsigned
1011
MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
1012
                                          SmallVectorImpl<MCFixup> &Fixups,
1013
0
                                          const MCSubtargetInfo &STI) const {
1014
0
  unsigned res = 0;
1015
1016
0
  if (MI.getOperand(0).getReg() == Mips::A1 &&
1017
0
      MI.getOperand(1).getReg() == Mips::A2)
1018
0
    res = 0;
1019
0
  else if (MI.getOperand(0).getReg() == Mips::A1 &&
1020
0
           MI.getOperand(1).getReg() == Mips::A3)
1021
0
    res = 1;
1022
0
  else if (MI.getOperand(0).getReg() == Mips::A2 &&
1023
0
           MI.getOperand(1).getReg() == Mips::A3)
1024
0
    res = 2;
1025
0
  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1026
0
           MI.getOperand(1).getReg() == Mips::S5)
1027
0
    res = 3;
1028
0
  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1029
0
           MI.getOperand(1).getReg() == Mips::S6)
1030
0
    res = 4;
1031
0
  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1032
0
           MI.getOperand(1).getReg() == Mips::A1)
1033
0
    res = 5;
1034
0
  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1035
0
           MI.getOperand(1).getReg() == Mips::A2)
1036
0
    res = 6;
1037
0
  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1038
0
           MI.getOperand(1).getReg() == Mips::A3)
1039
0
    res = 7;
1040
1041
0
  return res;
1042
0
}
1043
1044
unsigned
1045
MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
1046
                                         SmallVectorImpl<MCFixup> &Fixups,
1047
0
                                         const MCSubtargetInfo &STI) const {
1048
0
  const MCOperand &MO = MI.getOperand(OpNo);
1049
0
  assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate");
1050
  // The immediate is encoded as 'immediate >> 2'.
1051
0
  unsigned Res = static_cast<unsigned>(MO.getImm());
1052
0
  assert((Res & 3) == 0);
1053
0
  return Res >> 2;
1054
0
}
1055
1056
#include "MipsGenMCCodeEmitter.inc"