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