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