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