Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file implements the MipsMCCodeEmitter class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "MipsMCCodeEmitter.h"
14
#include "MCTargetDesc/MipsFixupKinds.h"
15
#include "MCTargetDesc/MipsMCExpr.h"
16
#include "MCTargetDesc/MipsMCTargetDesc.h"
17
#include "llvm/ADT/APFloat.h"
18
#include "llvm/ADT/APInt.h"
19
#include "llvm/ADT/SmallVector.h"
20
#include "llvm/MC/MCContext.h"
21
#include "llvm/MC/MCExpr.h"
22
#include "llvm/MC/MCFixup.h"
23
#include "llvm/MC/MCInst.h"
24
#include "llvm/MC/MCInstrDesc.h"
25
#include "llvm/MC/MCInstrInfo.h"
26
#include "llvm/MC/MCRegisterInfo.h"
27
#include "llvm/MC/MCSubtargetInfo.h"
28
#include "llvm/Support/Casting.h"
29
#include "llvm/Support/ErrorHandling.h"
30
#include "llvm/Support/raw_ostream.h"
31
#include <cassert>
32
#include <cstdint>
33
34
using namespace llvm;
35
36
#define DEBUG_TYPE "mccodeemitter"
37
38
#define GET_INSTRMAP_INFO
39
#include "MipsGenInstrInfo.inc"
40
#undef GET_INSTRMAP_INFO
41
42
namespace llvm {
43
44
MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
45
                                         const MCRegisterInfo &MRI,
46
690
                                         MCContext &Ctx) {
47
690
  return new MipsMCCodeEmitter(MCII, Ctx, false);
48
690
}
49
50
MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
51
                                         const MCRegisterInfo &MRI,
52
257
                                         MCContext &Ctx) {
53
257
  return new MipsMCCodeEmitter(MCII, Ctx, true);
54
257
}
55
56
} // end namespace llvm
57
58
// If the D<shift> instruction has a shift amount that is greater
59
// than 31 (checked in calling routine), lower it to a D<shift>32 instruction
60
1.15k
static void LowerLargeShift(MCInst& Inst) {
61
1.15k
  assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
62
1.15k
  assert(Inst.getOperand(2).isImm());
63
1.15k
64
1.15k
  int64_t Shift = Inst.getOperand(2).getImm();
65
1.15k
  if (Shift <= 31)
66
1.12k
    return; // Do nothing
67
28
  Shift -= 32;
68
28
69
28
  // saminus32
70
28
  Inst.getOperand(2).setImm(Shift);
71
28
72
28
  switch (Inst.getOpcode()) {
73
28
  default:
74
0
    // Calling function is not synchronized
75
0
    llvm_unreachable("Unexpected shift instruction");
76
28
  case Mips::DSLL:
77
21
    Inst.setOpcode(Mips::DSLL32);
78
21
    return;
79
28
  case Mips::DSRL:
80
5
    Inst.setOpcode(Mips::DSRL32);
81
5
    return;
82
28
  case Mips::DSRA:
83
2
    Inst.setOpcode(Mips::DSRA32);
84
2
    return;
85
28
  case Mips::DROTR:
86
0
    Inst.setOpcode(Mips::DROTR32);
87
0
    return;
88
28
  }
89
28
}
90
91
// Fix a bad compact branch encoding for beqc/bnec.
92
37
void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const {
93
37
  // Encoding may be illegal !(rs < rt), but this situation is
94
37
  // easily fixed.
95
37
  unsigned RegOp0 = Inst.getOperand(0).getReg();
96
37
  unsigned RegOp1 = Inst.getOperand(1).getReg();
97
37
98
37
  unsigned Reg0 =  Ctx.getRegisterInfo()->getEncodingValue(RegOp0);
99
37
  unsigned Reg1 =  Ctx.getRegisterInfo()->getEncodingValue(RegOp1);
100
37
101
37
  if (Inst.getOpcode() == Mips::BNEC || 
Inst.getOpcode() == Mips::BEQC27
||
102
37
      
Inst.getOpcode() == Mips::BNEC6417
||
Inst.getOpcode() == Mips::BEQC6416
) {
103
21
    assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!");
104
21
    if (Reg0 < Reg1)
105
14
      return;
106
16
  } else if (Inst.getOpcode() == Mips::BNVC || 
Inst.getOpcode() == Mips::BOVC10
) {
107
12
    if (Reg0 >= Reg1)
108
8
      return;
109
4
  } else if (Inst.getOpcode() == Mips::BNVC_MMR6 ||
110
4
             
Inst.getOpcode() == Mips::BOVC_MMR62
) {
111
4
    if (Reg1 >= Reg0)
112
2
      return;
113
4
  } else
114
4
    llvm_unreachable("Cannot rewrite unknown branch!");
115
37
116
37
  Inst.getOperand(0).setReg(RegOp1);
117
13
  Inst.getOperand(1).setReg(RegOp0);
118
13
}
119
120
59.5k
bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const {
121
59.5k
  return STI.getFeatureBits()[Mips::FeatureMicroMips];
122
59.5k
}
123
124
2.73k
bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const {
125
2.73k
  return STI.getFeatureBits()[Mips::FeatureMips32r6];
126
2.73k
}
127
128
169k
void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const {
129
169k
  OS << (char)C;
130
169k
}
131
132
void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size,
133
                                        const MCSubtargetInfo &STI,
134
44.1k
                                        raw_ostream &OS) const {
135
44.1k
  // Output the instruction encoding in little endian byte order.
136
44.1k
  // Little-endian byte ordering:
137
44.1k
  //   mips32r2:   4 | 3 | 2 | 1
138
44.1k
  //   microMIPS:  2 | 1 | 4 | 3
139
44.1k
  if (IsLittleEndian && 
Size == 46.79k
&&
isMicroMips(STI)5.16k
) {
140
765
    EmitInstruction(Val >> 16, 2, STI, OS);
141
765
    EmitInstruction(Val, 2, STI, OS);
142
43.3k
  } else {
143
213k
    for (unsigned i = 0; i < Size; 
++i169k
) {
144
169k
      unsigned Shift = IsLittleEndian ? 
i * 820.8k
:
(Size - 1 - i) * 8148k
;
145
169k
      EmitByte((Val >> Shift) & 0xff, OS);
146
169k
    }
147
43.3k
  }
148
44.1k
}
149
150
/// encodeInstruction - Emit the instruction.
151
/// Size the instruction with Desc.getSize().
152
void MipsMCCodeEmitter::
153
encodeInstruction(const MCInst &MI, raw_ostream &OS,
154
                  SmallVectorImpl<MCFixup> &Fixups,
155
                  const MCSubtargetInfo &STI) const
