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