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