156
42.6k
{
157
42.6k
  // Non-pseudo instructions that get changed for direct object
158
42.6k
  // only based on operand values.
159
42.6k
  // If this list of instructions get much longer we will move
160
42.6k
  // the check to a function call. Until then, this is more efficient.
161
42.6k
  MCInst TmpInst = MI;
162
42.6k
  switch (MI.getOpcode()) {
163
42.6k
  // If shift amount is >= 32 it the inst needs to be lowered further
164
42.6k
  case Mips::DSLL:
165
1.15k
  case Mips::DSRL:
166
1.15k
  case Mips::DSRA:
167
1.15k
  case Mips::DROTR:
168
1.15k
    LowerLargeShift(TmpInst);
169
1.15k
    break;
170
1.15k
  // Compact branches, enforce encoding restrictions.
171
1.15k
  case Mips::BEQC:
172
37
  case Mips::BNEC:
173
37
  case Mips::BEQC64:
174
37
  case Mips::BNEC64:
175
37
  case Mips::BOVC:
176
37
  case Mips::BOVC_MMR6:
177
37
  case Mips::BNVC:
178
37
  case Mips::BNVC_MMR6:
179
37
    LowerCompactBranch(TmpInst);
180
42.6k
  }
181
42.6k
182
42.6k
  unsigned long N = Fixups.size();
183
42.6k
  uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
184
42.6k
185
42.6k
  // Check for unimplemented opcodes.
186
42.6k
  // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
187
42.6k
  // so we have to special check for them.
188
42.6k
  const unsigned Opcode = TmpInst.getOpcode();
189
42.6k
  if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) &&
190
42.6k
      
(Opcode != Mips::SLL_MM)30.6k
&&
(Opcode != Mips::SLL_MMR6)30.6k
&&
!Binary30.6k
)
191
42.6k
    
llvm_unreachable0
("unimplemented opcode in encodeInstruction()");
192
42.6k
193
42.6k
  int NewOpcode = -1;
194
42.6k
  if (isMicroMips(STI)) {
195
2.73k
    if (isMips32r6(STI)) {
196
737
      NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6);
197
737
      if (NewOpcode == -1)
198
707
        NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6);
199
737
    }
200
1.99k
    else
201
1.99k
      NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips);
202
2.73k
203
2.73k
    // Check whether it is Dsp instruction.
204
2.73k
    if (NewOpcode == -1)
205
2.23k
      NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp);
206
2.73k
207
2.73k
    if (NewOpcode != -1) {
208
500
      if (Fixups.size() > N)
209
52
        Fixups.pop_back();
210
500
211
500
      TmpInst.setOpcode (NewOpcode);
212
500
      Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
213
500
    }
214
2.73k
215
2.73k
    if (((MI.getOpcode() == Mips::MOVEP_MM) ||
216
2.73k
         
(MI.getOpcode() == Mips::MOVEP_MMR6)2.72k
)) {
217
4
      unsigned RegPair = getMovePRegPairOpValue(MI, 0, Fixups, STI);
218
4
      Binary = (Binary & 0xFFFFFC7F) | (RegPair << 7);
219
4
    }
220
2.73k
  }
221
42.6k
222
42.6k
  const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
223
42.6k
224
42.6k
  // Get byte count of instruction
225
42.6k
  unsigned Size = Desc.getSize();
226
42.6k
  if (!Size)
227
42.6k
    
llvm_unreachable0
("Desc.getSize() returns 0");
228
42.6k
229
42.6k
  EmitInstruction(Binary, Size, STI, OS);
230
42.6k
}
231
232
/// getBranchTargetOpValue - Return binary encoding of the branch
233
/// target operand. If the machine operand requires relocation,
234
/// record the relocation and return zero.
235
unsigned MipsMCCodeEmitter::
236
getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
237
                       SmallVectorImpl<MCFixup> &Fixups,
238
740
                       const MCSubtargetInfo &STI) const {
239
740
  const MCOperand &MO = MI.getOperand(OpNo);
240
740
241
740
  // If the destination is an immediate, divide by 4.
242
740
  if (MO.isImm()) 
return MO.getImm() >> 2432
;
243
308
244
308
  assert(MO.isExpr() &&
245
308
         "getBranchTargetOpValue expects only expressions or immediates");
246
308
247
308
  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
248
308
      MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
249
308
  Fixups.push_back(MCFixup::create(0, FixupExpression,
250
308
                                   MCFixupKind(Mips::fixup_Mips_PC16)));
251
308
  return 0;
252
308
}
253
254
/// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch
255
/// target operand. If the machine operand requires relocation,
256
/// record the relocation and return zero.
257
unsigned MipsMCCodeEmitter::
258
getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo,
259
                              SmallVectorImpl<MCFixup> &Fixups,
260
1
                              const MCSubtargetInfo &STI) const {
261
1
  const MCOperand &MO = MI.getOperand(OpNo);
262
1
263
1
  // If the destination is an immediate, divide by 2.
264
1
  if (MO.isImm()) return MO.getImm() >> 1;
265
0
266
0
  assert(MO.isExpr() &&
267
0
         "getBranchTargetOpValue expects only expressions or immediates");
268
0
269
0
  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
270
0
      MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
271
0
  Fixups.push_back(MCFixup::create(0, FixupExpression,
272
0
                                   MCFixupKind(Mips::fixup_Mips_PC16)));
273
0
  return 0;
274
0
}
275
276
/// getBranchTargetOpValueMMR6 - Return binary encoding of the branch
277
/// target operand. If the machine operand requires relocation,
278
/// record the relocation and return zero.
279
unsigned MipsMCCodeEmitter::
280
getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo,
281
                           SmallVectorImpl<MCFixup> &Fixups,
282
4
                           const MCSubtargetInfo &STI) const {
283
4
  const MCOperand &MO = MI.getOperand(OpNo);
284
4
285
4
  // If the destination is an immediate, divide by 2.
286
4
  if (MO.isImm())
287
4
    return MO.getImm() >> 1;
288
0
289
0
  assert(MO.isExpr() &&
290
0
         "getBranchTargetOpValueMMR6 expects only expressions or immediates");
291
0
292
0
  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
293
0
      MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx);
