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