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