294
0
  Fixups.push_back(MCFixup::create(0, FixupExpression,
295
0
                                   MCFixupKind(Mips::fixup_Mips_PC16)));
296
0
  return 0;
297
0
}
298
299
/// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch
300
/// target operand. If the machine operand requires relocation,
301
/// record the relocation and return zero.
302
unsigned MipsMCCodeEmitter::
303
getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo,
304
                               SmallVectorImpl<MCFixup> &Fixups,
305
10
                               const MCSubtargetInfo &STI) const {
306
10
  const MCOperand &MO = MI.getOperand(OpNo);
307
10
308
10
  // If the destination is an immediate, divide by 4.
309
10
  if (MO.isImm())
310
10
    return MO.getImm() >> 2;
311
0
312
0
  assert(MO.isExpr() &&
313
0
         "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates");
314
0
315
0
  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
316
0
      MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
317
0
  Fixups.push_back(MCFixup::create(0, FixupExpression,
318
0
                                   MCFixupKind(Mips::fixup_Mips_PC16)));
319
0
  return 0;
320
0
}
321
322
/// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch
323
/// target operand. If the machine operand requires relocation,
324
/// record the relocation and return zero.
325
unsigned MipsMCCodeEmitter::
326
getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo,
327
                          SmallVectorImpl<MCFixup> &Fixups,
328
15
                          const MCSubtargetInfo &STI) const {
329
15
  const MCOperand &MO = MI.getOperand(OpNo);
330
15
331
15
  // If the destination is an immediate, divide by 2.
332
15
  if (MO.isImm()) 
return MO.getImm() >> 19
;
333
6
334
6
  assert(MO.isExpr() &&
335
6
         "getBranchTargetOpValueMM expects only expressions or immediates");
336
6
337
6
  const MCExpr *Expr = MO.getExpr();
338
6
  Fixups.push_back(MCFixup::create(0, Expr,
339
6
                                   MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1)));
340
6
  return 0;
341
6
}
342
343
/// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS
344
/// 10-bit branch target operand. If the machine operand requires relocation,
345
/// record the relocation and return zero.
346
unsigned MipsMCCodeEmitter::
347
getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo,
348
                             SmallVectorImpl<MCFixup> &Fixups,
349
13
                             const MCSubtargetInfo &STI) const {
350
13
  const MCOperand &MO = MI.getOperand(OpNo);
351
13
352
13
  // If the destination is an immediate, divide by 2.
353
13
  if (MO.isImm()) 
return MO.getImm() >> 18
;
354
5
355
5
  assert(MO.isExpr() &&
356
5
         "getBranchTargetOpValuePC10 expects only expressions or immediates");
357
5
358
5
  const MCExpr *Expr = MO.getExpr();
359
5
  Fixups.push_back(MCFixup::create(0, Expr,
360
5
                   MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1)));
361
5
  return 0;
362
5
}
363
364
/// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
365
/// target operand. If the machine operand requires relocation,
366
/// record the relocation and return zero.
367
unsigned MipsMCCodeEmitter::
368
getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
369
                         SmallVectorImpl<MCFixup> &Fixups,
370
103
                         const MCSubtargetInfo &STI) const {
371
103
  const MCOperand &MO = MI.getOperand(OpNo);
372
103
373
103
  // If the destination is an immediate, divide by 2.
374
103
  if (MO.isImm()) 
return MO.getImm() >> 156
;
375
47
376
47
  assert(MO.isExpr() &&
377
47
         "getBranchTargetOpValueMM expects only expressions or immediates");
378
47
379
47
  const MCExpr *Expr = MO.getExpr();
380
47
  Fixups.push_back(MCFixup::create(0, Expr,
381
47
                   MCFixupKind(Mips::
382
47
                               fixup_MICROMIPS_PC16_S1)));
383
47
  return 0;
384
47
}
385
386
/// getBranchTarget21OpValue - Return binary encoding of the branch
387
/// target operand. If the machine operand requires relocation,
388
/// record the relocation and return zero.
389
unsigned MipsMCCodeEmitter::
390
getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
391
                         SmallVectorImpl<MCFixup> &Fixups,
392
26
                         const MCSubtargetInfo &STI) const {
393
26
  const MCOperand &MO = MI.getOperand(OpNo);
394
26
395
26
  // If the destination is an immediate, divide by 4.
396
26
  if (MO.isImm()) 
return MO.getImm() >> 24
;
397
22
398
22
  assert(MO.isExpr() &&
399
22
         "getBranchTarget21OpValue expects only expressions or immediates");
400
22
401
22
  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
402
22
      MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
403
22
  Fixups.push_back(MCFixup::create(0, FixupExpression,
404
22
                                   MCFixupKind(Mips::fixup_MIPS_PC21_S2)));
405
22
  return 0;
406
22
}
407
408
/// getBranchTarget21OpValueMM - Return binary encoding of the branch
409
/// target operand for microMIPS. If the machine operand requires
410
/// relocation, record the relocation and return zero.
411
unsigned MipsMCCodeEmitter::
412
getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo,
413
                           SmallVectorImpl<MCFixup> &Fixups,
414
8
                           const MCSubtargetInfo &STI) const {
415
8
  const MCOperand &MO = MI.getOperand(OpNo);
416
8
417
8
  // If the destination is an immediate, divide by 4.
418
8
  if (MO.isImm()) 
return MO.getImm() >> 22
;
419
6
420
6
  assert(MO.isExpr() &&
421
6
    "getBranchTarget21OpValueMM expects only expressions or immediates");
422
6
423
6
  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
424
6
      MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
425
6
  Fixups.push_back(MCFixup::create(0, FixupExpression,
426
6
                                   MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1)));
427
6
  return 0;
428
6
}
429
430
/// getBranchTarget26OpValue - Return binary encoding of the branch
431
/// target operand. If the machine operand requires relocation,
432
/// record the relocation and return zero.
433
unsigned MipsMCCodeEmitter::
434
getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
435
                         SmallVectorImpl<MCFixup> &Fixups,
