xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp (revision f078c492a9b57877c723586db26d789cda1b98ea)
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   const 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       TmpInst.setOpcode (NewOpcode);
212       Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
213     }
214 
215     if (((MI.getOpcode() == Mips::MOVEP_MM) ||
216          (MI.getOpcode() == Mips::MOVEP_MMR6))) {
217       unsigned RegPair = getMovePRegPairOpValue(MI, 0, Fixups, STI);
218       Binary = (Binary & 0xFFFFFC7F) | (RegPair << 7);
219     }
220   }
221 
222   const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
223 
224   // Get byte count of instruction
225   unsigned Size = Desc.getSize();
226   if (!Size)
227     llvm_unreachable("Desc.getSize() returns 0");
228 
229   emitInstruction(Binary, Size, STI, OS);
230 }
231 
232 /// getBranchTargetOpValue - Return binary encoding of the branch
233 /// target operand. If the machine operand requires relocation,
234 /// record the relocation and return zero.
235 unsigned MipsMCCodeEmitter::
236 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
237                        SmallVectorImpl<MCFixup> &Fixups,
238                        const MCSubtargetInfo &STI) const {
239   const MCOperand &MO = MI.getOperand(OpNo);
240 
241   // If the destination is an immediate, divide by 4.
242   if (MO.isImm()) return MO.getImm() >> 2;
243 
244   assert(MO.isExpr() &&
245          "getBranchTargetOpValue expects only expressions or immediates");
246 
247   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
248       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
249   Fixups.push_back(MCFixup::create(0, FixupExpression,
250                                    MCFixupKind(Mips::fixup_Mips_PC16)));
251   return 0;
252 }
253 
254 /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch
255 /// target operand. If the machine operand requires relocation,
256 /// record the relocation and return zero.
257 unsigned MipsMCCodeEmitter::
258 getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo,
259                               SmallVectorImpl<MCFixup> &Fixups,
260                               const MCSubtargetInfo &STI) const {
261   const MCOperand &MO = MI.getOperand(OpNo);
262 
263   // If the destination is an immediate, divide by 2.
264   if (MO.isImm()) return MO.getImm() >> 1;
265 
266   assert(MO.isExpr() &&
267          "getBranchTargetOpValue expects only expressions or immediates");
268 
269   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
270       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
271   Fixups.push_back(MCFixup::create(0, FixupExpression,
272                                    MCFixupKind(Mips::fixup_Mips_PC16)));
273   return 0;
274 }
275 
276 /// getBranchTargetOpValueMMR6 - Return binary encoding of the branch
277 /// target operand. If the machine operand requires relocation,
278 /// record the relocation and return zero.
279 unsigned MipsMCCodeEmitter::
280 getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo,
281                            SmallVectorImpl<MCFixup> &Fixups,
282                            const MCSubtargetInfo &STI) const {
283   const MCOperand &MO = MI.getOperand(OpNo);
284 
285   // If the destination is an immediate, divide by 2.
286   if (MO.isImm())
287     return MO.getImm() >> 1;
288 
289   assert(MO.isExpr() &&
290          "getBranchTargetOpValueMMR6 expects only expressions or immediates");
291 
292   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
293       MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx);
294   Fixups.push_back(MCFixup::create(0, FixupExpression,
295                                    MCFixupKind(Mips::fixup_Mips_PC16)));
296   return 0;
297 }
298 
299 /// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch
300 /// target operand. If the machine operand requires relocation,
301 /// record the relocation and return zero.
302 unsigned MipsMCCodeEmitter::
303 getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo,
304                                SmallVectorImpl<MCFixup> &Fixups,
305                                const MCSubtargetInfo &STI) const {
306   const MCOperand &MO = MI.getOperand(OpNo);
307 
308   // If the destination is an immediate, divide by 4.
309   if (MO.isImm())
310     return MO.getImm() >> 2;
311 
312   assert(MO.isExpr() &&
313          "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates");
314 
315   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
316       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
317   Fixups.push_back(MCFixup::create(0, FixupExpression,
318                                    MCFixupKind(Mips::fixup_Mips_PC16)));
319   return 0;
320 }
321 
322 /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch
323 /// target operand. If the machine operand requires relocation,
324 /// record the relocation and return zero.
325 unsigned MipsMCCodeEmitter::
326 getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo,
327                           SmallVectorImpl<MCFixup> &Fixups,
328                           const MCSubtargetInfo &STI) const {
329   const MCOperand &MO = MI.getOperand(OpNo);
330 
331   // If the destination is an immediate, divide by 2.
332   if (MO.isImm()) return MO.getImm() >> 1;
333 
334   assert(MO.isExpr() &&
335          "getBranchTargetOpValueMM expects only expressions or immediates");
336 
337   const MCExpr *Expr = MO.getExpr();
338   Fixups.push_back(MCFixup::create(0, Expr,
339                                    MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1)));
340   return 0;
341 }
342 
343 /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS
344 /// 10-bit branch target operand. If the machine operand requires relocation,
345 /// record the relocation and return zero.
346 unsigned MipsMCCodeEmitter::
347 getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo,
348                              SmallVectorImpl<MCFixup> &Fixups,
349                              const MCSubtargetInfo &STI) const {
350   const MCOperand &MO = MI.getOperand(OpNo);
351 
352   // If the destination is an immediate, divide by 2.
353   if (MO.isImm()) return MO.getImm() >> 1;
354 
355   assert(MO.isExpr() &&
356          "getBranchTargetOpValuePC10 expects only expressions or immediates");
357 
358   const MCExpr *Expr = MO.getExpr();
359   Fixups.push_back(MCFixup::create(0, Expr,
360                    MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1)));
361   return 0;
362 }
363 
364 /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
365 /// target operand. If the machine operand requires relocation,
366 /// record the relocation and return zero.
367 unsigned MipsMCCodeEmitter::
368 getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
369                          SmallVectorImpl<MCFixup> &Fixups,
370                          const MCSubtargetInfo &STI) const {
371   const MCOperand &MO = MI.getOperand(OpNo);
372 
373   // If the destination is an immediate, divide by 2.
374   if (MO.isImm()) return MO.getImm() >> 1;
375 
376   assert(MO.isExpr() &&
377          "getBranchTargetOpValueMM expects only expressions or immediates");
378 
379   const MCExpr *Expr = MO.getExpr();
380   Fixups.push_back(MCFixup::create(0, Expr,
381                    MCFixupKind(Mips::
382                                fixup_MICROMIPS_PC16_S1)));
383   return 0;
384 }
385 
386 /// getBranchTarget21OpValue - Return binary encoding of the branch
387 /// target operand. If the machine operand requires relocation,
388 /// record the relocation and return zero.
389 unsigned MipsMCCodeEmitter::
390 getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
391                          SmallVectorImpl<MCFixup> &Fixups,
392                          const MCSubtargetInfo &STI) const {
393   const MCOperand &MO = MI.getOperand(OpNo);
394 
395   // If the destination is an immediate, divide by 4.
396   if (MO.isImm()) return MO.getImm() >> 2;
397 
398   assert(MO.isExpr() &&
399          "getBranchTarget21OpValue expects only expressions or immediates");
400 
401   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
402       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
403   Fixups.push_back(MCFixup::create(0, FixupExpression,
404                                    MCFixupKind(Mips::fixup_MIPS_PC21_S2)));
405   return 0;
406 }
407 
408 /// getBranchTarget21OpValueMM - Return binary encoding of the branch
409 /// target operand for microMIPS. If the machine operand requires
410 /// relocation, record the relocation and return zero.
411 unsigned MipsMCCodeEmitter::
412 getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo,
413                            SmallVectorImpl<MCFixup> &Fixups,
414                            const MCSubtargetInfo &STI) const {
415   const MCOperand &MO = MI.getOperand(OpNo);
416 
417   // If the destination is an immediate, divide by 4.
418   if (MO.isImm()) return MO.getImm() >> 2;
419 
420   assert(MO.isExpr() &&
421     "getBranchTarget21OpValueMM expects only expressions or immediates");
422 
423   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
424       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
425   Fixups.push_back(MCFixup::create(0, FixupExpression,
426                                    MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1)));
427   return 0;
428 }
429 
430 /// getBranchTarget26OpValue - Return binary encoding of the branch
431 /// target operand. If the machine operand requires relocation,
432 /// record the relocation and return zero.
433 unsigned MipsMCCodeEmitter::
434 getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
435                          SmallVectorImpl<MCFixup> &Fixups,
436                          const MCSubtargetInfo &STI) const {
437   const MCOperand &MO = MI.getOperand(OpNo);
438 
439   // If the destination is an immediate, divide by 4.
440   if (MO.isImm()) return MO.getImm() >> 2;
441 
442   assert(MO.isExpr() &&
443          "getBranchTarget26OpValue expects only expressions or immediates");
444 
445   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
446       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
447   Fixups.push_back(MCFixup::create(0, FixupExpression,
448                                    MCFixupKind(Mips::fixup_MIPS_PC26_S2)));
449   return 0;
450 }
451 
452 /// getBranchTarget26OpValueMM - Return binary encoding of the branch
453 /// target operand. If the machine operand requires relocation,
454 /// record the relocation and return zero.
455 unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM(
456     const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
457     const MCSubtargetInfo &STI) const {
458   const MCOperand &MO = MI.getOperand(OpNo);
459 
460   // If the destination is an immediate, divide by 2.
461   if (MO.isImm())
462     return MO.getImm() >> 1;
463 
464   assert(MO.isExpr() &&
465          "getBranchTarget26OpValueMM expects only expressions or immediates");
466 
467   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
468       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
469   Fixups.push_back(MCFixup::create(0, FixupExpression,
470                                    MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1)));
471   return 0;
472 }
473 
474 /// getJumpOffset16OpValue - Return binary encoding of the jump
475 /// target operand. If the machine operand requires relocation,
476 /// record the relocation and return zero.
477 unsigned MipsMCCodeEmitter::
478 getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo,
479                        SmallVectorImpl<MCFixup> &Fixups,
480                        const MCSubtargetInfo &STI) const {
481   const MCOperand &MO = MI.getOperand(OpNo);
482 
483   if (MO.isImm()) return MO.getImm();
484 
485   assert(MO.isExpr() &&
486          "getJumpOffset16OpValue expects only expressions or an immediate");
487 
488   const MCExpr *Expr = MO.getExpr();
489   Mips::Fixups FixupKind =
490       isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16 : Mips::fixup_Mips_LO16;
491   Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
492   return 0;
493 }
494 
495 /// getJumpTargetOpValue - Return binary encoding of the jump
496 /// target operand. If the machine operand requires relocation,
497 /// record the relocation and return zero.
498 unsigned MipsMCCodeEmitter::
499 getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
500                      SmallVectorImpl<MCFixup> &Fixups,
501                      const MCSubtargetInfo &STI) const {
502   const MCOperand &MO = MI.getOperand(OpNo);
503   // If the destination is an immediate, divide by 4.
504   if (MO.isImm()) return MO.getImm()>>2;
505 
506   assert(MO.isExpr() &&
507          "getJumpTargetOpValue expects only expressions or an immediate");
508 
509   const MCExpr *Expr = MO.getExpr();
510   Fixups.push_back(MCFixup::create(0, Expr,
511                                    MCFixupKind(Mips::fixup_Mips_26)));
512   return 0;
513 }
514 
515 unsigned MipsMCCodeEmitter::
516 getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
517                        SmallVectorImpl<MCFixup> &Fixups,
518                        const MCSubtargetInfo &STI) const {
519   const MCOperand &MO = MI.getOperand(OpNo);
520   // If the destination is an immediate, divide by 2.
521   if (MO.isImm()) return MO.getImm() >> 1;
522 
523   assert(MO.isExpr() &&
524          "getJumpTargetOpValueMM expects only expressions or an immediate");
525 
526   const MCExpr *Expr = MO.getExpr();
527   Fixups.push_back(MCFixup::create(0, Expr,
528                                    MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
529   return 0;
530 }
531 
532 unsigned MipsMCCodeEmitter::
533 getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo,
534                      SmallVectorImpl<MCFixup> &Fixups,
535                      const MCSubtargetInfo &STI) const {
536   const MCOperand &MO = MI.getOperand(OpNo);
537   if (MO.isImm()) {
538     // The immediate is encoded as 'immediate << 2'.
539     unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
540     assert((Res & 3) == 0);
541     return Res >> 2;
542   }
543 
544   assert(MO.isExpr() &&
545          "getUImm5Lsl2Encoding expects only expressions or an immediate");
546 
547   return 0;
548 }
549 
550 unsigned MipsMCCodeEmitter::
551 getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo,
552                   SmallVectorImpl<MCFixup> &Fixups,
553                   const MCSubtargetInfo &STI) const {
554   const MCOperand &MO = MI.getOperand(OpNo);
555   if (MO.isImm()) {
556     int Value = MO.getImm();
557     return Value >> 2;
558   }
559 
560   return 0;
561 }
562 
563 unsigned MipsMCCodeEmitter::
564 getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo,
565                      SmallVectorImpl<MCFixup> &Fixups,
566                      const MCSubtargetInfo &STI) const {
567   const MCOperand &MO = MI.getOperand(OpNo);
568   if (MO.isImm()) {
569     unsigned Value = MO.getImm();
570     return Value >> 2;
571   }
572 
573   return 0;
574 }
575 
576 unsigned MipsMCCodeEmitter::
577 getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
578                      SmallVectorImpl<MCFixup> &Fixups,
579                      const MCSubtargetInfo &STI) const {
580   const MCOperand &MO = MI.getOperand(OpNo);
581   if (MO.isImm()) {
582     unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff;
583     return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff));
584   }
585 
586   return 0;
587 }
588 
589 unsigned MipsMCCodeEmitter::
590 getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
591                const MCSubtargetInfo &STI) const {
592   int64_t Res;
593 
594   if (Expr->evaluateAsAbsolute(Res))
595     return Res;
596 
597   MCExpr::ExprKind Kind = Expr->getKind();
598   if (Kind == MCExpr::Constant) {
599     return cast<MCConstantExpr>(Expr)->getValue();
600   }
601 
602   if (Kind == MCExpr::Binary) {
603     unsigned Res =
604         getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
605     Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
606     return Res;
607   }
608 
609   if (Kind == MCExpr::Target) {
610     const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
611 
612     Mips::Fixups FixupKind = Mips::Fixups(0);
613     switch (MipsExpr->getKind()) {
614     case MipsMCExpr::MEK_None:
615     case MipsMCExpr::MEK_Special:
616       llvm_unreachable("Unhandled fixup kind!");
617       break;
618     case MipsMCExpr::MEK_DTPREL:
619       // MEK_DTPREL is used for marking TLS DIEExpr only
620       // and contains a regular sub-expression.
621       return getExprOpValue(MipsExpr->getSubExpr(), Fixups, STI);
622     case MipsMCExpr::MEK_CALL_HI16:
623       FixupKind = Mips::fixup_Mips_CALL_HI16;
624       break;
625     case MipsMCExpr::MEK_CALL_LO16:
626       FixupKind = Mips::fixup_Mips_CALL_LO16;
627       break;
628     case MipsMCExpr::MEK_DTPREL_HI:
629       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
630                                    : Mips::fixup_Mips_DTPREL_HI;
631       break;
632     case MipsMCExpr::MEK_DTPREL_LO:
633       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
634                                    : Mips::fixup_Mips_DTPREL_LO;
635       break;
636     case MipsMCExpr::MEK_GOTTPREL:
637       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOTTPREL
638                                    : Mips::fixup_Mips_GOTTPREL;
639       break;
640     case MipsMCExpr::MEK_GOT:
641       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
642                                    : Mips::fixup_Mips_GOT;
643       break;
644     case MipsMCExpr::MEK_GOT_CALL:
645       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16
646                                    : Mips::fixup_Mips_CALL16;
647       break;
648     case MipsMCExpr::MEK_GOT_DISP:
649       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP
650                                    : Mips::fixup_Mips_GOT_DISP;
651       break;
652     case MipsMCExpr::MEK_GOT_HI16:
653       FixupKind = Mips::fixup_Mips_GOT_HI16;
654       break;
655     case MipsMCExpr::MEK_GOT_LO16:
656       FixupKind = Mips::fixup_Mips_GOT_LO16;
657       break;
658     case MipsMCExpr::MEK_GOT_PAGE:
659       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE
660                                    : Mips::fixup_Mips_GOT_PAGE;
661       break;
662     case MipsMCExpr::MEK_GOT_OFST:
663       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST
664                                    : Mips::fixup_Mips_GOT_OFST;
665       break;
666     case MipsMCExpr::MEK_GPREL:
667       FixupKind = Mips::fixup_Mips_GPREL16;
668       break;
669     case MipsMCExpr::MEK_LO:
670       // Check for %lo(%neg(%gp_rel(X)))
671       if (MipsExpr->isGpOff())
672         FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_LO
673                                      : Mips::fixup_Mips_GPOFF_LO;
674       else
675         FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
676                                      : Mips::fixup_Mips_LO16;
677       break;
678     case MipsMCExpr::MEK_HIGHEST:
679       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHEST
680                                    : Mips::fixup_Mips_HIGHEST;
681       break;
682     case MipsMCExpr::MEK_HIGHER:
683       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHER
684                                    : Mips::fixup_Mips_HIGHER;
685       break;
686     case MipsMCExpr::MEK_HI:
687       // Check for %hi(%neg(%gp_rel(X)))
688       if (MipsExpr->isGpOff())
689         FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_HI
690                                      : Mips::fixup_Mips_GPOFF_HI;
691       else
692         FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
693                                      : Mips::fixup_Mips_HI16;
694       break;
695     case MipsMCExpr::MEK_PCREL_HI16:
696       FixupKind = Mips::fixup_MIPS_PCHI16;
697       break;
698     case MipsMCExpr::MEK_PCREL_LO16:
699       FixupKind = Mips::fixup_MIPS_PCLO16;
700       break;
701     case MipsMCExpr::MEK_TLSGD:
702       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD
703                                    : Mips::fixup_Mips_TLSGD;
704       break;
705     case MipsMCExpr::MEK_TLSLDM:
706       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM
707                                    : Mips::fixup_Mips_TLSLDM;
708       break;
709     case MipsMCExpr::MEK_TPREL_HI:
710       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
711                                    : Mips::fixup_Mips_TPREL_HI;
712       break;
713     case MipsMCExpr::MEK_TPREL_LO:
714       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
715                                    : Mips::fixup_Mips_TPREL_LO;
716       break;
717     case MipsMCExpr::MEK_NEG:
718       FixupKind =
719           isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB;
720       break;
721     }
722     Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind)));
723     return 0;
724   }
725 
726   if (Kind == MCExpr::SymbolRef)
727     Ctx.reportError(Expr->getLoc(), "expected an immediate");
728   return 0;
729 }
730 
731 /// getMachineOpValue - Return binary encoding of operand. If the machine
732 /// operand requires relocation, record the relocation and return zero.
733 unsigned MipsMCCodeEmitter::
734 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
735                   SmallVectorImpl<MCFixup> &Fixups,
736                   const MCSubtargetInfo &STI) const {
737   if (MO.isReg()) {
738     unsigned Reg = MO.getReg();
739     unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
740     return RegNo;
741   } else if (MO.isImm()) {
742     return static_cast<unsigned>(MO.getImm());
743   } else if (MO.isFPImm()) {
744     return static_cast<unsigned>(APFloat(MO.getFPImm())
745         .bitcastToAPInt().getHiBits(32).getLimitedValue());
746   }
747   // MO must be an Expr.
748   assert(MO.isExpr());
749   return getExprOpValue(MO.getExpr(),Fixups, STI);
750 }
751 
752 /// Return binary encoding of memory related operand.
753 /// If the offset operand requires relocation, record the relocation.
754 template <unsigned ShiftAmount>
755 unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
756                                            SmallVectorImpl<MCFixup> &Fixups,
757                                            const MCSubtargetInfo &STI) const {
758   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
759   assert(MI.getOperand(OpNo).isReg());
760   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI)
761                      << 16;
762   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
763 
764   // Apply the scale factor if there is one.
765   OffBits >>= ShiftAmount;
766 
767   return (OffBits & 0xFFFF) | RegBits;
768 }
769 
770 unsigned MipsMCCodeEmitter::
771 getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo,
772                      SmallVectorImpl<MCFixup> &Fixups,
773                      const MCSubtargetInfo &STI) const {
774   // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
775   assert(MI.getOperand(OpNo).isReg());
776   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
777                                        Fixups, STI) << 4;
778   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
779                                        Fixups, STI);
780 
781   return (OffBits & 0xF) | RegBits;
782 }
783 
784 unsigned MipsMCCodeEmitter::
785 getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo,
786                          SmallVectorImpl<MCFixup> &Fixups,
787                          const MCSubtargetInfo &STI) const {
788   // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
789   assert(MI.getOperand(OpNo).isReg());
790   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
791                                        Fixups, STI) << 4;
792   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
793                                        Fixups, STI) >> 1;
794 
795   return (OffBits & 0xF) | RegBits;
796 }
797 
798 unsigned MipsMCCodeEmitter::
799 getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo,
800                          SmallVectorImpl<MCFixup> &Fixups,
801                          const MCSubtargetInfo &STI) const {
802   // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
803   assert(MI.getOperand(OpNo).isReg());
804   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
805                                        Fixups, STI) << 4;
806   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
807                                        Fixups, STI) >> 2;
808 
809   return (OffBits & 0xF) | RegBits;
810 }
811 
812 unsigned MipsMCCodeEmitter::
813 getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
814                            SmallVectorImpl<MCFixup> &Fixups,
815                            const MCSubtargetInfo &STI) const {
816   // Register is encoded in bits 9-5, offset is encoded in bits 4-0.
817   assert(MI.getOperand(OpNo).isReg() &&
818          (MI.getOperand(OpNo).getReg() == Mips::SP ||
819          MI.getOperand(OpNo).getReg() == Mips::SP_64) &&
820          "Unexpected base register!");
821   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
822                                        Fixups, STI) >> 2;
823 
824   return OffBits & 0x1F;
825 }
826 
827 unsigned MipsMCCodeEmitter::
828 getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
829                            SmallVectorImpl<MCFixup> &Fixups,
830                            const MCSubtargetInfo &STI) const {
831   // Register is encoded in bits 9-7, offset is encoded in bits 6-0.
832   assert(MI.getOperand(OpNo).isReg() &&
833          MI.getOperand(OpNo).getReg() == Mips::GP &&
834          "Unexpected base register!");
835 
836   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
837                                        Fixups, STI) >> 2;
838 
839   return OffBits & 0x7F;
840 }
841 
842 unsigned MipsMCCodeEmitter::
843 getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo,
844                      SmallVectorImpl<MCFixup> &Fixups,
845                      const MCSubtargetInfo &STI) const {
846   // Base register is encoded in bits 20-16, offset is encoded in bits 8-0.
847   assert(MI.getOperand(OpNo).isReg());
848   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
849                                        STI) << 16;
850   unsigned OffBits =
851       getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI);
852 
853   return (OffBits & 0x1FF) | RegBits;
854 }
855 
856 unsigned MipsMCCodeEmitter::
857 getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo,
858                       SmallVectorImpl<MCFixup> &Fixups,
859                       const MCSubtargetInfo &STI) const {
860   // Base register is encoded in bits 20-16, offset is encoded in bits 10-0.
861   assert(MI.getOperand(OpNo).isReg());
862   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
863                                        STI) << 16;
864   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
865 
866   return (OffBits & 0x07FF) | RegBits;
867 }
868 
869 unsigned MipsMCCodeEmitter::
870 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
871                       SmallVectorImpl<MCFixup> &Fixups,
872                       const MCSubtargetInfo &STI) const {
873   // opNum can be invalid if instruction had reglist as operand.
874   // MemOperand is always last operand of instruction (base + offset).
875   switch (MI.getOpcode()) {
876   default:
877     break;
878   case Mips::SWM32_MM:
879   case Mips::LWM32_MM:
880     OpNo = MI.getNumOperands() - 2;
881     break;
882   }
883 
884   // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
885   assert(MI.getOperand(OpNo).isReg());
886   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI)
887                      << 16;
888   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
889 
890   return (OffBits & 0x0FFF) | RegBits;
891 }
892 
893 unsigned MipsMCCodeEmitter::
894 getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo,
895                       SmallVectorImpl<MCFixup> &Fixups,
896                       const MCSubtargetInfo &STI) const {
897   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
898   assert(MI.getOperand(OpNo).isReg());
899   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
900                                        STI) << 16;
901   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
902 
903   return (OffBits & 0xFFFF) | RegBits;
904 }
905 
906 unsigned MipsMCCodeEmitter::
907 getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
908                        SmallVectorImpl<MCFixup> &Fixups,
909                        const MCSubtargetInfo &STI) const {
910   // opNum can be invalid if instruction had reglist as operand
911   // MemOperand is always last operand of instruction (base + offset)
912   switch (MI.getOpcode()) {
913   default:
914     break;
915   case Mips::SWM16_MM:
916   case Mips::SWM16_MMR6:
917   case Mips::LWM16_MM:
918   case Mips::LWM16_MMR6:
919     OpNo = MI.getNumOperands() - 2;
920     break;
921   }
922 
923   // Offset is encoded in bits 4-0.
924   assert(MI.getOperand(OpNo).isReg());
925   // Base register is always SP - thus it is not encoded.
926   assert(MI.getOperand(OpNo+1).isImm());
927   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
928 
929   return ((OffBits >> 2) & 0x0F);
930 }
931 
932 // FIXME: should be called getMSBEncoding
933 //
934 unsigned
935 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
936                                       SmallVectorImpl<MCFixup> &Fixups,
937                                       const MCSubtargetInfo &STI) const {
938   assert(MI.getOperand(OpNo-1).isImm());
939   assert(MI.getOperand(OpNo).isImm());
940   unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI);
941   unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
942 
943   return Position + Size - 1;
944 }
945 
946 template <unsigned Bits, int Offset>
947 unsigned
948 MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo,
949                                              SmallVectorImpl<MCFixup> &Fixups,
950                                              const MCSubtargetInfo &STI) const {
951   assert(MI.getOperand(OpNo).isImm());
952   unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
953   Value -= Offset;
954   return Value;
955 }
956 
957 unsigned
958 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
959                                          SmallVectorImpl<MCFixup> &Fixups,
960                                          const MCSubtargetInfo &STI) const {
961   const MCOperand &MO = MI.getOperand(OpNo);
962   if (MO.isImm()) {
963     // The immediate is encoded as 'immediate << 2'.
964     unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
965     assert((Res & 3) == 0);
966     return Res >> 2;
967   }
968 
969   assert(MO.isExpr() &&
970          "getSimm19Lsl2Encoding expects only expressions or an immediate");
971 
972   const MCExpr *Expr = MO.getExpr();
973   Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2
974                                             : Mips::fixup_MIPS_PC19_S2;
975   Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
976   return 0;
977 }
978 
979 unsigned
980 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
981                                          SmallVectorImpl<MCFixup> &Fixups,
982                                          const MCSubtargetInfo &STI) const {
983   const MCOperand &MO = MI.getOperand(OpNo);
984   if (MO.isImm()) {
985     // The immediate is encoded as 'immediate << 3'.
986     unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
987     assert((Res & 7) == 0);
988     return Res >> 3;
989   }
990 
991   assert(MO.isExpr() &&
992          "getSimm18Lsl2Encoding expects only expressions or an immediate");
993 
994   const MCExpr *Expr = MO.getExpr();
995   Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3
996                                             : Mips::fixup_MIPS_PC18_S3;
997   Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
998   return 0;
999 }
1000 
1001 unsigned
1002 MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
1003                                         SmallVectorImpl<MCFixup> &Fixups,
1004                                         const MCSubtargetInfo &STI) const {
1005   assert(MI.getOperand(OpNo).isImm());
1006   const MCOperand &MO = MI.getOperand(OpNo);
1007   return MO.getImm() % 8;
1008 }
1009 
1010 unsigned
1011 MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo,
1012                                     SmallVectorImpl<MCFixup> &Fixups,
1013                                     const MCSubtargetInfo &STI) const {
1014   assert(MI.getOperand(OpNo).isImm());
1015   const MCOperand &MO = MI.getOperand(OpNo);
1016   unsigned Value = MO.getImm();
1017   switch (Value) {
1018     case 128:   return 0x0;
1019     case 1:     return 0x1;
1020     case 2:     return 0x2;
1021     case 3:     return 0x3;
1022     case 4:     return 0x4;
1023     case 7:     return 0x5;
1024     case 8:     return 0x6;
1025     case 15:    return 0x7;
1026     case 16:    return 0x8;
1027     case 31:    return 0x9;
1028     case 32:    return 0xa;
1029     case 63:    return 0xb;
1030     case 64:    return 0xc;
1031     case 255:   return 0xd;
1032     case 32768: return 0xe;
1033     case 65535: return 0xf;
1034   }
1035   llvm_unreachable("Unexpected value");
1036 }
1037 
1038 unsigned
1039 MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo,
1040                                           SmallVectorImpl<MCFixup> &Fixups,
1041                                           const MCSubtargetInfo &STI) const {
1042   unsigned res = 0;
1043 
1044   // Register list operand is always first operand of instruction and it is
1045   // placed before memory operand (register + imm).
1046 
1047   for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) {
1048     unsigned Reg = MI.getOperand(I).getReg();
1049     unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
1050     if (RegNo != 31)
1051       res++;
1052     else
1053       res |= 0x10;
1054   }
1055   return res;
1056 }
1057 
1058 unsigned
1059 MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
1060                                             SmallVectorImpl<MCFixup> &Fixups,
1061                                             const MCSubtargetInfo &STI) const {
1062   return (MI.getNumOperands() - 4);
1063 }
1064 
1065 unsigned
1066 MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
1067                                           SmallVectorImpl<MCFixup> &Fixups,
1068                                           const MCSubtargetInfo &STI) const {
1069   unsigned res = 0;
1070 
1071   if (MI.getOperand(0).getReg() == Mips::A1 &&
1072       MI.getOperand(1).getReg() == Mips::A2)
1073     res = 0;
1074   else if (MI.getOperand(0).getReg() == Mips::A1 &&
1075            MI.getOperand(1).getReg() == Mips::A3)
1076     res = 1;
1077   else if (MI.getOperand(0).getReg() == Mips::A2 &&
1078            MI.getOperand(1).getReg() == Mips::A3)
1079     res = 2;
1080   else if (MI.getOperand(0).getReg() == Mips::A0 &&
1081            MI.getOperand(1).getReg() == Mips::S5)
1082     res = 3;
1083   else if (MI.getOperand(0).getReg() == Mips::A0 &&
1084            MI.getOperand(1).getReg() == Mips::S6)
1085     res = 4;
1086   else if (MI.getOperand(0).getReg() == Mips::A0 &&
1087            MI.getOperand(1).getReg() == Mips::A1)
1088     res = 5;
1089   else if (MI.getOperand(0).getReg() == Mips::A0 &&
1090            MI.getOperand(1).getReg() == Mips::A2)
1091     res = 6;
1092   else if (MI.getOperand(0).getReg() == Mips::A0 &&
1093            MI.getOperand(1).getReg() == Mips::A3)
1094     res = 7;
1095 
1096   return res;
1097 }
1098 
1099 unsigned
1100 MipsMCCodeEmitter::getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo,
1101                                             SmallVectorImpl<MCFixup> &Fixups,
1102                                             const MCSubtargetInfo &STI) const {
1103   assert(((OpNo == 2) || (OpNo == 3)) &&
1104          "Unexpected OpNo for movep operand encoding!");
1105 
1106   MCOperand Op = MI.getOperand(OpNo);
1107   assert(Op.isReg() && "Operand of movep is not a register!");
1108   switch (Op.getReg()) {
1109   default:
1110     llvm_unreachable("Unknown register for movep!");
1111   case Mips::ZERO:  return 0;
1112   case Mips::S1:    return 1;
1113   case Mips::V0:    return 2;
1114   case Mips::V1:    return 3;
1115   case Mips::S0:    return 4;
1116   case Mips::S2:    return 5;
1117   case Mips::S3:    return 6;
1118   case Mips::S4:    return 7;
1119   }
1120 }
1121 
1122 unsigned
1123 MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
1124                                          SmallVectorImpl<MCFixup> &Fixups,
1125                                          const MCSubtargetInfo &STI) const {
1126   const MCOperand &MO = MI.getOperand(OpNo);
1127   assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate");
1128   // The immediate is encoded as 'immediate >> 2'.
1129   unsigned Res = static_cast<unsigned>(MO.getImm());
1130   assert((Res & 3) == 0);
1131   return Res >> 2;
1132 }
1133 
1134 #include "MipsGenMCCodeEmitter.inc"
1135