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