436
27
                         const MCSubtargetInfo &STI) const {
437
27
  const MCOperand &MO = MI.getOperand(OpNo);
438
27
439
27
  // If the destination is an immediate, divide by 4.
440
27
  if (MO.isImm()) 
return MO.getImm() >> 26
;
441
21
442
21
  assert(MO.isExpr() &&
443
21
         "getBranchTarget26OpValue expects only expressions or immediates");
444
21
445
21
  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
446
21
      MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
447
21
  Fixups.push_back(MCFixup::create(0, FixupExpression,
448
21
                                   MCFixupKind(Mips::fixup_MIPS_PC26_S2)));
449
21
  return 0;
450
21
}
451
452
/// getBranchTarget26OpValueMM - Return binary encoding of the branch
453
/// target operand. If the machine operand requires relocation,
454
/// record the relocation and return zero.
455
unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM(
456
    const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
457
14
    const MCSubtargetInfo &STI) const {
458
14
  const MCOperand &MO = MI.getOperand(OpNo);
459
14
460
14
  // If the destination is an immediate, divide by 2.
461
14
  if (MO.isImm())
462
3
    return MO.getImm() >> 1;
463
11
464
11
  assert(MO.isExpr() &&
465
11
         "getBranchTarget26OpValueMM expects only expressions or immediates");
466
11
467
11
  const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
468
11
      MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
469
11
  Fixups.push_back(MCFixup::create(0, FixupExpression,
470
11
                                   MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1)));
471
11
  return 0;
472
11
}
473
474
/// getJumpOffset16OpValue - Return binary encoding of the jump
475
/// target operand. If the machine operand requires relocation,
476
/// record the relocation and return zero.
477
unsigned MipsMCCodeEmitter::
478
getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo,
479
                       SmallVectorImpl<MCFixup> &Fixups,
480
52
                       const MCSubtargetInfo &STI) const {
481
52
  const MCOperand &MO = MI.getOperand(OpNo);
482
52
483
52
  if (MO.isImm()) return MO.getImm();
484
0
485
0
  assert(MO.isExpr() &&
486
0
         "getJumpOffset16OpValue expects only expressions or an immediate");
487
0
488
0
   // TODO: Push fixup.
489
0
   return 0;
490
0
}
491
492
/// getJumpTargetOpValue - Return binary encoding of the jump
493
/// target operand. If the machine operand requires relocation,
494
/// record the relocation and return zero.
495
unsigned MipsMCCodeEmitter::
496
getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
497
                     SmallVectorImpl<MCFixup> &Fixups,
498
146
                     const MCSubtargetInfo &STI) const {
499
146
  const MCOperand &MO = MI.getOperand(OpNo);
500
146
  // If the destination is an immediate, divide by 4.
501
146
  if (MO.isImm()) 
return MO.getImm()>>241
;
502
105
503
105
  assert(MO.isExpr() &&
504
105
         "getJumpTargetOpValue expects only expressions or an immediate");
505
105
506
105
  const MCExpr *Expr = MO.getExpr();
507
105
  Fixups.push_back(MCFixup::create(0, Expr,
508
105
                                   MCFixupKind(Mips::fixup_Mips_26)));
509
105
  return 0;
510
105
}
511
512
unsigned MipsMCCodeEmitter::
513
getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
514
                       SmallVectorImpl<MCFixup> &Fixups,
515
37
                       const MCSubtargetInfo &STI) const {
516
37
  const MCOperand &MO = MI.getOperand(OpNo);
517
37
  // If the destination is an immediate, divide by 2.
518
37
  if (MO.isImm()) 
return MO.getImm() >> 19
;
519
28
520
28
  assert(MO.isExpr() &&
521
28
         "getJumpTargetOpValueMM expects only expressions or an immediate");
522
28
523
28
  const MCExpr *Expr = MO.getExpr();
524
28
  Fixups.push_back(MCFixup::create(0, Expr,
525
28
                                   MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
526
28
  return 0;
527
28
}
528
529
unsigned MipsMCCodeEmitter::
530
getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo,
531
                     SmallVectorImpl<MCFixup> &Fixups,
532
4
                     const MCSubtargetInfo &STI) const {
533
4
  const MCOperand &MO = MI.getOperand(OpNo);
534
4
  if (MO.isImm()) {
535
4
    // The immediate is encoded as 'immediate << 2'.
536
4
    unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
537
4
    assert((Res & 3) == 0);
538
4
    return Res >> 2;
539
4
  }
540
0
541
0
  assert(MO.isExpr() &&
542
0
         "getUImm5Lsl2Encoding expects only expressions or an immediate");
543
0
544
0
  return 0;
545
0
}
546
547
unsigned MipsMCCodeEmitter::
548
getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo,
549
                  SmallVectorImpl<MCFixup> &Fixups,
550
8
                  const MCSubtargetInfo &STI) const {
551
8
  const MCOperand &MO = MI.getOperand(OpNo);
552
8
  if (MO.isImm()) {
553
8
    int Value = MO.getImm();
554
8
    return Value >> 2;
555
8
  }
556
0
557
0
  return 0;
558
0
}
559
560
unsigned MipsMCCodeEmitter::
561
getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo,
562
                     SmallVectorImpl<MCFixup> &Fixups,
563
4
                     const MCSubtargetInfo &STI) const {
564
4
  const MCOperand &MO = MI.getOperand(OpNo);
565
4
  if (MO.isImm()) {
566
4
    unsigned Value = MO.getImm();
567
4
    return Value >> 2;
568
4
  }
569
0
570
0
  return 0;
571
0
}
572
573
unsigned MipsMCCodeEmitter::
574
getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
575
                     SmallVectorImpl<MCFixup> &Fixups,
576
26
                     const MCSubtargetInfo &STI) const {
577
26
  const MCOperand &MO = MI.getOperand(OpNo);
578
26
  if (MO.isImm()) {
579
26
    unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff;
580
26
    return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff));
581
26
  }
582
0
583
0
  return 0;
