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