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