584
0
}
585
586
unsigned MipsMCCodeEmitter::
587
getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
588
11.7k
               const MCSubtargetInfo &STI) const {
589
11.7k
  int64_t Res;
590
11.7k
591
11.7k
  if (Expr->evaluateAsAbsolute(Res))
592
18
    return Res;
593
11.7k
594
11.7k
  MCExpr::ExprKind Kind = Expr->getKind();
595
11.7k
  if (Kind == MCExpr::Constant) {
596
0
    return cast<MCConstantExpr>(Expr)->getValue();
597
0
  }
598
11.7k
599
11.7k
  if (Kind == MCExpr::Binary) {
600
0
    unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
601
0
    Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
602
0
    return Res;
603
0
  }
604
11.7k
605
11.7k
  if (Kind == MCExpr::Target) {
606
11.7k
    const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
607
11.7k
608
11.7k
    Mips::Fixups FixupKind = Mips::Fixups(0);
609
11.7k
    switch (MipsExpr->getKind()) {
610
11.7k
    case MipsMCExpr::MEK_None:
611
0
    case MipsMCExpr::MEK_Special:
612
0
      llvm_unreachable("Unhandled fixup kind!");
613
0
      break;
614
0
    case MipsMCExpr::MEK_DTPREL:
615
0
      // MEK_DTPREL is used for marking TLS DIEExpr only
616
0
      // and contains a regular sub-expression.
617
0
      return getExprOpValue(MipsExpr->getSubExpr(), Fixups, STI);
618
8
    case MipsMCExpr::MEK_CALL_HI16:
619
8
      FixupKind = Mips::fixup_Mips_CALL_HI16;
620
8
      break;
621
8
    case MipsMCExpr::MEK_CALL_LO16:
622
8
      FixupKind = Mips::fixup_Mips_CALL_LO16;
623
8
      break;
624
10
    case MipsMCExpr::MEK_DTPREL_HI:
625
10
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_TLS_DTPREL_HI162
626
10
                                   : 
Mips::fixup_Mips_DTPREL_HI8
;
627
10
      break;
628
11
    case MipsMCExpr::MEK_DTPREL_LO:
629
11
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_TLS_DTPREL_LO162
630
11
                                   : 
Mips::fixup_Mips_DTPREL_LO9
;
631
11
      break;
632
19
    case MipsMCExpr::MEK_GOTTPREL:
633
19
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_GOTTPREL4
634
19
                                   : 
Mips::fixup_Mips_GOTTPREL15
;
635
19
      break;
636
213
    case MipsMCExpr::MEK_GOT:
637
213
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_GOT1639
638
213
                                   : 
Mips::fixup_Mips_GOT174
;
639
213
      break;
640
10.0k
    case MipsMCExpr::MEK_GOT_CALL:
641
10.0k
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_CALL1619
642
10.0k
                                   : 
Mips::fixup_Mips_CALL1610.0k
;
643
10.0k
      break;
644
52
    case MipsMCExpr::MEK_GOT_DISP:
645
52
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_GOT_DISP2
646
52
                                   : 
Mips::fixup_Mips_GOT_DISP50
;
647
52
      break;
648
10
    case MipsMCExpr::MEK_GOT_HI16:
649
10
      FixupKind = Mips::fixup_Mips_GOT_HI16;
650
10
      break;
651
10
    case MipsMCExpr::MEK_GOT_LO16:
652
10
      FixupKind = Mips::fixup_Mips_GOT_LO16;
653
10
      break;
654
38
    case MipsMCExpr::MEK_GOT_PAGE:
655
38
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_GOT_PAGE6
656
38
                                   : 
Mips::fixup_Mips_GOT_PAGE32
;
657
38
      break;
658
28
    case MipsMCExpr::MEK_GOT_OFST:
659
28
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_GOT_OFST6
660
28
                                   : 
Mips::fixup_Mips_GOT_OFST22
;
661
28
      break;
662
12
    case MipsMCExpr::MEK_GPREL:
663
12
      FixupKind = Mips::fixup_Mips_GPREL16;
664
12
      break;
665
752
    case MipsMCExpr::MEK_LO:
666
752
      // Check for %lo(%neg(%gp_rel(X)))
667
752
      if (MipsExpr->isGpOff())
668
38
        FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_GPOFF_LO8
669
38
                                     : 
Mips::fixup_Mips_GPOFF_LO30
;
670
714
      else
671
714
        FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_LO1679
672
714
                                     : 
Mips::fixup_Mips_LO16635
;
673
752
      break;
674
56
    case MipsMCExpr::MEK_HIGHEST:
675
56
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_HIGHEST4
676
56
                                   : 
Mips::fixup_Mips_HIGHEST52
;
677
56
      break;
678
56
    case MipsMCExpr::MEK_HIGHER:
679
56
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_HIGHER4
680
56
                                   : 
Mips::fixup_Mips_HIGHER52
;
681
56
      break;
682
340
    case MipsMCExpr::MEK_HI:
683
340
      // Check for %hi(%neg(%gp_rel(X)))
684
340
      if (MipsExpr->isGpOff())
685
40
        FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_GPOFF_HI8
686
40
                                     : 
Mips::fixup_Mips_GPOFF_HI32
;
687
300
      else
688
300
        FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_HI1649
689
300
                                     : 
Mips::fixup_Mips_HI16251
;
690
340
      break;
691
13
    case MipsMCExpr::MEK_PCREL_HI16:
692
13
      FixupKind = Mips::fixup_MIPS_PCHI16;
693
13
      break;
694
13
    case MipsMCExpr::MEK_PCREL_LO16:
695
13
      FixupKind = Mips::fixup_MIPS_PCLO16;
696
13
      break;
697
18
    case MipsMCExpr::MEK_TLSGD:
698
18
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_TLS_GD2
699
18
                                   : 
Mips::fixup_Mips_TLSGD16
;
700
18
      break;
701
11
    case MipsMCExpr::MEK_TLSLDM:
702
11
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_TLS_LDM2
703
11
                                   : 
Mips::fixup_Mips_TLSLDM9
;
704
11
      break;
705
9
    case MipsMCExpr::MEK_TPREL_HI:
706
9
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_TLS_TPREL_HI162
707
9
                                   : 
Mips::fixup_Mips_TPREL_HI7
;
708
9
      break;
709
9
    case MipsMCExpr::MEK_TPREL_LO:
710
9
      FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_TLS_TPREL_LO162
711
9
                                   : 
Mips::fixup_Mips_TPREL_LO7
;
712
9
      break;
713
0
    case MipsMCExpr::MEK_NEG:
714
0
      FixupKind =
715
0
          isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB;
716
0
      break;
717
11.7k
    }
718
11.7k
    Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind)));
719
11.7k
    return 0;
720
11.7k
  }
721
0
722
0
  if (Kind == MCExpr::SymbolRef) {
723
0
    Mips::Fixups FixupKind = Mips::Fixups(0);
724
0
725
0
    switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
726
0
    default: llvm_unreachable("Unknown fixup kind!");
727
0
      break;
728
0
    case MCSymbolRefExpr::VK_None:
729
0
      FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64.
730
0
      break;
731
0
    } // switch
732
0
733
0
    Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
734
0
    return 0;
735
0
  }
736
0
  return 0;
