xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp (revision a7dea1671b87c07d2d266f836bfa8b58efc7c134)
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 = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
604     Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
605     return Res;
606   }
607 
608   if (Kind == MCExpr::Target) {
609     const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
610 
611     Mips::Fixups FixupKind = Mips::Fixups(0);
612     switch (MipsExpr->getKind()) {
613     case MipsMCExpr::MEK_None:
614     case MipsMCExpr::MEK_Special:
615       llvm_unreachable("Unhandled fixup kind!");
616       break;
617     case MipsMCExpr::MEK_DTPREL:
618       // MEK_DTPREL is used for marking TLS DIEExpr only
619       // and contains a regular sub-expression.
620       return getExprOpValue(MipsExpr->getSubExpr(), Fixups, STI);
621     case MipsMCExpr::MEK_CALL_HI16:
622       FixupKind = Mips::fixup_Mips_CALL_HI16;
623       break;
624     case MipsMCExpr::MEK_CALL_LO16:
625       FixupKind = Mips::fixup_Mips_CALL_LO16;
626       break;
627     case MipsMCExpr::MEK_DTPREL_HI:
628       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
629                                    : Mips::fixup_Mips_DTPREL_HI;
630       break;
631     case MipsMCExpr::MEK_DTPREL_LO:
632       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
633                                    : Mips::fixup_Mips_DTPREL_LO;
634       break;
635     case MipsMCExpr::MEK_GOTTPREL:
636       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOTTPREL
637                                    : Mips::fixup_Mips_GOTTPREL;
638       break;
639     case MipsMCExpr::MEK_GOT:
640       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
641                                    : Mips::fixup_Mips_GOT;
642       break;
643     case MipsMCExpr::MEK_GOT_CALL:
644       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16
645                                    : Mips::fixup_Mips_CALL16;
646       break;
647     case MipsMCExpr::MEK_GOT_DISP:
648       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP
649                                    : Mips::fixup_Mips_GOT_DISP;
650       break;
651     case MipsMCExpr::MEK_GOT_HI16:
652       FixupKind = Mips::fixup_Mips_GOT_HI16;
653       break;
654     case MipsMCExpr::MEK_GOT_LO16:
655       FixupKind = Mips::fixup_Mips_GOT_LO16;
656       break;
657     case MipsMCExpr::MEK_GOT_PAGE:
658       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE
659                                    : Mips::fixup_Mips_GOT_PAGE;
660       break;
661     case MipsMCExpr::MEK_GOT_OFST:
662       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST
663                                    : Mips::fixup_Mips_GOT_OFST;
664       break;
665     case MipsMCExpr::MEK_GPREL:
666       FixupKind = Mips::fixup_Mips_GPREL16;
667       break;
668     case MipsMCExpr::MEK_LO:
669       // Check for %lo(%neg(%gp_rel(X)))
670       if (MipsExpr->isGpOff())
671         FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_LO
672                                      : Mips::fixup_Mips_GPOFF_LO;
673       else
674         FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
675                                      : Mips::fixup_Mips_LO16;
676       break;
677     case MipsMCExpr::MEK_HIGHEST:
678       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHEST
679                                    : Mips::fixup_Mips_HIGHEST;
680       break;
681     case MipsMCExpr::MEK_HIGHER:
682       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHER
683                                    : Mips::fixup_Mips_HIGHER;
684       break;
685     case MipsMCExpr::MEK_HI:
686       // Check for %hi(%neg(%gp_rel(X)))
687       if (MipsExpr->isGpOff())
688         FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_HI
689                                      : Mips::fixup_Mips_GPOFF_HI;
690       else
691         FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
692                                      : Mips::fixup_Mips_HI16;
693       break;
694     case MipsMCExpr::MEK_PCREL_HI16:
695       FixupKind = Mips::fixup_MIPS_PCHI16;
696       break;
697     case MipsMCExpr::MEK_PCREL_LO16:
698       FixupKind = Mips::fixup_MIPS_PCLO16;
699       break;
700     case MipsMCExpr::MEK_TLSGD:
701       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD
702                                    : Mips::fixup_Mips_TLSGD;
703       break;
704     case MipsMCExpr::MEK_TLSLDM:
705       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM
706                                    : Mips::fixup_Mips_TLSLDM;
707       break;
708     case MipsMCExpr::MEK_TPREL_HI:
709       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
710                                    : Mips::fixup_Mips_TPREL_HI;
711       break;
712     case MipsMCExpr::MEK_TPREL_LO:
713       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
714                                    : Mips::fixup_Mips_TPREL_LO;
715       break;
716     case MipsMCExpr::MEK_NEG:
717       FixupKind =
718           isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB;
719       break;
720     }
721     Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind)));
722     return 0;
723   }
724 
725   if (Kind == MCExpr::SymbolRef) {
726     Mips::Fixups FixupKind = Mips::Fixups(0);
727 
728     switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
729     default: llvm_unreachable("Unknown fixup kind!");
730       break;
731     case MCSymbolRefExpr::VK_None:
732       FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64.
733       break;
734     } // switch
735 
736     Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
737     return 0;
738   }
739   return 0;
740 }
741 
742 /// getMachineOpValue - Return binary encoding of operand. If the machine
743 /// operand requires relocation, record the relocation and return zero.
744 unsigned MipsMCCodeEmitter::
745 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
746                   SmallVectorImpl<MCFixup> &Fixups,
747                   const MCSubtargetInfo &STI) const {
748   if (MO.isReg()) {
749     unsigned Reg = MO.getReg();
750     unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
751     return RegNo;
752   } else if (MO.isImm()) {
753     return static_cast<unsigned>(MO.getImm());
754   } else if (MO.isFPImm()) {
755     return static_cast<unsigned>(APFloat(MO.getFPImm())
756         .bitcastToAPInt().getHiBits(32).getLimitedValue());
757   }
758   // MO must be an Expr.
759   assert(MO.isExpr());
760   return getExprOpValue(MO.getExpr(),Fixups, STI);
761 }
762 
763 /// Return binary encoding of memory related operand.
764 /// If the offset operand requires relocation, record the relocation.
765 template <unsigned ShiftAmount>
766 unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
767                                            SmallVectorImpl<MCFixup> &Fixups,
768                                            const MCSubtargetInfo &STI) const {
769   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
770   assert(MI.getOperand(OpNo).isReg());
771   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
772   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
773 
774   // Apply the scale factor if there is one.
775   OffBits >>= ShiftAmount;
776 
777   return (OffBits & 0xFFFF) | RegBits;
778 }
779 
780 unsigned MipsMCCodeEmitter::
781 getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo,
782                      SmallVectorImpl<MCFixup> &Fixups,
783                      const MCSubtargetInfo &STI) const {
784   // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
785   assert(MI.getOperand(OpNo).isReg());
786   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
787                                        Fixups, STI) << 4;
788   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
789                                        Fixups, STI);
790 
791   return (OffBits & 0xF) | RegBits;
792 }
793 
794 unsigned MipsMCCodeEmitter::
795 getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo,
796                          SmallVectorImpl<MCFixup> &Fixups,
797                          const MCSubtargetInfo &STI) const {
798   // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
799   assert(MI.getOperand(OpNo).isReg());
800   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
801                                        Fixups, STI) << 4;
802   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
803                                        Fixups, STI) >> 1;
804 
805   return (OffBits & 0xF) | RegBits;
806 }
807 
808 unsigned MipsMCCodeEmitter::
809 getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo,
810                          SmallVectorImpl<MCFixup> &Fixups,
811                          const MCSubtargetInfo &STI) const {
812   // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
813   assert(MI.getOperand(OpNo).isReg());
814   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
815                                        Fixups, STI) << 4;
816   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
817                                        Fixups, STI) >> 2;
818 
819   return (OffBits & 0xF) | RegBits;
820 }
821 
822 unsigned MipsMCCodeEmitter::
823 getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
824                            SmallVectorImpl<MCFixup> &Fixups,
825                            const MCSubtargetInfo &STI) const {
826   // Register is encoded in bits 9-5, offset is encoded in bits 4-0.
827   assert(MI.getOperand(OpNo).isReg() &&
828          (MI.getOperand(OpNo).getReg() == Mips::SP ||
829          MI.getOperand(OpNo).getReg() == Mips::SP_64) &&
830          "Unexpected base register!");
831   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
832                                        Fixups, STI) >> 2;
833 
834   return OffBits & 0x1F;
835 }
836 
837 unsigned MipsMCCodeEmitter::
838 getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
839                            SmallVectorImpl<MCFixup> &Fixups,
840                            const MCSubtargetInfo &STI) const {
841   // Register is encoded in bits 9-7, offset is encoded in bits 6-0.
842   assert(MI.getOperand(OpNo).isReg() &&
843          MI.getOperand(OpNo).getReg() == Mips::GP &&
844          "Unexpected base register!");
845 
846   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
847                                        Fixups, STI) >> 2;
848 
849   return OffBits & 0x7F;
850 }
851 
852 unsigned MipsMCCodeEmitter::
853 getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo,
854                      SmallVectorImpl<MCFixup> &Fixups,
855                      const MCSubtargetInfo &STI) const {
856   // Base register is encoded in bits 20-16, offset is encoded in bits 8-0.
857   assert(MI.getOperand(OpNo).isReg());
858   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
859                                        STI) << 16;
860   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI);
861 
862   return (OffBits & 0x1FF) | RegBits;
863 }
864 
865 unsigned MipsMCCodeEmitter::
866 getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo,
867                       SmallVectorImpl<MCFixup> &Fixups,
868                       const MCSubtargetInfo &STI) const {
869   // Base register is encoded in bits 20-16, offset is encoded in bits 10-0.
870   assert(MI.getOperand(OpNo).isReg());
871   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
872                                        STI) << 16;
873   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
874 
875   return (OffBits & 0x07FF) | RegBits;
876 }
877 
878 unsigned MipsMCCodeEmitter::
879 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
880                       SmallVectorImpl<MCFixup> &Fixups,
881                       const MCSubtargetInfo &STI) const {
882   // opNum can be invalid if instruction had reglist as operand.
883   // MemOperand is always last operand of instruction (base + offset).
884   switch (MI.getOpcode()) {
885   default:
886     break;
887   case Mips::SWM32_MM:
888   case Mips::LWM32_MM:
889     OpNo = MI.getNumOperands() - 2;
890     break;
891   }
892 
893   // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
894   assert(MI.getOperand(OpNo).isReg());
895   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
896   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
897 
898   return (OffBits & 0x0FFF) | RegBits;
899 }
900 
901 unsigned MipsMCCodeEmitter::
902 getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo,
903                       SmallVectorImpl<MCFixup> &Fixups,
904                       const MCSubtargetInfo &STI) const {
905   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
906   assert(MI.getOperand(OpNo).isReg());
907   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
908                                        STI) << 16;
909   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
910 
911   return (OffBits & 0xFFFF) | RegBits;
912 }
913 
914 unsigned MipsMCCodeEmitter::
915 getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
916                        SmallVectorImpl<MCFixup> &Fixups,
917                        const MCSubtargetInfo &STI) const {
918   // opNum can be invalid if instruction had reglist as operand
919   // MemOperand is always last operand of instruction (base + offset)
920   switch (MI.getOpcode()) {
921   default:
922     break;
923   case Mips::SWM16_MM:
924   case Mips::SWM16_MMR6:
925   case Mips::LWM16_MM:
926   case Mips::LWM16_MMR6:
927     OpNo = MI.getNumOperands() - 2;
928     break;
929   }
930 
931   // Offset is encoded in bits 4-0.
932   assert(MI.getOperand(OpNo).isReg());
933   // Base register is always SP - thus it is not encoded.
934   assert(MI.getOperand(OpNo+1).isImm());
935   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
936 
937   return ((OffBits >> 2) & 0x0F);
938 }
939 
940 // FIXME: should be called getMSBEncoding
941 //
942 unsigned
943 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
944                                       SmallVectorImpl<MCFixup> &Fixups,
945                                       const MCSubtargetInfo &STI) const {
946   assert(MI.getOperand(OpNo-1).isImm());
947   assert(MI.getOperand(OpNo).isImm());
948   unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI);
949   unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
950 
951   return Position + Size - 1;
952 }
953 
954 template <unsigned Bits, int Offset>
955 unsigned
956 MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo,
957                                              SmallVectorImpl<MCFixup> &Fixups,
958                                              const MCSubtargetInfo &STI) const {
959   assert(MI.getOperand(OpNo).isImm());
960   unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
961   Value -= Offset;
962   return Value;
963 }
964 
965 unsigned
966 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
967                                          SmallVectorImpl<MCFixup> &Fixups,
968                                          const MCSubtargetInfo &STI) const {
969   const MCOperand &MO = MI.getOperand(OpNo);
970   if (MO.isImm()) {
971     // The immediate is encoded as 'immediate << 2'.
972     unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
973     assert((Res & 3) == 0);
974     return Res >> 2;
975   }
976 
977   assert(MO.isExpr() &&
978          "getSimm19Lsl2Encoding expects only expressions or an immediate");
979 
980   const MCExpr *Expr = MO.getExpr();
981   Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2
982                                             : Mips::fixup_MIPS_PC19_S2;
983   Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
984   return 0;
985 }
986 
987 unsigned
988 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
989                                          SmallVectorImpl<MCFixup> &Fixups,
990                                          const MCSubtargetInfo &STI) const {
991   const MCOperand &MO = MI.getOperand(OpNo);
992   if (MO.isImm()) {
993     // The immediate is encoded as 'immediate << 3'.
994     unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
995     assert((Res & 7) == 0);
996     return Res >> 3;
997   }
998 
999   assert(MO.isExpr() &&
1000          "getSimm18Lsl2Encoding expects only expressions or an immediate");
1001 
1002   const MCExpr *Expr = MO.getExpr();
1003   Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3
1004                                             : Mips::fixup_MIPS_PC18_S3;
1005   Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
1006   return 0;
1007 }
1008 
1009 unsigned
1010 MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
1011                                         SmallVectorImpl<MCFixup> &Fixups,
1012                                         const MCSubtargetInfo &STI) const {
1013   assert(MI.getOperand(OpNo).isImm());
1014   const MCOperand &MO = MI.getOperand(OpNo);
1015   return MO.getImm() % 8;
1016 }
1017 
1018 unsigned
1019 MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo,
1020                                     SmallVectorImpl<MCFixup> &Fixups,
1021                                     const MCSubtargetInfo &STI) const {
1022   assert(MI.getOperand(OpNo).isImm());
1023   const MCOperand &MO = MI.getOperand(OpNo);
1024   unsigned Value = MO.getImm();
1025   switch (Value) {
1026     case 128:   return 0x0;
1027     case 1:     return 0x1;
1028     case 2:     return 0x2;
1029     case 3:     return 0x3;
1030     case 4:     return 0x4;
1031     case 7:     return 0x5;
1032     case 8:     return 0x6;
1033     case 15:    return 0x7;
1034     case 16:    return 0x8;
1035     case 31:    return 0x9;
1036     case 32:    return 0xa;
1037     case 63:    return 0xb;
1038     case 64:    return 0xc;
1039     case 255:   return 0xd;
1040     case 32768: return 0xe;
1041     case 65535: return 0xf;
1042   }
1043   llvm_unreachable("Unexpected value");
1044 }
1045 
1046 unsigned
1047 MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo,
1048                                           SmallVectorImpl<MCFixup> &Fixups,
1049                                           const MCSubtargetInfo &STI) const {
1050   unsigned res = 0;
1051 
1052   // Register list operand is always first operand of instruction and it is
1053   // placed before memory operand (register + imm).
1054 
1055   for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) {
1056     unsigned Reg = MI.getOperand(I).getReg();
1057     unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
1058     if (RegNo != 31)
1059       res++;
1060     else
1061       res |= 0x10;
1062   }
1063   return res;
1064 }
1065 
1066 unsigned
1067 MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
1068                                             SmallVectorImpl<MCFixup> &Fixups,
1069                                             const MCSubtargetInfo &STI) const {
1070   return (MI.getNumOperands() - 4);
1071 }
1072 
1073 unsigned
1074 MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
1075                                           SmallVectorImpl<MCFixup> &Fixups,
1076                                           const MCSubtargetInfo &STI) const {
1077   unsigned res = 0;
1078 
1079   if (MI.getOperand(0).getReg() == Mips::A1 &&
1080       MI.getOperand(1).getReg() == Mips::A2)
1081     res = 0;
1082   else if (MI.getOperand(0).getReg() == Mips::A1 &&
1083            MI.getOperand(1).getReg() == Mips::A3)
1084     res = 1;
1085   else if (MI.getOperand(0).getReg() == Mips::A2 &&
1086            MI.getOperand(1).getReg() == Mips::A3)
1087     res = 2;
1088   else if (MI.getOperand(0).getReg() == Mips::A0 &&
1089            MI.getOperand(1).getReg() == Mips::S5)
1090     res = 3;
1091   else if (MI.getOperand(0).getReg() == Mips::A0 &&
1092            MI.getOperand(1).getReg() == Mips::S6)
1093     res = 4;
1094   else if (MI.getOperand(0).getReg() == Mips::A0 &&
1095            MI.getOperand(1).getReg() == Mips::A1)
1096     res = 5;
1097   else if (MI.getOperand(0).getReg() == Mips::A0 &&
1098            MI.getOperand(1).getReg() == Mips::A2)
1099     res = 6;
1100   else if (MI.getOperand(0).getReg() == Mips::A0 &&
1101            MI.getOperand(1).getReg() == Mips::A3)
1102     res = 7;
1103 
1104   return res;
1105 }
1106 
1107 unsigned
1108 MipsMCCodeEmitter::getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo,
1109                                             SmallVectorImpl<MCFixup> &Fixups,
1110                                             const MCSubtargetInfo &STI) const {
1111   assert(((OpNo == 2) || (OpNo == 3)) &&
1112          "Unexpected OpNo for movep operand encoding!");
1113 
1114   MCOperand Op = MI.getOperand(OpNo);
1115   assert(Op.isReg() && "Operand of movep is not a register!");
1116   switch (Op.getReg()) {
1117   default:
1118     llvm_unreachable("Unknown register for movep!");
1119   case Mips::ZERO:  return 0;
1120   case Mips::S1:    return 1;
1121   case Mips::V0:    return 2;
1122   case Mips::V1:    return 3;
1123   case Mips::S0:    return 4;
1124   case Mips::S2:    return 5;
1125   case Mips::S3:    return 6;
1126   case Mips::S4:    return 7;
1127   }
1128 }
1129 
1130 unsigned
1131 MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
1132                                          SmallVectorImpl<MCFixup> &Fixups,
1133                                          const MCSubtargetInfo &STI) const {
1134   const MCOperand &MO = MI.getOperand(OpNo);
1135   assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate");
1136   // The immediate is encoded as 'immediate >> 2'.
1137   unsigned Res = static_cast<unsigned>(MO.getImm());
1138   assert((Res & 3) == 0);
1139   return Res >> 2;
1140 }
1141 
1142 #include "MipsGenMCCodeEmitter.inc"
1143