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.isFPImm()) {
744 return static_cast<unsigned>(APFloat(MO.getFPImm())
745 .bitcastToAPInt().getHiBits(32).getLimitedValue());
746 }
747 // MO must be an Expr.
748 assert(MO.isExpr());
749 return getExprOpValue(MO.getExpr(),Fixups, STI);
750 }
751
752 /// Return binary encoding of memory related operand.
753 /// If the offset operand requires relocation, record the relocation.
754 template <unsigned ShiftAmount>
getMemEncoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const755 unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
756 SmallVectorImpl<MCFixup> &Fixups,
757 const MCSubtargetInfo &STI) const {
758 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
759 assert(MI.getOperand(OpNo).isReg());
760 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI)
761 << 16;
762 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
763
764 // Apply the scale factor if there is one.
765 OffBits >>= ShiftAmount;
766
767 return (OffBits & 0xFFFF) | RegBits;
768 }
769
770 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm4(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const771 getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo,
772 SmallVectorImpl<MCFixup> &Fixups,
773 const MCSubtargetInfo &STI) const {
774 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
775 assert(MI.getOperand(OpNo).isReg());
776 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
777 Fixups, STI) << 4;
778 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
779 Fixups, STI);
780
781 return (OffBits & 0xF) | RegBits;
782 }
783
784 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm4Lsl1(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const785 getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo,
786 SmallVectorImpl<MCFixup> &Fixups,
787 const MCSubtargetInfo &STI) const {
788 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
789 assert(MI.getOperand(OpNo).isReg());
790 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
791 Fixups, STI) << 4;
792 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
793 Fixups, STI) >> 1;
794
795 return (OffBits & 0xF) | RegBits;
796 }
797
798 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm4Lsl2(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const799 getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo,
800 SmallVectorImpl<MCFixup> &Fixups,
801 const MCSubtargetInfo &STI) const {
802 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
803 assert(MI.getOperand(OpNo).isReg());
804 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
805 Fixups, STI) << 4;
806 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
807 Fixups, STI) >> 2;
808
809 return (OffBits & 0xF) | RegBits;
810 }
811
812 unsigned MipsMCCodeEmitter::
getMemEncodingMMSPImm5Lsl2(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const813 getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
814 SmallVectorImpl<MCFixup> &Fixups,
815 const MCSubtargetInfo &STI) const {
816 // Register is encoded in bits 9-5, offset is encoded in bits 4-0.
817 assert(MI.getOperand(OpNo).isReg() &&
818 (MI.getOperand(OpNo).getReg() == Mips::SP ||
819 MI.getOperand(OpNo).getReg() == Mips::SP_64) &&
820 "Unexpected base register!");
821 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
822 Fixups, STI) >> 2;
823
824 return OffBits & 0x1F;
825 }
826
827 unsigned MipsMCCodeEmitter::
getMemEncodingMMGPImm7Lsl2(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const828 getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
829 SmallVectorImpl<MCFixup> &Fixups,
830 const MCSubtargetInfo &STI) const {
831 // Register is encoded in bits 9-7, offset is encoded in bits 6-0.
832 assert(MI.getOperand(OpNo).isReg() &&
833 MI.getOperand(OpNo).getReg() == Mips::GP &&
834 "Unexpected base register!");
835
836 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
837 Fixups, STI) >> 2;
838
839 return OffBits & 0x7F;
840 }
841
842 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm9(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const843 getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo,
844 SmallVectorImpl<MCFixup> &Fixups,
845 const MCSubtargetInfo &STI) const {
846 // Base register is encoded in bits 20-16, offset is encoded in bits 8-0.
847 assert(MI.getOperand(OpNo).isReg());
848 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
849 STI) << 16;
850 unsigned OffBits =
851 getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI);
852
853 return (OffBits & 0x1FF) | RegBits;
854 }
855
856 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm11(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const857 getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo,
858 SmallVectorImpl<MCFixup> &Fixups,
859 const MCSubtargetInfo &STI) const {
860 // Base register is encoded in bits 20-16, offset is encoded in bits 10-0.
861 assert(MI.getOperand(OpNo).isReg());
862 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
863 STI) << 16;
864 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
865
866 return (OffBits & 0x07FF) | RegBits;
867 }
868
869 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm12(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const870 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
871 SmallVectorImpl<MCFixup> &Fixups,
872 const MCSubtargetInfo &STI) const {
873 // opNum can be invalid if instruction had reglist as operand.
874 // MemOperand is always last operand of instruction (base + offset).
875 switch (MI.getOpcode()) {
876 default:
877 break;
878 case Mips::SWM32_MM:
879 case Mips::LWM32_MM:
880 OpNo = MI.getNumOperands() - 2;
881 break;
882 }
883
884 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
885 assert(MI.getOperand(OpNo).isReg());
886 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI)
887 << 16;
888 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
889
890 return (OffBits & 0x0FFF) | RegBits;
891 }
892
893 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm16(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const894 getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo,
895 SmallVectorImpl<MCFixup> &Fixups,
896 const MCSubtargetInfo &STI) const {
897 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
898 assert(MI.getOperand(OpNo).isReg());
899 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
900 STI) << 16;
901 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
902
903 return (OffBits & 0xFFFF) | RegBits;
904 }
905
906 unsigned MipsMCCodeEmitter::
getMemEncodingMMImm4sp(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const907 getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
908 SmallVectorImpl<MCFixup> &Fixups,
909 const MCSubtargetInfo &STI) const {
910 // opNum can be invalid if instruction had reglist as operand
911 // MemOperand is always last operand of instruction (base + offset)
912 switch (MI.getOpcode()) {
913 default:
914 break;
915 case Mips::SWM16_MM:
916 case Mips::SWM16_MMR6:
917 case Mips::LWM16_MM:
918 case Mips::LWM16_MMR6:
919 OpNo = MI.getNumOperands() - 2;
920 break;
921 }
922
923 // Offset is encoded in bits 4-0.
924 assert(MI.getOperand(OpNo).isReg());
925 // Base register is always SP - thus it is not encoded.
926 assert(MI.getOperand(OpNo+1).isImm());
927 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
928
929 return ((OffBits >> 2) & 0x0F);
930 }
931
932 // FIXME: should be called getMSBEncoding
933 //
934 unsigned
getSizeInsEncoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const935 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
936 SmallVectorImpl<MCFixup> &Fixups,
937 const MCSubtargetInfo &STI) const {
938 assert(MI.getOperand(OpNo-1).isImm());
939 assert(MI.getOperand(OpNo).isImm());
940 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI);
941 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
942
943 return Position + Size - 1;
944 }
945
946 template <unsigned Bits, int Offset>
947 unsigned
getUImmWithOffsetEncoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const948 MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo,
949 SmallVectorImpl<MCFixup> &Fixups,
950 const MCSubtargetInfo &STI) const {
951 assert(MI.getOperand(OpNo).isImm());
952 unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
953 Value -= Offset;
954 return Value;
955 }
956
957 unsigned
getSimm19Lsl2Encoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const958 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
959 SmallVectorImpl<MCFixup> &Fixups,
960 const MCSubtargetInfo &STI) const {
961 const MCOperand &MO = MI.getOperand(OpNo);
962 if (MO.isImm()) {
963 // The immediate is encoded as 'immediate << 2'.
964 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
965 assert((Res & 3) == 0);
966 return Res >> 2;
967 }
968
969 assert(MO.isExpr() &&
970 "getSimm19Lsl2Encoding expects only expressions or an immediate");
971
972 const MCExpr *Expr = MO.getExpr();
973 Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2
974 : Mips::fixup_MIPS_PC19_S2;
975 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
976 return 0;
977 }
978
979 unsigned
getSimm18Lsl3Encoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const980 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
981 SmallVectorImpl<MCFixup> &Fixups,
982 const MCSubtargetInfo &STI) const {
983 const MCOperand &MO = MI.getOperand(OpNo);
984 if (MO.isImm()) {
985 // The immediate is encoded as 'immediate << 3'.
986 unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
987 assert((Res & 7) == 0);
988 return Res >> 3;
989 }
990
991 assert(MO.isExpr() &&
992 "getSimm18Lsl2Encoding expects only expressions or an immediate");
993
994 const MCExpr *Expr = MO.getExpr();
995 Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3
996 : Mips::fixup_MIPS_PC18_S3;
997 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
998 return 0;
999 }
1000
1001 unsigned
getUImm3Mod8Encoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1002 MipsMCCodeEmitter::getUImm3Mod8Encoding(const MCInst &MI, unsigned OpNo,
1003 SmallVectorImpl<MCFixup> &Fixups,
1004 const MCSubtargetInfo &STI) const {
1005 assert(MI.getOperand(OpNo).isImm());
1006 const MCOperand &MO = MI.getOperand(OpNo);
1007 return MO.getImm() % 8;
1008 }
1009
1010 unsigned
getUImm4AndValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1011 MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo,
1012 SmallVectorImpl<MCFixup> &Fixups,
1013 const MCSubtargetInfo &STI) const {
1014 assert(MI.getOperand(OpNo).isImm());
1015 const MCOperand &MO = MI.getOperand(OpNo);
1016 unsigned Value = MO.getImm();
1017 switch (Value) {
1018 case 128: return 0x0;
1019 case 1: return 0x1;
1020 case 2: return 0x2;
1021 case 3: return 0x3;
1022 case 4: return 0x4;
1023 case 7: return 0x5;
1024 case 8: return 0x6;
1025 case 15: return 0x7;
1026 case 16: return 0x8;
1027 case 31: return 0x9;
1028 case 32: return 0xa;
1029 case 63: return 0xb;
1030 case 64: return 0xc;
1031 case 255: return 0xd;
1032 case 32768: return 0xe;
1033 case 65535: return 0xf;
1034 }
1035 llvm_unreachable("Unexpected value");
1036 }
1037
1038 unsigned
getRegisterListOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1039 MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo,
1040 SmallVectorImpl<MCFixup> &Fixups,
1041 const MCSubtargetInfo &STI) const {
1042 unsigned res = 0;
1043
1044 // Register list operand is always first operand of instruction and it is
1045 // placed before memory operand (register + imm).
1046
1047 for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) {
1048 unsigned Reg = MI.getOperand(I).getReg();
1049 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
1050 if (RegNo != 31)
1051 res++;
1052 else
1053 res |= 0x10;
1054 }
1055 return res;
1056 }
1057
1058 unsigned
getRegisterListOpValue16(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1059 MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
1060 SmallVectorImpl<MCFixup> &Fixups,
1061 const MCSubtargetInfo &STI) const {
1062 return (MI.getNumOperands() - 4);
1063 }
1064
1065 unsigned
getMovePRegPairOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1066 MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
1067 SmallVectorImpl<MCFixup> &Fixups,
1068 const MCSubtargetInfo &STI) const {
1069 unsigned res = 0;
1070
1071 if (MI.getOperand(0).getReg() == Mips::A1 &&
1072 MI.getOperand(1).getReg() == Mips::A2)
1073 res = 0;
1074 else if (MI.getOperand(0).getReg() == Mips::A1 &&
1075 MI.getOperand(1).getReg() == Mips::A3)
1076 res = 1;
1077 else if (MI.getOperand(0).getReg() == Mips::A2 &&
1078 MI.getOperand(1).getReg() == Mips::A3)
1079 res = 2;
1080 else if (MI.getOperand(0).getReg() == Mips::A0 &&
1081 MI.getOperand(1).getReg() == Mips::S5)
1082 res = 3;
1083 else if (MI.getOperand(0).getReg() == Mips::A0 &&
1084 MI.getOperand(1).getReg() == Mips::S6)
1085 res = 4;
1086 else if (MI.getOperand(0).getReg() == Mips::A0 &&
1087 MI.getOperand(1).getReg() == Mips::A1)
1088 res = 5;
1089 else if (MI.getOperand(0).getReg() == Mips::A0 &&
1090 MI.getOperand(1).getReg() == Mips::A2)
1091 res = 6;
1092 else if (MI.getOperand(0).getReg() == Mips::A0 &&
1093 MI.getOperand(1).getReg() == Mips::A3)
1094 res = 7;
1095
1096 return res;
1097 }
1098
1099 unsigned
getMovePRegSingleOpValue(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1100 MipsMCCodeEmitter::getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo,
1101 SmallVectorImpl<MCFixup> &Fixups,
1102 const MCSubtargetInfo &STI) const {
1103 assert(((OpNo == 2) || (OpNo == 3)) &&
1104 "Unexpected OpNo for movep operand encoding!");
1105
1106 MCOperand Op = MI.getOperand(OpNo);
1107 assert(Op.isReg() && "Operand of movep is not a register!");
1108 switch (Op.getReg()) {
1109 default:
1110 llvm_unreachable("Unknown register for movep!");
1111 case Mips::ZERO: return 0;
1112 case Mips::S1: return 1;
1113 case Mips::V0: return 2;
1114 case Mips::V1: return 3;
1115 case Mips::S0: return 4;
1116 case Mips::S2: return 5;
1117 case Mips::S3: return 6;
1118 case Mips::S4: return 7;
1119 }
1120 }
1121
1122 unsigned
getSimm23Lsl2Encoding(const MCInst & MI,unsigned OpNo,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1123 MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
1124 SmallVectorImpl<MCFixup> &Fixups,
1125 const MCSubtargetInfo &STI) const {
1126 const MCOperand &MO = MI.getOperand(OpNo);
1127 assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate");
1128 // The immediate is encoded as 'immediate >> 2'.
1129 unsigned Res = static_cast<unsigned>(MO.getImm());
1130 assert((Res & 3) == 0);
1131 return Res >> 2;
1132 }
1133
1134 #include "MipsGenMCCodeEmitter.inc"
1135