737
0
}
738
739
/// getMachineOpValue - Return binary encoding of operand. If the machine
740
/// operand requires relocation, record the relocation and return zero.
741
unsigned MipsMCCodeEmitter::
742
getMachineOpValue(const MCInst &MI, const MCOperand &MO,
743
                  SmallVectorImpl<MCFixup> &Fixups,
744
120k
                  const MCSubtargetInfo &STI) const {
745
120k
  if (MO.isReg()) {
746
85.5k
    unsigned Reg = MO.getReg();
747
85.5k
    unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
748
85.5k
    return RegNo;
749
85.5k
  } else 
if (34.8k
MO.isImm()34.8k
) {
750
23.0k
    return static_cast<unsigned>(MO.getImm());
751
23.0k
  } else 
if (11.7k
MO.isFPImm()11.7k
) {
752
0
    return static_cast<unsigned>(APFloat(MO.getFPImm())
753
0
        .bitcastToAPInt().getHiBits(32).getLimitedValue());
754
0
  }
755
11.7k
  // MO must be an Expr.
756
11.7k
  assert(MO.isExpr());
757
11.7k
  return getExprOpValue(MO.getExpr(),Fixups, STI);
758
11.7k
}
759
760
/// Return binary encoding of memory related operand.
761
/// If the offset operand requires relocation, record the relocation.
762
template <unsigned ShiftAmount>
763
unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
764
                                           SmallVectorImpl<MCFixup> &Fixups,
765
12.7k
                                           const MCSubtargetInfo &STI) const {
766
12.7k
  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
767
12.7k
  assert(MI.getOperand(OpNo).isReg());
768
12.7k
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
769
12.7k
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
770
12.7k
771
12.7k
  // Apply the scale factor if there is one.
772
12.7k
  OffBits >>= ShiftAmount;
773
12.7k
774
12.7k
  return (OffBits & 0xFFFF) | RegBits;
775
12.7k
}
unsigned int llvm::MipsMCCodeEmitter::getMemEncoding<0u>(llvm::MCInst const&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const
Line
Count
Source
765
12.6k
                                           const MCSubtargetInfo &STI) const {
766
12.6k
  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
767
12.6k
  assert(MI.getOperand(OpNo).isReg());
768
12.6k
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
769
12.6k
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
770
12.6k
771
12.6k
  // Apply the scale factor if there is one.
772
12.6k
  OffBits >>= ShiftAmount;
773
12.6k
774
12.6k
  return (OffBits & 0xFFFF) | RegBits;
775
12.6k
}
unsigned int llvm::MipsMCCodeEmitter::getMemEncoding<1u>(llvm::MCInst const&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const
Line
Count
Source
765
5
                                           const MCSubtargetInfo &STI) const {
766
5
  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
767
5
  assert(MI.getOperand(OpNo).isReg());
768
5
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
769
5
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
770
5
771
5
  // Apply the scale factor if there is one.
772
5
  OffBits >>= ShiftAmount;
773
5
774
5
  return (OffBits & 0xFFFF) | RegBits;
775
5
}
unsigned int llvm::MipsMCCodeEmitter::getMemEncoding<2u>(llvm::MCInst const&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const
Line
Count
Source
765
6
                                           const MCSubtargetInfo &STI) const {
766
6
  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
767
6
  assert(MI.getOperand(OpNo).isReg());
768
6
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
769
6
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
770
6
771
6
  // Apply the scale factor if there is one.
772
6
  OffBits >>= ShiftAmount;
773
6
774
6
  return (OffBits & 0xFFFF) | RegBits;
775
6
}
unsigned int llvm::MipsMCCodeEmitter::getMemEncoding<3u>(llvm::MCInst const&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const
Line
Count
Source
765
9
                                           const MCSubtargetInfo &STI) const {
766
9
  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
767
9
  assert(MI.getOperand(OpNo).isReg());
768
9
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
769
9
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
770
9
771
9
  // Apply the scale factor if there is one.
772
9
  OffBits >>= ShiftAmount;
773
9
774
9
  return (OffBits & 0xFFFF) | RegBits;
775
9
}
776
777
unsigned MipsMCCodeEmitter::
778
getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo,
779
                     SmallVectorImpl<MCFixup> &Fixups,
780
12
                     const MCSubtargetInfo &STI) const {
781
12
  // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
782
12
  assert(MI.getOperand(OpNo).isReg());
783
12
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
784
12
                                       Fixups, STI) << 4;
785
12
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
786
12
                                       Fixups, STI);
787
12
788
12
  return (OffBits & 0xF) | RegBits;
789
12
}
790
791
unsigned MipsMCCodeEmitter::
792
getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo,
793
                         SmallVectorImpl<MCFixup> &Fixups,
794
8
                         const MCSubtargetInfo &STI) const {
795
8
  // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
796
8
  assert(MI.getOperand(OpNo).isReg());
797
8
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
798
8
                                       Fixups, STI) << 4;
799
8
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
800
8
                                       Fixups, STI) >> 1;
801
8
802
8
  return (OffBits & 0xF) | RegBits;
803
8
}
804
805
unsigned MipsMCCodeEmitter::
806
getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo,
807
                         SmallVectorImpl<MCFixup> &Fixups,
808
18
                         const MCSubtargetInfo &STI) const {
809
18
  // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
810
18
  assert(MI.getOperand(OpNo).isReg());
811
18
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
812
18
                                       Fixups, STI) << 4;
813
18
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
814
18
                                       Fixups, STI) >> 2;
815
18
816
18
  return (OffBits & 0xF) | RegBits;
817
18
}
818
819
unsigned MipsMCCodeEmitter::
820
getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
821
                           SmallVectorImpl<MCFixup> &Fixups,
822
23
                           const MCSubtargetInfo &STI) const {
823
23
  // Register is encoded in bits 9-5, offset is encoded in bits 4-0.
824
23
  assert(MI.getOperand(OpNo).isReg() &&
825
23
         (MI.getOperand(OpNo).getReg() == Mips::SP ||
826
23
         MI.getOperand(OpNo).getReg() == Mips::SP_64) &&
827
23
         "Unexpected base register!");
828
23
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
829
23
                                       Fixups, STI) >> 2;
830
23
831
23
  return OffBits & 0x1F;
832
23
}
833
834
unsigned MipsMCCodeEmitter::
835
getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
836
                           SmallVectorImpl<MCFixup> &Fixups,
837
6
                           const MCSubtargetInfo &STI) const {
838
6
  // Register is encoded in bits 9-7, offset is encoded in bits 6-0.
839
6
  assert(MI.getOperand(OpNo).isReg() &&
840
6
         MI.getOperand(OpNo).getReg() == Mips::GP &&
841
6
         "Unexpected base register!");
842
6
843
6
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
844
6
                                       Fixups, STI) >> 2;
