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