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