845
6
846
6
  return OffBits & 0x7F;
847
6
}
848
849
unsigned MipsMCCodeEmitter::
850
getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo,
851
                     SmallVectorImpl<MCFixup> &Fixups,
852
30
                     const MCSubtargetInfo &STI) const {
853
30
  // Base register is encoded in bits 20-16, offset is encoded in bits 8-0.
854
30
  assert(MI.getOperand(OpNo).isReg());
855
30
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
856
30
                                       STI) << 16;
857
30
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI);
858
30
859
30
  return (OffBits & 0x1FF) | RegBits;
860
30
}
861
862
unsigned MipsMCCodeEmitter::
863
getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo,
864
                      SmallVectorImpl<MCFixup> &Fixups,
865
4
                      const MCSubtargetInfo &STI) const {
866
4
  // Base register is encoded in bits 20-16, offset is encoded in bits 10-0.
867
4
  assert(MI.getOperand(OpNo).isReg());
868
4
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
869
4
                                       STI) << 16;
870
4
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
871
4
872
4
  return (OffBits & 0x07FF) | RegBits;
873
4
}
874
875
unsigned MipsMCCodeEmitter::
876
getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
877
                      SmallVectorImpl<MCFixup> &Fixups,
878
79
                      const MCSubtargetInfo &STI) const {
879
79
  // opNum can be invalid if instruction had reglist as operand.
880
79
  // MemOperand is always last operand of instruction (base + offset).
881
79
  switch (MI.getOpcode()) {
882
79
  default:
883
34
    break;
884
79
  case Mips::SWM32_MM:
885
45
  case Mips::LWM32_MM:
886
45
    OpNo = MI.getNumOperands() - 2;
887
45
    break;
888
79
  }
889
79
890
79
  // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
891
79
  assert(MI.getOperand(OpNo).isReg());
892
79
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
893
79
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
894
79
895
79
  return (OffBits & 0x0FFF) | RegBits;
896
79
}
897
898
unsigned MipsMCCodeEmitter::
899
getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo,
900
                      SmallVectorImpl<MCFixup> &Fixups,
901
40
                      const MCSubtargetInfo &STI) const {
902
40
  // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
903
40
  assert(MI.getOperand(OpNo).isReg());
904
40
  unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
905
40
                                       STI) << 16;
906
40
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
907
40
908
40
  return (OffBits & 0xFFFF) | RegBits;
909
40
}
910
911
unsigned MipsMCCodeEmitter::
912
getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
913
                       SmallVectorImpl<MCFixup> &Fixups,
914
14
                       const MCSubtargetInfo &STI) const {
915
14
  // opNum can be invalid if instruction had reglist as operand
916
14
  // MemOperand is always last operand of instruction (base + offset)
917
14
  switch (MI.getOpcode()) {
918
14
  default:
919
0
    break;
920
14
  case Mips::SWM16_MM:
921
14
  case Mips::SWM16_MMR6:
922
14
  case Mips::LWM16_MM:
923
14
  case Mips::LWM16_MMR6:
924
14
    OpNo = MI.getNumOperands() - 2;
925
14
    break;
926
14
  }
927
14
928
14
  // Offset is encoded in bits 4-0.
929
14
  assert(MI.getOperand(OpNo).isReg());
930
14
  // Base register is always SP - thus it is not encoded.
931
14
  assert(MI.getOperand(OpNo+1).isImm());
932
14
  unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
933
14
934
14
  return ((OffBits >> 2) & 0x0F);
935
14
}
936
937
// FIXME: should be called getMSBEncoding
938
//
939
unsigned
940
MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
941
                                      SmallVectorImpl<MCFixup> &Fixups,
942
19
                                      const MCSubtargetInfo &STI) const {
943
19
  assert(MI.getOperand(OpNo-1).isImm());
944
19
  assert(MI.getOperand(OpNo).isImm());
945
19
  unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI);
946
19
  unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
947
19
948
19
  return Position + Size - 1;
949
19
}
950
951
template <unsigned Bits, int Offset>
952
unsigned
953
MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo,
954
                                             SmallVectorImpl<MCFixup> &Fixups,
955
30
                                             const MCSubtargetInfo &STI) const {
956
30
  assert(MI.getOperand(OpNo).isImm());
957
30
  unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
958
30
  Value -= Offset;
959
30
  return Value;
960
30
}
unsigned int llvm::MipsMCCodeEmitter::getUImmWithOffsetEncoding<2u, 1>(llvm::MCInst const&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const
Line
Count
Source
955
12
                                             const MCSubtargetInfo &STI) const {
956
12
  assert(MI.getOperand(OpNo).isImm());
957
12
  unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
958
12
  Value -= Offset;
959
12
  return Value;
960
12
}
unsigned int llvm::MipsMCCodeEmitter::getUImmWithOffsetEncoding<5u, 1>(llvm::MCInst const&, unsigned int, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const
Line
Count
Source
955
18
                                             const MCSubtargetInfo &STI) const {
956
18
  assert(MI.getOperand(OpNo).isImm());
957
18
  unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
958
18
  Value -= Offset;
959
18
  return Value;
960
18
}
961
962
unsigned
963
MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
964
                                         SmallVectorImpl<MCFixup> &Fixups,
965
56
                                         const MCSubtargetInfo &STI) const {
966
56
  const MCOperand &MO = MI.getOperand(OpNo);
967
56
  if (MO.isImm()) {
968
17
    // The immediate is encoded as 'immediate << 2'.
969
17
    unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
970
17
    assert((Res & 3) == 0);
971
17
    return Res >> 2;
972
17
  }
973
39
974
39
  assert(MO.isExpr() &&
975
39
         "getSimm19Lsl2Encoding expects only expressions or an immediate");
976
39
977
39
  const MCExpr *Expr = MO.getExpr();
978
39
  Mips::Fixups FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_PC19_S216
979
39
                                            : 
Mips::fixup_MIPS_PC19_S223
;
980
39
  Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
981
39
  return 0;
982
39
}
983
984
unsigned
985
MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
986
                                         SmallVectorImpl<MCFixup> &Fixups,
