• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the MipsMCCodeEmitter class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "MipsMCCodeEmitter.h"
15 #include "MCTargetDesc/MipsFixupKinds.h"
16 #include "MCTargetDesc/MipsMCExpr.h"
17 #include "MCTargetDesc/MipsMCTargetDesc.h"
18 #include "llvm/ADT/APFloat.h"
19 #include "llvm/ADT/APInt.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/MC/MCContext.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCFixup.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCInstrDesc.h"
26 #include "llvm/MC/MCInstrInfo.h"
27 #include "llvm/MC/MCRegisterInfo.h"
28 #include "llvm/MC/MCSubtargetInfo.h"
29 #include "llvm/Support/Casting.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 
createMipsMCCodeEmitterEB(const MCInstrInfo & MCII,const MCRegisterInfo & MRI,MCContext & Ctx)45 MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
46                                          const MCRegisterInfo &MRI,
47                                          MCContext &Ctx) {
48   return new MipsMCCodeEmitter(MCII, Ctx, false);
49 }
50 
createMipsMCCodeEmitterEL(const MCInstrInfo & MCII,const MCRegisterInfo & MRI,MCContext & Ctx)51 MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
52                                          const MCRegisterInfo &MRI,
53                                          MCContext &Ctx) {
54   return new MipsMCCodeEmitter(MCII, Ctx, true);
55 }
56 
57 } // end namespace llvm
58 
59 // If the D<shift> instruction has a shift amount that is greater
60 // than 31 (checked in calling routine), lower it to a D<shift>32 instruction
LowerLargeShift(MCInst & Inst)61 static void LowerLargeShift(MCInst& Inst) {
62   assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
63   assert(Inst.getOperand(2).isImm());
64 
65   int64_t Shift = Inst.getOperand(2).getImm();
66   if (Shift <= 31)
67     return; // Do nothing
68   Shift -= 32;
69 
70   // saminus32
71   Inst.getOperand(2).setImm(Shift);
72 
73   switch (Inst.getOpcode()) {
74   default:
75     // Calling function is not synchronized
76     llvm_unreachable("Unexpected shift instruction");
77   case Mips::DSLL:
78     Inst.setOpcode(Mips::DSLL32);
79     return;
80   case Mips::DSRL:
81     Inst.setOpcode(Mips::DSRL32);
82     return;
83   case Mips::DSRA:
84     Inst.setOpcode(Mips::DSRA32);
85     return;
86   case Mips::DROTR:
87     Inst.setOpcode(Mips::DROTR32);
88     return;
89   }
90 }
91 
92 // Fix a bad compact branch encoding for beqc/bnec.
LowerCompactBranch(MCInst & Inst) const93 void MipsMCCodeEmitter::LowerCompactBranch(MCInst& Inst) const {
94   // Encoding may be illegal !(rs < rt), but this situation is
95   // easily fixed.
96   unsigned RegOp0 = Inst.getOperand(0).getReg();
97   unsigned RegOp1 = Inst.getOperand(1).getReg();
98 
99   unsigned Reg0 =  Ctx.getRegisterInfo()->getEncodingValue(RegOp0);
100   unsigned Reg1 =  Ctx.getRegisterInfo()->getEncodingValue(RegOp1);
101 
102   if (Inst.getOpcode() == Mips::BNEC || Inst.getOpcode() == Mips::BEQC ||
103       Inst.getOpcode() == Mips::BNEC64 || Inst.getOpcode() == Mips::BEQC64) {
104     assert(Reg0 != Reg1 && "Instruction has bad operands ($rs == $rt)!");
105     if (Reg0 < Reg1)
106       return;
107   } else if (Inst.getOpcode() == Mips::BNVC || Inst.getOpcode() == Mips::BOVC) {
108     if (Reg0 >= Reg1)
109       return;
110   } else if (Inst.getOpcode() == Mips::BNVC_MMR6 ||
111              Inst.getOpcode() == Mips::BOVC_MMR6) {
112     if (Reg1 >= Reg0)
113       return;
114   } else
115     llvm_unreachable("Cannot rewrite unknown branch!");
116 
117   Inst.getOperand(0).setReg(RegOp1);
118   Inst.getOperand(1).setReg(RegOp0);
119 }
120 
isMicroMips(const MCSubtargetInfo & STI) const121 bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const {
122   return STI.getFeatureBits()[Mips::FeatureMicroMips];
123 }
124 
isMips32r6(const MCSubtargetInfo & STI) const125 bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const {
126   return STI.getFeatureBits()[Mips::FeatureMips32r6];
127 }
128 
EmitByte(unsigned char C,raw_ostream & OS) const129 void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const {
130   OS << (char)C;
131 }
132 
EmitInstruction(uint64_t Val,unsigned Size,const MCSubtargetInfo & STI,raw_ostream & OS) const133 void MipsMCCodeEmitter::EmitInstruction(uint64_t Val, unsigned Size,
134                                         const MCSubtargetInfo &STI,
135                                         raw_ostream &OS) const {
136   // Output the instruction encoding in little endian byte order.
137   // Little-endian byte ordering:
138   //   mips32r2:   4 | 3 | 2 | 1
139   //   microMIPS:  2 | 1 | 4 | 3
140   if (IsLittleEndian && Size == 4 && isMicroMips(STI)) {
141     EmitInstruction(Val >> 16, 2, STI, OS);
142     EmitInstruction(Val, 2, STI, OS);
143   } else {
144     for (unsigned i = 0; i < Size; ++i) {
145       unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
146       EmitByte((Val >> Shift) & 0xff, OS);
147     }
148   }
149 }
150 
151 /// encodeInstruction - Emit the instruction.
152 /// Size the instruction with Desc.getSize().
153 void MipsMCCodeEmitter::
encodeInstruction(const MCInst & MI,raw_ostream & OS,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const154 encodeInstruction(const MCInst &MI, raw_ostream &OS,
155                   SmallVectorImpl<MCFixup> &Fixups,
156                   const MCSubtargetInfo &STI) const
157 {
158   // Non-pseudo instructions that get changed for direct object
159   // only based on operand values.
160   // If this list of instructions get much longer we will move
161   // the check to a function call. Until then, this is more efficient.
162   MCInst TmpInst = MI;
163   switch (MI.getOpcode()) {
164   // If shift amount is >= 32 it the inst needs to be lowered further
165   case Mips::DSLL:
166   case Mips::DSRL:
167   case Mips::DSRA:
168   case Mips::DROTR:
169     LowerLargeShift(TmpInst);
170     break;
171   // Compact branches, enforce encoding restrictions.
172   case Mips::BEQC:
173   case Mips::BNEC:
174   case Mips::BEQC64:
175   case Mips::BNEC64:
176   case Mips::BOVC:
177   case Mips::BOVC_MMR6:
178   case Mips::BNVC:
179   case Mips::BNVC_MMR6:
180     LowerCompactBranch(TmpInst);
181   }
182 
183   unsigned long N = Fixups.size();
184   uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
185 
186   // Check for unimplemented opcodes.
187   // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
188   // so we have to special check for them.
189   unsigned Opcode = TmpInst.getOpcode();
190   if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) &&
191       (Opcode != Mips::SLL_MM) && (Opcode != Mips::SLL_MMR6) && !Binary)
192     llvm_unreachable("unimplemented opcode in encodeInstruction()");
193 
194   int NewOpcode = -1;
195   if (isMicroMips(STI)) {
196     if (isMips32r6(STI)) {
197       NewOpcode = Mips::MipsR62MicroMipsR6(Opcode, Mips::Arch_micromipsr6);
198       if (NewOpcode == -1)
199         NewOpcode = Mips::Std2MicroMipsR6(Opcode, Mips::Arch_micromipsr6);
200     }
201     else
202       NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips);
203 
204     // Check whether it is Dsp instruction.
205     if (NewOpcode == -1)
206       NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp);
207 
208     if (NewOpcode != -1) {
209       if (Fixups.size() > N)
210         Fixups.pop_back();
211 
212       Opcode = NewOpcode;
213       TmpInst.setOpcode (NewOpcode);
214       Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
215     }
216   }
217 
218   const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
219 
220   // Get byte count of instruction
221   unsigned Size = Desc.getSize();
222   if (!Size)
223     llvm_unreachable("Desc.getSize() returns 0");
224 
225   EmitInstruction(Binary, Size, STI, OS);
226 }
227 
228 /// getBranchTargetOpValue - Return binary encoding of the branch
229 /// target operand. If the machine operand requires relocation,
230 /// record the relocation and return zero.
231 unsigned MipsMCCodeEmitter::
getBranchTargetOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const232 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
233                        SmallVectorImpl<MCFixup> &Fixups,
234                        const MCSubtargetInfo &STI) const {
235   const MCOperand &MO = MI.getOperand(OpNo);
236 
237   // If the destination is an immediate, divide by 4.
238   if (MO.isImm()) return MO.getImm() >> 2;
239 
240   assert(MO.isExpr() &&
241          "getBranchTargetOpValue expects only expressions or immediates");
242 
243   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
244       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
245   Fixups.push_back(MCFixup::create(0, FixupExpression,
246                                    MCFixupKind(Mips::fixup_Mips_PC16)));
247   return 0;
248 }
249 
250 /// getBranchTargetOpValue1SImm16 - Return binary encoding of the branch
251 /// target operand. If the machine operand requires relocation,
252 /// record the relocation and return zero.
253 unsigned MipsMCCodeEmitter::
getBranchTargetOpValue1SImm16(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const254 getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo,
255                               SmallVectorImpl<MCFixup> &Fixups,
256                               const MCSubtargetInfo &STI) const {
257   const MCOperand &MO = MI.getOperand(OpNo);
258 
259   // If the destination is an immediate, divide by 2.
260   if (MO.isImm()) return MO.getImm() >> 1;
261 
262   assert(MO.isExpr() &&
263          "getBranchTargetOpValue expects only expressions or immediates");
264 
265   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
266       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
267   Fixups.push_back(MCFixup::create(0, FixupExpression,
268                                    MCFixupKind(Mips::fixup_Mips_PC16)));
269   return 0;
270 }
271 
272 /// getBranchTargetOpValueMMR6 - Return binary encoding of the branch
273 /// target operand. If the machine operand requires relocation,
274 /// record the relocation and return zero.
275 unsigned MipsMCCodeEmitter::
getBranchTargetOpValueMMR6(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const276 getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo,
277                            SmallVectorImpl<MCFixup> &Fixups,
278                            const MCSubtargetInfo &STI) const {
279   const MCOperand &MO = MI.getOperand(OpNo);
280 
281   // If the destination is an immediate, divide by 2.
282   if (MO.isImm())
283     return MO.getImm() >> 1;
284 
285   assert(MO.isExpr() &&
286          "getBranchTargetOpValueMMR6 expects only expressions or immediates");
287 
288   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
289       MO.getExpr(), MCConstantExpr::create(-2, Ctx), Ctx);
290   Fixups.push_back(MCFixup::create(0, FixupExpression,
291                                    MCFixupKind(Mips::fixup_Mips_PC16)));
292   return 0;
293 }
294 
295 /// getBranchTargetOpValueLsl2MMR6 - Return binary encoding of the branch
296 /// target operand. If the machine operand requires relocation,
297 /// record the relocation and return zero.
298 unsigned MipsMCCodeEmitter::
getBranchTargetOpValueLsl2MMR6(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const299 getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo,
300                                SmallVectorImpl<MCFixup> &Fixups,
301                                const MCSubtargetInfo &STI) const {
302   const MCOperand &MO = MI.getOperand(OpNo);
303 
304   // If the destination is an immediate, divide by 4.
305   if (MO.isImm())
306     return MO.getImm() >> 2;
307 
308   assert(MO.isExpr() &&
309          "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates");
310 
311   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
312       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
313   Fixups.push_back(MCFixup::create(0, FixupExpression,
314                                    MCFixupKind(Mips::fixup_Mips_PC16)));
315   return 0;
316 }
317 
318 /// getBranchTarget7OpValueMM - Return binary encoding of the microMIPS branch
319 /// target operand. If the machine operand requires relocation,
320 /// record the relocation and return zero.
321 unsigned MipsMCCodeEmitter::
getBranchTarget7OpValueMM(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const322 getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo,
323                           SmallVectorImpl<MCFixup> &Fixups,
324                           const MCSubtargetInfo &STI) const {
325   const MCOperand &MO = MI.getOperand(OpNo);
326 
327   // If the destination is an immediate, divide by 2.
328   if (MO.isImm()) return MO.getImm() >> 1;
329 
330   assert(MO.isExpr() &&
331          "getBranchTargetOpValueMM expects only expressions or immediates");
332 
333   const MCExpr *Expr = MO.getExpr();
334   Fixups.push_back(MCFixup::create(0, Expr,
335                                    MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1)));
336   return 0;
337 }
338 
339 /// getBranchTargetOpValueMMPC10 - Return binary encoding of the microMIPS
340 /// 10-bit branch target operand. If the machine operand requires relocation,
341 /// record the relocation and return zero.
342 unsigned MipsMCCodeEmitter::
getBranchTargetOpValueMMPC10(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const343 getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo,
344                              SmallVectorImpl<MCFixup> &Fixups,
345                              const MCSubtargetInfo &STI) const {
346   const MCOperand &MO = MI.getOperand(OpNo);
347 
348   // If the destination is an immediate, divide by 2.
349   if (MO.isImm()) return MO.getImm() >> 1;
350 
351   assert(MO.isExpr() &&
352          "getBranchTargetOpValuePC10 expects only expressions or immediates");
353 
354   const MCExpr *Expr = MO.getExpr();
355   Fixups.push_back(MCFixup::create(0, Expr,
356                    MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1)));
357   return 0;
358 }
359 
360 /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
361 /// target operand. If the machine operand requires relocation,
362 /// record the relocation and return zero.
363 unsigned MipsMCCodeEmitter::
getBranchTargetOpValueMM(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const364 getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
365                          SmallVectorImpl<MCFixup> &Fixups,
366                          const MCSubtargetInfo &STI) const {
367   const MCOperand &MO = MI.getOperand(OpNo);
368 
369   // If the destination is an immediate, divide by 2.
370   if (MO.isImm()) return MO.getImm() >> 1;
371 
372   assert(MO.isExpr() &&
373          "getBranchTargetOpValueMM expects only expressions or immediates");
374 
375   const MCExpr *Expr = MO.getExpr();
376   Fixups.push_back(MCFixup::create(0, Expr,
377                    MCFixupKind(Mips::
378                                fixup_MICROMIPS_PC16_S1)));
379   return 0;
380 }
381 
382 /// getBranchTarget21OpValue - Return binary encoding of the branch
383 /// target operand. If the machine operand requires relocation,
384 /// record the relocation and return zero.
385 unsigned MipsMCCodeEmitter::
getBranchTarget21OpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const386 getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
387                          SmallVectorImpl<MCFixup> &Fixups,
388                          const MCSubtargetInfo &STI) const {
389   const MCOperand &MO = MI.getOperand(OpNo);
390 
391   // If the destination is an immediate, divide by 4.
392   if (MO.isImm()) return MO.getImm() >> 2;
393 
394   assert(MO.isExpr() &&
395          "getBranchTarget21OpValue expects only expressions or immediates");
396 
397   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
398       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
399   Fixups.push_back(MCFixup::create(0, FixupExpression,
400                                    MCFixupKind(Mips::fixup_MIPS_PC21_S2)));
401   return 0;
402 }
403 
404 /// getBranchTarget21OpValueMM - Return binary encoding of the branch
405 /// target operand for microMIPS. If the machine operand requires
406 /// relocation, record the relocation and return zero.
407 unsigned MipsMCCodeEmitter::
getBranchTarget21OpValueMM(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const408 getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo,
409                            SmallVectorImpl<MCFixup> &Fixups,
410                            const MCSubtargetInfo &STI) const {
411   const MCOperand &MO = MI.getOperand(OpNo);
412 
413   // If the destination is an immediate, divide by 4.
414   if (MO.isImm()) return MO.getImm() >> 2;
415 
416   assert(MO.isExpr() &&
417     "getBranchTarget21OpValueMM expects only expressions or immediates");
418 
419   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
420       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
421   Fixups.push_back(MCFixup::create(0, FixupExpression,
422                                    MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1)));
423   return 0;
424 }
425 
426 /// getBranchTarget26OpValue - Return binary encoding of the branch
427 /// target operand. If the machine operand requires relocation,
428 /// record the relocation and return zero.
429 unsigned MipsMCCodeEmitter::
getBranchTarget26OpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const430 getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
431                          SmallVectorImpl<MCFixup> &Fixups,
432                          const MCSubtargetInfo &STI) const {
433   const MCOperand &MO = MI.getOperand(OpNo);
434 
435   // If the destination is an immediate, divide by 4.
436   if (MO.isImm()) return MO.getImm() >> 2;
437 
438   assert(MO.isExpr() &&
439          "getBranchTarget26OpValue expects only expressions or immediates");
440 
441   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
442       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
443   Fixups.push_back(MCFixup::create(0, FixupExpression,
444                                    MCFixupKind(Mips::fixup_MIPS_PC26_S2)));
445   return 0;
446 }
447 
448 /// getBranchTarget26OpValueMM - Return binary encoding of the branch
449 /// target operand. If the machine operand requires relocation,
450 /// record the relocation and return zero.
getBranchTarget26OpValueMM(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const451 unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM(
452     const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
453     const MCSubtargetInfo &STI) const {
454   const MCOperand &MO = MI.getOperand(OpNo);
455 
456   // If the destination is an immediate, divide by 2.
457   if (MO.isImm())
458     return MO.getImm() >> 1;
459 
460   assert(MO.isExpr() &&
461          "getBranchTarget26OpValueMM expects only expressions or immediates");
462 
463   const MCExpr *FixupExpression = MCBinaryExpr::createAdd(
464       MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx);
465   Fixups.push_back(MCFixup::create(0, FixupExpression,
466                                    MCFixupKind(Mips::fixup_MICROMIPS_PC26_S1)));
467   return 0;
468 }
469 
470 /// getJumpOffset16OpValue - Return binary encoding of the jump
471 /// target operand. If the machine operand requires relocation,
472 /// record the relocation and return zero.
473 unsigned MipsMCCodeEmitter::
getJumpOffset16OpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const474 getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo,
475                        SmallVectorImpl<MCFixup> &Fixups,
476                        const MCSubtargetInfo &STI) const {
477   const MCOperand &MO = MI.getOperand(OpNo);
478 
479   if (MO.isImm()) return MO.getImm();
480 
481   assert(MO.isExpr() &&
482          "getJumpOffset16OpValue expects only expressions or an immediate");
483 
484    // TODO: Push fixup.
485    return 0;
486 }
487 
488 /// getJumpTargetOpValue - Return binary encoding of the jump
489 /// target operand. If the machine operand requires relocation,
490 /// record the relocation and return zero.
491 unsigned MipsMCCodeEmitter::
getJumpTargetOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const492 getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
493                      SmallVectorImpl<MCFixup> &Fixups,
494                      const MCSubtargetInfo &STI) const {
495   const MCOperand &MO = MI.getOperand(OpNo);
496   // If the destination is an immediate, divide by 4.
497   if (MO.isImm()) return MO.getImm()>>2;
498 
499   assert(MO.isExpr() &&
500          "getJumpTargetOpValue expects only expressions or an immediate");
501 
502   const MCExpr *Expr = MO.getExpr();
503   Fixups.push_back(MCFixup::create(0, Expr,
504                                    MCFixupKind(Mips::fixup_Mips_26)));
505   return 0;
506 }
507 
508 unsigned MipsMCCodeEmitter::
getJumpTargetOpValueMM(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const509 getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
510                        SmallVectorImpl<MCFixup> &Fixups,
511                        const MCSubtargetInfo &STI) const {
512   const MCOperand &MO = MI.getOperand(OpNo);
513   // If the destination is an immediate, divide by 2.
514   if (MO.isImm()) return MO.getImm() >> 1;
515 
516   assert(MO.isExpr() &&
517          "getJumpTargetOpValueMM expects only expressions or an immediate");
518 
519   const MCExpr *Expr = MO.getExpr();
520   Fixups.push_back(MCFixup::create(0, Expr,
521                                    MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
522   return 0;
523 }
524 
525 unsigned MipsMCCodeEmitter::
getUImm5Lsl2Encoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const526 getUImm5Lsl2Encoding(const MCInst &MI, unsigned OpNo,
527                      SmallVectorImpl<MCFixup> &Fixups,
528                      const MCSubtargetInfo &STI) const {
529   const MCOperand &MO = MI.getOperand(OpNo);
530   if (MO.isImm()) {
531     // The immediate is encoded as 'immediate << 2'.
532     unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
533     assert((Res & 3) == 0);
534     return Res >> 2;
535   }
536 
537   assert(MO.isExpr() &&
538          "getUImm5Lsl2Encoding expects only expressions or an immediate");
539 
540   return 0;
541 }
542 
543 unsigned MipsMCCodeEmitter::
getSImm3Lsa2Value(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const544 getSImm3Lsa2Value(const MCInst &MI, unsigned OpNo,
545                   SmallVectorImpl<MCFixup> &Fixups,
546                   const MCSubtargetInfo &STI) const {
547   const MCOperand &MO = MI.getOperand(OpNo);
548   if (MO.isImm()) {
549     int Value = MO.getImm();
550     return Value >> 2;
551   }
552 
553   return 0;
554 }
555 
556 unsigned MipsMCCodeEmitter::
getUImm6Lsl2Encoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const557 getUImm6Lsl2Encoding(const MCInst &MI, unsigned OpNo,
558                      SmallVectorImpl<MCFixup> &Fixups,
559                      const MCSubtargetInfo &STI) const {
560   const MCOperand &MO = MI.getOperand(OpNo);
561   if (MO.isImm()) {
562     unsigned Value = MO.getImm();
563     return Value >> 2;
564   }
565 
566   return 0;
567 }
568 
569 unsigned MipsMCCodeEmitter::
getSImm9AddiuspValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const570 getSImm9AddiuspValue(const MCInst &MI, unsigned OpNo,
571                      SmallVectorImpl<MCFixup> &Fixups,
572                      const MCSubtargetInfo &STI) const {
573   const MCOperand &MO = MI.getOperand(OpNo);
574   if (MO.isImm()) {
575     unsigned Binary = (MO.getImm() >> 2) & 0x0000ffff;
576     return (((Binary & 0x8000) >> 7) | (Binary & 0x00ff));
577   }
578 
579   return 0;
580 }
581 
582 unsigned MipsMCCodeEmitter::
getExprOpValue(const MCExpr * Expr,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const583 getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
584                const MCSubtargetInfo &STI) const {
585   int64_t Res;
586 
587   if (Expr->evaluateAsAbsolute(Res))
588     return Res;
589 
590   MCExpr::ExprKind Kind = Expr->getKind();
591   if (Kind == MCExpr::Constant) {
592     return cast<MCConstantExpr>(Expr)->getValue();
593   }
594 
595   if (Kind == MCExpr::Binary) {
596     unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
597     Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
598     return Res;
599   }
600 
601   if (Kind == MCExpr::Target) {
602     const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
603 
604     Mips::Fixups FixupKind = Mips::Fixups(0);
605     switch (MipsExpr->getKind()) {
606     case MipsMCExpr::MEK_None:
607     case MipsMCExpr::MEK_Special:
608       llvm_unreachable("Unhandled fixup kind!");
609       break;
610     case MipsMCExpr::MEK_CALL_HI16:
611       FixupKind = Mips::fixup_Mips_CALL_HI16;
612       break;
613     case MipsMCExpr::MEK_CALL_LO16:
614       FixupKind = Mips::fixup_Mips_CALL_LO16;
615       break;
616     case MipsMCExpr::MEK_DTPREL_HI:
617       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
618                                    : Mips::fixup_Mips_DTPREL_HI;
619       break;
620     case MipsMCExpr::MEK_DTPREL_LO:
621       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
622                                    : Mips::fixup_Mips_DTPREL_LO;
623       break;
624     case MipsMCExpr::MEK_GOTTPREL:
625       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOTTPREL
626                                    : Mips::fixup_Mips_GOTTPREL;
627       break;
628     case MipsMCExpr::MEK_GOT:
629       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
630                                    : Mips::fixup_Mips_GOT;
631       break;
632     case MipsMCExpr::MEK_GOT_CALL:
633       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16
634                                    : Mips::fixup_Mips_CALL16;
635       break;
636     case MipsMCExpr::MEK_GOT_DISP:
637       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP
638                                    : Mips::fixup_Mips_GOT_DISP;
639       break;
640     case MipsMCExpr::MEK_GOT_HI16:
641       FixupKind = Mips::fixup_Mips_GOT_HI16;
642       break;
643     case MipsMCExpr::MEK_GOT_LO16:
644       FixupKind = Mips::fixup_Mips_GOT_LO16;
645       break;
646     case MipsMCExpr::MEK_GOT_PAGE:
647       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE
648                                    : Mips::fixup_Mips_GOT_PAGE;
649       break;
650     case MipsMCExpr::MEK_GOT_OFST:
651       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST
652                                    : Mips::fixup_Mips_GOT_OFST;
653       break;
654     case MipsMCExpr::MEK_GPREL:
655       FixupKind = Mips::fixup_Mips_GPREL16;
656       break;
657     case MipsMCExpr::MEK_LO:
658       // Check for %lo(%neg(%gp_rel(X)))
659       if (MipsExpr->isGpOff())
660         FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_LO
661                                      : Mips::fixup_Mips_GPOFF_LO;
662       else
663         FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
664                                      : Mips::fixup_Mips_LO16;
665       break;
666     case MipsMCExpr::MEK_HIGHEST:
667       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHEST
668                                    : Mips::fixup_Mips_HIGHEST;
669       break;
670     case MipsMCExpr::MEK_HIGHER:
671       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHER
672                                    : Mips::fixup_Mips_HIGHER;
673       break;
674     case MipsMCExpr::MEK_HI:
675       // Check for %hi(%neg(%gp_rel(X)))
676       if (MipsExpr->isGpOff())
677         FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_HI
678                                      : Mips::fixup_Mips_GPOFF_HI;
679       else
680         FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
681                                      : Mips::fixup_Mips_HI16;
682       break;
683     case MipsMCExpr::MEK_PCREL_HI16:
684       FixupKind = Mips::fixup_MIPS_PCHI16;
685       break;
686     case MipsMCExpr::MEK_PCREL_LO16:
687       FixupKind = Mips::fixup_MIPS_PCLO16;
688       break;
689     case MipsMCExpr::MEK_TLSGD:
690       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD
691                                    : Mips::fixup_Mips_TLSGD;
692       break;
693     case MipsMCExpr::MEK_TLSLDM:
694       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM
695                                    : Mips::fixup_Mips_TLSLDM;
696       break;
697     case MipsMCExpr::MEK_TPREL_HI:
698       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
699                                    : Mips::fixup_Mips_TPREL_HI;
700       break;
701     case MipsMCExpr::MEK_TPREL_LO:
702       FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
703                                    : Mips::fixup_Mips_TPREL_LO;
704       break;
705     case MipsMCExpr::MEK_NEG:
706       FixupKind =
707           isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB;
708       break;
709     }
710     Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind)));
711     return 0;
712   }
713 
714   if (Kind == MCExpr::SymbolRef) {
715     Mips::Fixups FixupKind = Mips::Fixups(0);
716 
717     switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
718     default: llvm_unreachable("Unknown fixup kind!");
719       break;
720     case MCSymbolRefExpr::VK_None:
721       FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64.
722       break;
723     } // switch
724 
725     Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
726     return 0;
727   }
728   return 0;
729 }
730 
731 /// getMachineOpValue - Return binary encoding of operand. If the machine
732 /// operand requires relocation, record the relocation and return zero.
733 unsigned MipsMCCodeEmitter::
getMachineOpValue(const MCInst & MI,const MCOperand & MO,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const734 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
735                   SmallVectorImpl<MCFixup> &Fixups,
736                   const MCSubtargetInfo &STI) const {
737   if (MO.isReg()) {
738     unsigned Reg = MO.getReg();
739     unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
740     return RegNo;
741   } else if (MO.isImm()) {
742     return static_cast<unsigned>(MO.getImm());
743   } else if (MO.isFPImm()) {
744     return static_cast<unsigned>(APFloat(MO.getFPImm())
745         .bitcastToAPInt().getHiBits(32).getLimitedValue());
746   }
747   // MO must be an Expr.
748   assert(MO.isExpr());
749   return getExprOpValue(MO.getExpr(),Fixups, STI);
750 }
751 
752 /// Return binary encoding of memory related operand.
753 /// If the offset operand requires relocation, record the relocation.
754 template <unsigned ShiftAmount>
getMemEncoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const755 unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
756                                            SmallVectorImpl<MCFixup> &Fixups,
757                                            const MCSubtargetInfo &STI) const {
758   // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
759   assert(MI.getOperand(OpNo).isReg());
760   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
761   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
762 
763   // Apply the scale factor if there is one.
764   OffBits >>= ShiftAmount;
765 
766   return (OffBits & 0xFFFF) | RegBits;
767 }
768 
769 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm4(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const770 getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo,
771                      SmallVectorImpl<MCFixup> &Fixups,
772                      const MCSubtargetInfo &STI) const {
773   // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
774   assert(MI.getOperand(OpNo).isReg());
775   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
776                                        Fixups, STI) << 4;
777   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
778                                        Fixups, STI);
779 
780   return (OffBits & 0xF) | RegBits;
781 }
782 
783 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm4Lsl1(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const784 getMemEncodingMMImm4Lsl1(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) >> 1;
793 
794   return (OffBits & 0xF) | RegBits;
795 }
796 
797 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm4Lsl2(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const798 getMemEncodingMMImm4Lsl2(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) >> 2;
807 
808   return (OffBits & 0xF) | RegBits;
809 }
810 
811 unsigned MipsMCCodeEmitter::
getMemEncodingMMSPImm5Lsl2(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const812 getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
813                            SmallVectorImpl<MCFixup> &Fixups,
814                            const MCSubtargetInfo &STI) const {
815   // Register is encoded in bits 9-5, offset is encoded in bits 4-0.
816   assert(MI.getOperand(OpNo).isReg() &&
817          (MI.getOperand(OpNo).getReg() == Mips::SP ||
818          MI.getOperand(OpNo).getReg() == Mips::SP_64) &&
819          "Unexpected base register!");
820   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
821                                        Fixups, STI) >> 2;
822 
823   return OffBits & 0x1F;
824 }
825 
826 unsigned MipsMCCodeEmitter::
getMemEncodingMMGPImm7Lsl2(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const827 getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
828                            SmallVectorImpl<MCFixup> &Fixups,
829                            const MCSubtargetInfo &STI) const {
830   // Register is encoded in bits 9-7, offset is encoded in bits 6-0.
831   assert(MI.getOperand(OpNo).isReg() &&
832          MI.getOperand(OpNo).getReg() == Mips::GP &&
833          "Unexpected base register!");
834 
835   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
836                                        Fixups, STI) >> 2;
837 
838   return OffBits & 0x7F;
839 }
840 
841 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm9(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const842 getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo,
843                      SmallVectorImpl<MCFixup> &Fixups,
844                      const MCSubtargetInfo &STI) const {
845   // Base register is encoded in bits 20-16, offset is encoded in bits 8-0.
846   assert(MI.getOperand(OpNo).isReg());
847   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
848                                        STI) << 16;
849   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI);
850 
851   return (OffBits & 0x1FF) | RegBits;
852 }
853 
854 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm11(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const855 getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo,
856                       SmallVectorImpl<MCFixup> &Fixups,
857                       const MCSubtargetInfo &STI) const {
858   // Base register is encoded in bits 20-16, offset is encoded in bits 10-0.
859   assert(MI.getOperand(OpNo).isReg());
860   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
861                                        STI) << 16;
862   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
863 
864   return (OffBits & 0x07FF) | RegBits;
865 }
866 
867 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm12(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const868 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
869                       SmallVectorImpl<MCFixup> &Fixups,
870                       const MCSubtargetInfo &STI) const {
871   // opNum can be invalid if instruction had reglist as operand.
872   // MemOperand is always last operand of instruction (base + offset).
873   switch (MI.getOpcode()) {
874   default:
875     break;
876   case Mips::SWM32_MM:
877   case Mips::LWM32_MM:
878     OpNo = MI.getNumOperands() - 2;
879     break;
880   }
881 
882   // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
883   assert(MI.getOperand(OpNo).isReg());
884   unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
885   unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
886 
887   return (OffBits & 0x0FFF) | RegBits;
888 }
889 
890 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm16(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const891 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::
getMemEncodingMMImm4sp(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const904 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
getSizeInsEncoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const932 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
getUImmWithOffsetEncoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const945 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
getSimm19Lsl2Encoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const955 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
getSimm18Lsl3Encoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const977 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
getUImm3Mod8Encoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const999 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
getUImm4AndValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1008 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
getRegisterListOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1036 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
getRegisterListOpValue16(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1056 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
getMovePRegPairOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1063 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
getMovePRegSingleOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1097 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
getSimm23Lsl2Encoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1120 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