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