987
9
                                         const MCSubtargetInfo &STI) const {
988
9
  const MCOperand &MO = MI.getOperand(OpNo);
989
9
  if (MO.isImm()) {
990
1
    // The immediate is encoded as 'immediate << 3'.
991
1
    unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
992
1
    assert((Res & 7) == 0);
993
1
    return Res >> 3;
994
1
  }
995
8
996
8
  assert(MO.isExpr() &&
997
8
         "getSimm18Lsl2Encoding expects only expressions or an immediate");
998
8
999
8
  const MCExpr *Expr = MO.getExpr();
1000
8
  Mips::Fixups FixupKind = isMicroMips(STI) ? 
Mips::fixup_MICROMIPS_PC18_S30
1001
8
                                            : Mips::fixup_MIPS_PC18_S3;
1002
8
  Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
1003
8
  return 0;
1004
8
}
1005
1006
unsigned
1007
MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
1008
                                        SmallVectorImpl<MCFixup> &Fixups,
1009
8
                                        const MCSubtargetInfo &STI) const {
1010
8
  assert(MI.getOperand(OpNo).isImm());
1011
8
  const MCOperand &MO = MI.getOperand(OpNo);
1012
8
  return MO.getImm() % 8;
1013
8
}
1014
1015
unsigned
1016
MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo,
1017
                                    SmallVectorImpl<MCFixup> &Fixups,
1018
5
                                    const MCSubtargetInfo &STI) const {
1019
5
  assert(MI.getOperand(OpNo).isImm());
1020
5
  const MCOperand &MO = MI.getOperand(OpNo);
1021
5
  unsigned Value = MO.getImm();
1022
5
  switch (Value) {
1023
5
    
case 128: return 0x00
;
1024
5
    
case 1: return 0x11
;
1025
5
    
case 2: return 0x20
;
1026
5
    
case 3: return 0x30
;
1027
5
    
case 4: return 0x40
;
1028
5
    
case 7: return 0x50
;
1029
5
    
case 8: return 0x61
;
1030
5
    
case 15: return 0x70
;
1031
5
    
case 16: return 0x80
;
1032
5
    
case 31: return 0x93
;
1033
5
    
case 32: return 0xa0
;
1034
5
    
case 63: return 0xb0
;
1035
5
    
case 64: return 0xc0
;
1036
5
    
case 255: return 0xd0
;
1037
5
    
case 32768: return 0xe0
;
1038
5
    
case 65535: return 0xf0
;
1039
0
  }
1040
0
  llvm_unreachable("Unexpected value");
1041
0
}
1042
1043
unsigned
1044
MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo,
1045
                                          SmallVectorImpl<MCFixup> &Fixups,
1046
45
                                          const MCSubtargetInfo &STI) const {
1047
45
  unsigned res = 0;
1048
45
1049
45
  // Register list operand is always first operand of instruction and it is
1050
45
  // placed before memory operand (register + imm).
1051
45
1052
244
  for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; 
++I199
) {
1053
199
    unsigned Reg = MI.getOperand(I).getReg();
1054
199
    unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
1055
199
    if (RegNo != 31)
1056
178
      res++;
1057
21
    else
1058
21
      res |= 0x10;
1059
199
  }
1060
45
  return res;
1061
45
}
1062
1063
unsigned
1064
MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
1065
                                            SmallVectorImpl<MCFixup> &Fixups,
1066
14
                                            const MCSubtargetInfo &STI) const {
1067
14
  return (MI.getNumOperands() - 4);
1068
14
}
1069
1070
unsigned
1071
MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
1072
                                          SmallVectorImpl<MCFixup> &Fixups,
1073
4
                                          const MCSubtargetInfo &STI) const {
1074
4
  unsigned res = 0;
1075
4
1076
4
  if (MI.getOperand(0).getReg() == Mips::A1 &&
1077
4
      MI.getOperand(1).getReg() == Mips::A2)
1078
4
    res = 0;
1079
0
  else if (MI.getOperand(0).getReg() == Mips::A1 &&
1080
0
           MI.getOperand(1).getReg() == Mips::A3)
1081
0
    res = 1;
1082
0
  else if (MI.getOperand(0).getReg() == Mips::A2 &&
1083
0
           MI.getOperand(1).getReg() == Mips::A3)
1084
0
    res = 2;
1085
0
  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1086
0
           MI.getOperand(1).getReg() == Mips::S5)
1087
0
    res = 3;
1088
0
  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1089
0
           MI.getOperand(1).getReg() == Mips::S6)
1090
0
    res = 4;
1091
0
  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1092
0
           MI.getOperand(1).getReg() == Mips::A1)
1093
0
    res = 5;
1094
0
  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1095
0
           MI.getOperand(1).getReg() == Mips::A2)
1096
0
    res = 6;
1097
0
  else if (MI.getOperand(0).getReg() == Mips::A0 &&
1098
0
           MI.getOperand(1).getReg() == Mips::A3)
1099
0
    res = 7;
1100
4
1101
4
  return res;
1102
4
}
1103
1104
unsigned
1105
MipsMCCodeEmitter::getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo,
1106
                                            SmallVectorImpl<MCFixup> &Fixups,
1107
8
                                            const MCSubtargetInfo &STI) const {
1108
8
  assert(((OpNo == 2) || (OpNo == 3)) &&
1109
8
         "Unexpected OpNo for movep operand encoding!");
1110
8
1111
8
  MCOperand Op = MI.getOperand(OpNo);
1112
8
  assert(Op.isReg() && "Operand of movep is not a register!");
1113
8
  switch (Op.getReg()) {
1114
8
  default:
1115
0
    llvm_unreachable("Unknown register for movep!");
1116
8
  
case Mips::ZERO: return 00
;
1117
8
  
case Mips::S1: return 10
;
1118
8
  
case Mips::V0: return 24
;
1119
8
  
case Mips::V1: return 34
;
1120
8
  
case Mips::S0: return 40
;
1121
8
  
case Mips::S2: return 50
;
1122
8
  
case Mips::S3: return 60
;
1123
8
  
case Mips::S4: return 70
;
1124
8
  }
1125
8
}
1126
1127
unsigned
1128
MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
1129
                                         SmallVectorImpl<MCFixup> &Fixups,
1130
9
                                         const MCSubtargetInfo &STI) const {
1131
9
  const MCOperand &MO = MI.getOperand(OpNo);
1132
9
  assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate");
1133
9
  // The immediate is encoded as 'immediate >> 2'.
1134
9
  unsigned Res = static_cast<unsigned>(MO.getImm());
1135
9
  assert((Res & 3) == 0);
1136
9
  return Res >> 2;
1137
9
}
1138
1139
#include "MipsGenMCCodeEmitter.inc"