[InstCombine] Signed saturation patterns
[llvm-complete.git] / lib / Target / Mips / MCTargetDesc / MipsMCCodeEmitter.cpp
blob142e9cebb79e9a816f55a99bd7a4b10dae74a1e3
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.
11 //===----------------------------------------------------------------------===//
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>
34 using namespace llvm;
36 #define DEBUG_TYPE "mccodeemitter"
38 #define GET_INSTRMAP_INFO
39 #include "MipsGenInstrInfo.inc"
40 #undef GET_INSTRMAP_INFO
42 namespace llvm {
44 MCCodeEmitter *createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
45 const MCRegisterInfo &MRI,
46 MCContext &Ctx) {
47 return new MipsMCCodeEmitter(MCII, Ctx, false);
50 MCCodeEmitter *createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
51 const MCRegisterInfo &MRI,
52 MCContext &Ctx) {
53 return new MipsMCCodeEmitter(MCII, Ctx, true);
56 } // end namespace llvm
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
60 static void LowerLargeShift(MCInst& Inst) {
61 assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
62 assert(Inst.getOperand(2).isImm());
64 int64_t Shift = Inst.getOperand(2).getImm();
65 if (Shift <= 31)
66 return; // Do nothing
67 Shift -= 32;
69 // saminus32
70 Inst.getOperand(2).setImm(Shift);
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;
91 // Fix a bad compact branch encoding for beqc/bnec.
92 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();
98 unsigned Reg0 = Ctx.getRegisterInfo()->getEncodingValue(RegOp0);
99 unsigned Reg1 = Ctx.getRegisterInfo()->getEncodingValue(RegOp1);
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!");
116 Inst.getOperand(0).setReg(RegOp1);
117 Inst.getOperand(1).setReg(RegOp0);
120 bool MipsMCCodeEmitter::isMicroMips(const MCSubtargetInfo &STI) const {
121 return STI.getFeatureBits()[Mips::FeatureMicroMips];
124 bool MipsMCCodeEmitter::isMips32r6(const MCSubtargetInfo &STI) const {
125 return STI.getFeatureBits()[Mips::FeatureMips32r6];
128 void MipsMCCodeEmitter::EmitByte(unsigned char C, raw_ostream &OS) const {
129 OS << (char)C;
132 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);
150 /// encodeInstruction - Emit the instruction.
151 /// Size the instruction with Desc.getSize().
152 void MipsMCCodeEmitter::
153 encodeInstruction(const MCInst &MI, raw_ostream &OS,
154 SmallVectorImpl<MCFixup> &Fixups,
155 const MCSubtargetInfo &STI) const
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);
182 unsigned long N = Fixups.size();
183 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
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()");
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);
200 else
201 NewOpcode = Mips::Std2MicroMips(Opcode, Mips::Arch_micromips);
203 // Check whether it is Dsp instruction.
204 if (NewOpcode == -1)
205 NewOpcode = Mips::Dsp2MicroMips(Opcode, Mips::Arch_mmdsp);
207 if (NewOpcode != -1) {
208 if (Fixups.size() > N)
209 Fixups.pop_back();
211 TmpInst.setOpcode (NewOpcode);
212 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
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);
222 const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
224 // Get byte count of instruction
225 unsigned Size = Desc.getSize();
226 if (!Size)
227 llvm_unreachable("Desc.getSize() returns 0");
229 EmitInstruction(Binary, Size, STI, OS);
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::
236 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
237 SmallVectorImpl<MCFixup> &Fixups,
238 const MCSubtargetInfo &STI) const {
239 const MCOperand &MO = MI.getOperand(OpNo);
241 // If the destination is an immediate, divide by 4.
242 if (MO.isImm()) return MO.getImm() >> 2;
244 assert(MO.isExpr() &&
245 "getBranchTargetOpValue expects only expressions or immediates");
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;
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::
258 getBranchTargetOpValue1SImm16(const MCInst &MI, unsigned OpNo,
259 SmallVectorImpl<MCFixup> &Fixups,
260 const MCSubtargetInfo &STI) const {
261 const MCOperand &MO = MI.getOperand(OpNo);
263 // If the destination is an immediate, divide by 2.
264 if (MO.isImm()) return MO.getImm() >> 1;
266 assert(MO.isExpr() &&
267 "getBranchTargetOpValue expects only expressions or immediates");
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;
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::
280 getBranchTargetOpValueMMR6(const MCInst &MI, unsigned OpNo,
281 SmallVectorImpl<MCFixup> &Fixups,
282 const MCSubtargetInfo &STI) const {
283 const MCOperand &MO = MI.getOperand(OpNo);
285 // If the destination is an immediate, divide by 2.
286 if (MO.isImm())
287 return MO.getImm() >> 1;
289 assert(MO.isExpr() &&
290 "getBranchTargetOpValueMMR6 expects only expressions or immediates");
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;
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::
303 getBranchTargetOpValueLsl2MMR6(const MCInst &MI, unsigned OpNo,
304 SmallVectorImpl<MCFixup> &Fixups,
305 const MCSubtargetInfo &STI) const {
306 const MCOperand &MO = MI.getOperand(OpNo);
308 // If the destination is an immediate, divide by 4.
309 if (MO.isImm())
310 return MO.getImm() >> 2;
312 assert(MO.isExpr() &&
313 "getBranchTargetOpValueLsl2MMR6 expects only expressions or immediates");
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;
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::
326 getBranchTarget7OpValueMM(const MCInst &MI, unsigned OpNo,
327 SmallVectorImpl<MCFixup> &Fixups,
328 const MCSubtargetInfo &STI) const {
329 const MCOperand &MO = MI.getOperand(OpNo);
331 // If the destination is an immediate, divide by 2.
332 if (MO.isImm()) return MO.getImm() >> 1;
334 assert(MO.isExpr() &&
335 "getBranchTargetOpValueMM expects only expressions or immediates");
337 const MCExpr *Expr = MO.getExpr();
338 Fixups.push_back(MCFixup::create(0, Expr,
339 MCFixupKind(Mips::fixup_MICROMIPS_PC7_S1)));
340 return 0;
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::
347 getBranchTargetOpValueMMPC10(const MCInst &MI, unsigned OpNo,
348 SmallVectorImpl<MCFixup> &Fixups,
349 const MCSubtargetInfo &STI) const {
350 const MCOperand &MO = MI.getOperand(OpNo);
352 // If the destination is an immediate, divide by 2.
353 if (MO.isImm()) return MO.getImm() >> 1;
355 assert(MO.isExpr() &&
356 "getBranchTargetOpValuePC10 expects only expressions or immediates");
358 const MCExpr *Expr = MO.getExpr();
359 Fixups.push_back(MCFixup::create(0, Expr,
360 MCFixupKind(Mips::fixup_MICROMIPS_PC10_S1)));
361 return 0;
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::
368 getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
369 SmallVectorImpl<MCFixup> &Fixups,
370 const MCSubtargetInfo &STI) const {
371 const MCOperand &MO = MI.getOperand(OpNo);
373 // If the destination is an immediate, divide by 2.
374 if (MO.isImm()) return MO.getImm() >> 1;
376 assert(MO.isExpr() &&
377 "getBranchTargetOpValueMM expects only expressions or immediates");
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;
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::
390 getBranchTarget21OpValue(const MCInst &MI, unsigned OpNo,
391 SmallVectorImpl<MCFixup> &Fixups,
392 const MCSubtargetInfo &STI) const {
393 const MCOperand &MO = MI.getOperand(OpNo);
395 // If the destination is an immediate, divide by 4.
396 if (MO.isImm()) return MO.getImm() >> 2;
398 assert(MO.isExpr() &&
399 "getBranchTarget21OpValue expects only expressions or immediates");
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;
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::
412 getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo,
413 SmallVectorImpl<MCFixup> &Fixups,
414 const MCSubtargetInfo &STI) const {
415 const MCOperand &MO = MI.getOperand(OpNo);
417 // If the destination is an immediate, divide by 4.
418 if (MO.isImm()) return MO.getImm() >> 2;
420 assert(MO.isExpr() &&
421 "getBranchTarget21OpValueMM expects only expressions or immediates");
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;
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::
434 getBranchTarget26OpValue(const MCInst &MI, unsigned OpNo,
435 SmallVectorImpl<MCFixup> &Fixups,
436 const MCSubtargetInfo &STI) const {
437 const MCOperand &MO = MI.getOperand(OpNo);
439 // If the destination is an immediate, divide by 4.
440 if (MO.isImm()) return MO.getImm() >> 2;
442 assert(MO.isExpr() &&
443 "getBranchTarget26OpValue expects only expressions or immediates");
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;
452 /// getBranchTarget26OpValueMM - Return binary encoding of the branch
453 /// target operand. If the machine operand requires relocation,
454 /// record the relocation and return zero.
455 unsigned MipsMCCodeEmitter::getBranchTarget26OpValueMM(
456 const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
457 const MCSubtargetInfo &STI) const {
458 const MCOperand &MO = MI.getOperand(OpNo);
460 // If the destination is an immediate, divide by 2.
461 if (MO.isImm())
462 return MO.getImm() >> 1;
464 assert(MO.isExpr() &&
465 "getBranchTarget26OpValueMM expects only expressions or immediates");
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;
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::
478 getJumpOffset16OpValue(const MCInst &MI, unsigned OpNo,
479 SmallVectorImpl<MCFixup> &Fixups,
480 const MCSubtargetInfo &STI) const {
481 const MCOperand &MO = MI.getOperand(OpNo);
483 if (MO.isImm()) return MO.getImm();
485 assert(MO.isExpr() &&
486 "getJumpOffset16OpValue expects only expressions or an immediate");
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;
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::
499 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;
506 assert(MO.isExpr() &&
507 "getJumpTargetOpValue expects only expressions or an immediate");
509 const MCExpr *Expr = MO.getExpr();
510 Fixups.push_back(MCFixup::create(0, Expr,
511 MCFixupKind(Mips::fixup_Mips_26)));
512 return 0;
515 unsigned MipsMCCodeEmitter::
516 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;
523 assert(MO.isExpr() &&
524 "getJumpTargetOpValueMM expects only expressions or an immediate");
526 const MCExpr *Expr = MO.getExpr();
527 Fixups.push_back(MCFixup::create(0, Expr,
528 MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
529 return 0;
532 unsigned MipsMCCodeEmitter::
533 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;
544 assert(MO.isExpr() &&
545 "getUImm5Lsl2Encoding expects only expressions or an immediate");
547 return 0;
550 unsigned MipsMCCodeEmitter::
551 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;
560 return 0;
563 unsigned MipsMCCodeEmitter::
564 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;
573 return 0;
576 unsigned MipsMCCodeEmitter::
577 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));
586 return 0;
589 unsigned MipsMCCodeEmitter::
590 getExprOpValue(const MCExpr *Expr, SmallVectorImpl<MCFixup> &Fixups,
591 const MCSubtargetInfo &STI) const {
592 int64_t Res;
594 if (Expr->evaluateAsAbsolute(Res))
595 return Res;
597 MCExpr::ExprKind Kind = Expr->getKind();
598 if (Kind == MCExpr::Constant) {
599 return cast<MCConstantExpr>(Expr)->getValue();
602 if (Kind == MCExpr::Binary) {
603 unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
604 Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
605 return Res;
608 if (Kind == MCExpr::Target) {
609 const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
611 Mips::Fixups FixupKind = Mips::Fixups(0);
612 switch (MipsExpr->getKind()) {
613 case MipsMCExpr::MEK_None:
614 case MipsMCExpr::MEK_Special:
615 llvm_unreachable("Unhandled fixup kind!");
616 break;
617 case MipsMCExpr::MEK_DTPREL:
618 // MEK_DTPREL is used for marking TLS DIEExpr only
619 // and contains a regular sub-expression.
620 return getExprOpValue(MipsExpr->getSubExpr(), Fixups, STI);
621 case MipsMCExpr::MEK_CALL_HI16:
622 FixupKind = Mips::fixup_Mips_CALL_HI16;
623 break;
624 case MipsMCExpr::MEK_CALL_LO16:
625 FixupKind = Mips::fixup_Mips_CALL_LO16;
626 break;
627 case MipsMCExpr::MEK_DTPREL_HI:
628 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
629 : Mips::fixup_Mips_DTPREL_HI;
630 break;
631 case MipsMCExpr::MEK_DTPREL_LO:
632 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
633 : Mips::fixup_Mips_DTPREL_LO;
634 break;
635 case MipsMCExpr::MEK_GOTTPREL:
636 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOTTPREL
637 : Mips::fixup_Mips_GOTTPREL;
638 break;
639 case MipsMCExpr::MEK_GOT:
640 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
641 : Mips::fixup_Mips_GOT;
642 break;
643 case MipsMCExpr::MEK_GOT_CALL:
644 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16
645 : Mips::fixup_Mips_CALL16;
646 break;
647 case MipsMCExpr::MEK_GOT_DISP:
648 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP
649 : Mips::fixup_Mips_GOT_DISP;
650 break;
651 case MipsMCExpr::MEK_GOT_HI16:
652 FixupKind = Mips::fixup_Mips_GOT_HI16;
653 break;
654 case MipsMCExpr::MEK_GOT_LO16:
655 FixupKind = Mips::fixup_Mips_GOT_LO16;
656 break;
657 case MipsMCExpr::MEK_GOT_PAGE:
658 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE
659 : Mips::fixup_Mips_GOT_PAGE;
660 break;
661 case MipsMCExpr::MEK_GOT_OFST:
662 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST
663 : Mips::fixup_Mips_GOT_OFST;
664 break;
665 case MipsMCExpr::MEK_GPREL:
666 FixupKind = Mips::fixup_Mips_GPREL16;
667 break;
668 case MipsMCExpr::MEK_LO:
669 // Check for %lo(%neg(%gp_rel(X)))
670 if (MipsExpr->isGpOff())
671 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_LO
672 : Mips::fixup_Mips_GPOFF_LO;
673 else
674 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
675 : Mips::fixup_Mips_LO16;
676 break;
677 case MipsMCExpr::MEK_HIGHEST:
678 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHEST
679 : Mips::fixup_Mips_HIGHEST;
680 break;
681 case MipsMCExpr::MEK_HIGHER:
682 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HIGHER
683 : Mips::fixup_Mips_HIGHER;
684 break;
685 case MipsMCExpr::MEK_HI:
686 // Check for %hi(%neg(%gp_rel(X)))
687 if (MipsExpr->isGpOff())
688 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GPOFF_HI
689 : Mips::fixup_Mips_GPOFF_HI;
690 else
691 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
692 : Mips::fixup_Mips_HI16;
693 break;
694 case MipsMCExpr::MEK_PCREL_HI16:
695 FixupKind = Mips::fixup_MIPS_PCHI16;
696 break;
697 case MipsMCExpr::MEK_PCREL_LO16:
698 FixupKind = Mips::fixup_MIPS_PCLO16;
699 break;
700 case MipsMCExpr::MEK_TLSGD:
701 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD
702 : Mips::fixup_Mips_TLSGD;
703 break;
704 case MipsMCExpr::MEK_TLSLDM:
705 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM
706 : Mips::fixup_Mips_TLSLDM;
707 break;
708 case MipsMCExpr::MEK_TPREL_HI:
709 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
710 : Mips::fixup_Mips_TPREL_HI;
711 break;
712 case MipsMCExpr::MEK_TPREL_LO:
713 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
714 : Mips::fixup_Mips_TPREL_LO;
715 break;
716 case MipsMCExpr::MEK_NEG:
717 FixupKind =
718 isMicroMips(STI) ? Mips::fixup_MICROMIPS_SUB : Mips::fixup_Mips_SUB;
719 break;
721 Fixups.push_back(MCFixup::create(0, MipsExpr, MCFixupKind(FixupKind)));
722 return 0;
725 if (Kind == MCExpr::SymbolRef) {
726 Mips::Fixups FixupKind = Mips::Fixups(0);
728 switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
729 default: llvm_unreachable("Unknown fixup kind!");
730 break;
731 case MCSymbolRefExpr::VK_None:
732 FixupKind = Mips::fixup_Mips_32; // FIXME: This is ok for O32/N32 but not N64.
733 break;
734 } // switch
736 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
737 return 0;
739 return 0;
742 /// getMachineOpValue - Return binary encoding of operand. If the machine
743 /// operand requires relocation, record the relocation and return zero.
744 unsigned MipsMCCodeEmitter::
745 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
746 SmallVectorImpl<MCFixup> &Fixups,
747 const MCSubtargetInfo &STI) const {
748 if (MO.isReg()) {
749 unsigned Reg = MO.getReg();
750 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
751 return RegNo;
752 } else if (MO.isImm()) {
753 return static_cast<unsigned>(MO.getImm());
754 } else if (MO.isFPImm()) {
755 return static_cast<unsigned>(APFloat(MO.getFPImm())
756 .bitcastToAPInt().getHiBits(32).getLimitedValue());
758 // MO must be an Expr.
759 assert(MO.isExpr());
760 return getExprOpValue(MO.getExpr(),Fixups, STI);
763 /// Return binary encoding of memory related operand.
764 /// If the offset operand requires relocation, record the relocation.
765 template <unsigned ShiftAmount>
766 unsigned MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
767 SmallVectorImpl<MCFixup> &Fixups,
768 const MCSubtargetInfo &STI) const {
769 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
770 assert(MI.getOperand(OpNo).isReg());
771 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
772 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
774 // Apply the scale factor if there is one.
775 OffBits >>= ShiftAmount;
777 return (OffBits & 0xFFFF) | RegBits;
780 unsigned MipsMCCodeEmitter::
781 getMemEncodingMMImm4(const MCInst &MI, unsigned OpNo,
782 SmallVectorImpl<MCFixup> &Fixups,
783 const MCSubtargetInfo &STI) const {
784 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
785 assert(MI.getOperand(OpNo).isReg());
786 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
787 Fixups, STI) << 4;
788 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
789 Fixups, STI);
791 return (OffBits & 0xF) | RegBits;
794 unsigned MipsMCCodeEmitter::
795 getMemEncodingMMImm4Lsl1(const MCInst &MI, unsigned OpNo,
796 SmallVectorImpl<MCFixup> &Fixups,
797 const MCSubtargetInfo &STI) const {
798 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
799 assert(MI.getOperand(OpNo).isReg());
800 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
801 Fixups, STI) << 4;
802 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
803 Fixups, STI) >> 1;
805 return (OffBits & 0xF) | RegBits;
808 unsigned MipsMCCodeEmitter::
809 getMemEncodingMMImm4Lsl2(const MCInst &MI, unsigned OpNo,
810 SmallVectorImpl<MCFixup> &Fixups,
811 const MCSubtargetInfo &STI) const {
812 // Base register is encoded in bits 6-4, offset is encoded in bits 3-0.
813 assert(MI.getOperand(OpNo).isReg());
814 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),
815 Fixups, STI) << 4;
816 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
817 Fixups, STI) >> 2;
819 return (OffBits & 0xF) | RegBits;
822 unsigned MipsMCCodeEmitter::
823 getMemEncodingMMSPImm5Lsl2(const MCInst &MI, unsigned OpNo,
824 SmallVectorImpl<MCFixup> &Fixups,
825 const MCSubtargetInfo &STI) const {
826 // Register is encoded in bits 9-5, offset is encoded in bits 4-0.
827 assert(MI.getOperand(OpNo).isReg() &&
828 (MI.getOperand(OpNo).getReg() == Mips::SP ||
829 MI.getOperand(OpNo).getReg() == Mips::SP_64) &&
830 "Unexpected base register!");
831 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
832 Fixups, STI) >> 2;
834 return OffBits & 0x1F;
837 unsigned MipsMCCodeEmitter::
838 getMemEncodingMMGPImm7Lsl2(const MCInst &MI, unsigned OpNo,
839 SmallVectorImpl<MCFixup> &Fixups,
840 const MCSubtargetInfo &STI) const {
841 // Register is encoded in bits 9-7, offset is encoded in bits 6-0.
842 assert(MI.getOperand(OpNo).isReg() &&
843 MI.getOperand(OpNo).getReg() == Mips::GP &&
844 "Unexpected base register!");
846 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1),
847 Fixups, STI) >> 2;
849 return OffBits & 0x7F;
852 unsigned MipsMCCodeEmitter::
853 getMemEncodingMMImm9(const MCInst &MI, unsigned OpNo,
854 SmallVectorImpl<MCFixup> &Fixups,
855 const MCSubtargetInfo &STI) const {
856 // Base register is encoded in bits 20-16, offset is encoded in bits 8-0.
857 assert(MI.getOperand(OpNo).isReg());
858 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
859 STI) << 16;
860 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo + 1), Fixups, STI);
862 return (OffBits & 0x1FF) | RegBits;
865 unsigned MipsMCCodeEmitter::
866 getMemEncodingMMImm11(const MCInst &MI, unsigned OpNo,
867 SmallVectorImpl<MCFixup> &Fixups,
868 const MCSubtargetInfo &STI) const {
869 // Base register is encoded in bits 20-16, offset is encoded in bits 10-0.
870 assert(MI.getOperand(OpNo).isReg());
871 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
872 STI) << 16;
873 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
875 return (OffBits & 0x07FF) | RegBits;
878 unsigned MipsMCCodeEmitter::
879 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
880 SmallVectorImpl<MCFixup> &Fixups,
881 const MCSubtargetInfo &STI) const {
882 // opNum can be invalid if instruction had reglist as operand.
883 // MemOperand is always last operand of instruction (base + offset).
884 switch (MI.getOpcode()) {
885 default:
886 break;
887 case Mips::SWM32_MM:
888 case Mips::LWM32_MM:
889 OpNo = MI.getNumOperands() - 2;
890 break;
893 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
894 assert(MI.getOperand(OpNo).isReg());
895 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
896 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
898 return (OffBits & 0x0FFF) | RegBits;
901 unsigned MipsMCCodeEmitter::
902 getMemEncodingMMImm16(const MCInst &MI, unsigned OpNo,
903 SmallVectorImpl<MCFixup> &Fixups,
904 const MCSubtargetInfo &STI) const {
905 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
906 assert(MI.getOperand(OpNo).isReg());
907 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups,
908 STI) << 16;
909 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
911 return (OffBits & 0xFFFF) | RegBits;
914 unsigned MipsMCCodeEmitter::
915 getMemEncodingMMImm4sp(const MCInst &MI, unsigned OpNo,
916 SmallVectorImpl<MCFixup> &Fixups,
917 const MCSubtargetInfo &STI) const {
918 // opNum can be invalid if instruction had reglist as operand
919 // MemOperand is always last operand of instruction (base + offset)
920 switch (MI.getOpcode()) {
921 default:
922 break;
923 case Mips::SWM16_MM:
924 case Mips::SWM16_MMR6:
925 case Mips::LWM16_MM:
926 case Mips::LWM16_MMR6:
927 OpNo = MI.getNumOperands() - 2;
928 break;
931 // Offset is encoded in bits 4-0.
932 assert(MI.getOperand(OpNo).isReg());
933 // Base register is always SP - thus it is not encoded.
934 assert(MI.getOperand(OpNo+1).isImm());
935 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
937 return ((OffBits >> 2) & 0x0F);
940 // FIXME: should be called getMSBEncoding
942 unsigned
943 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
944 SmallVectorImpl<MCFixup> &Fixups,
945 const MCSubtargetInfo &STI) const {
946 assert(MI.getOperand(OpNo-1).isImm());
947 assert(MI.getOperand(OpNo).isImm());
948 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI);
949 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
951 return Position + Size - 1;
954 template <unsigned Bits, int Offset>
955 unsigned
956 MipsMCCodeEmitter::getUImmWithOffsetEncoding(const MCInst &MI, unsigned OpNo,
957 SmallVectorImpl<MCFixup> &Fixups,
958 const MCSubtargetInfo &STI) const {
959 assert(MI.getOperand(OpNo).isImm());
960 unsigned Value = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
961 Value -= Offset;
962 return Value;
965 unsigned
966 MipsMCCodeEmitter::getSimm19Lsl2Encoding(const MCInst &MI, unsigned OpNo,
967 SmallVectorImpl<MCFixup> &Fixups,
968 const MCSubtargetInfo &STI) const {
969 const MCOperand &MO = MI.getOperand(OpNo);
970 if (MO.isImm()) {
971 // The immediate is encoded as 'immediate << 2'.
972 unsigned Res = getMachineOpValue(MI, MO, Fixups, STI);
973 assert((Res & 3) == 0);
974 return Res >> 2;
977 assert(MO.isExpr() &&
978 "getSimm19Lsl2Encoding expects only expressions or an immediate");
980 const MCExpr *Expr = MO.getExpr();
981 Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC19_S2
982 : Mips::fixup_MIPS_PC19_S2;
983 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
984 return 0;
987 unsigned
988 MipsMCCodeEmitter::getSimm18Lsl3Encoding(const MCInst &MI, unsigned OpNo,
989 SmallVectorImpl<MCFixup> &Fixups,
990 const MCSubtargetInfo &STI) const {
991 const MCOperand &MO = MI.getOperand(OpNo);
992 if (MO.isImm()) {
993 // The immediate is encoded as 'immediate << 3'.
994 unsigned Res = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
995 assert((Res & 7) == 0);
996 return Res >> 3;
999 assert(MO.isExpr() &&
1000 "getSimm18Lsl2Encoding expects only expressions or an immediate");
1002 const MCExpr *Expr = MO.getExpr();
1003 Mips::Fixups FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_PC18_S3
1004 : Mips::fixup_MIPS_PC18_S3;
1005 Fixups.push_back(MCFixup::create(0, Expr, MCFixupKind(FixupKind)));
1006 return 0;
1009 unsigned
1010 MipsMCCodeEmitter::getUImm3Mod8Encoding(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 return MO.getImm() % 8;
1018 unsigned
1019 MipsMCCodeEmitter::getUImm4AndValue(const MCInst &MI, unsigned OpNo,
1020 SmallVectorImpl<MCFixup> &Fixups,
1021 const MCSubtargetInfo &STI) const {
1022 assert(MI.getOperand(OpNo).isImm());
1023 const MCOperand &MO = MI.getOperand(OpNo);
1024 unsigned Value = MO.getImm();
1025 switch (Value) {
1026 case 128: return 0x0;
1027 case 1: return 0x1;
1028 case 2: return 0x2;
1029 case 3: return 0x3;
1030 case 4: return 0x4;
1031 case 7: return 0x5;
1032 case 8: return 0x6;
1033 case 15: return 0x7;
1034 case 16: return 0x8;
1035 case 31: return 0x9;
1036 case 32: return 0xa;
1037 case 63: return 0xb;
1038 case 64: return 0xc;
1039 case 255: return 0xd;
1040 case 32768: return 0xe;
1041 case 65535: return 0xf;
1043 llvm_unreachable("Unexpected value");
1046 unsigned
1047 MipsMCCodeEmitter::getRegisterListOpValue(const MCInst &MI, unsigned OpNo,
1048 SmallVectorImpl<MCFixup> &Fixups,
1049 const MCSubtargetInfo &STI) const {
1050 unsigned res = 0;
1052 // Register list operand is always first operand of instruction and it is
1053 // placed before memory operand (register + imm).
1055 for (unsigned I = OpNo, E = MI.getNumOperands() - 2; I < E; ++I) {
1056 unsigned Reg = MI.getOperand(I).getReg();
1057 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
1058 if (RegNo != 31)
1059 res++;
1060 else
1061 res |= 0x10;
1063 return res;
1066 unsigned
1067 MipsMCCodeEmitter::getRegisterListOpValue16(const MCInst &MI, unsigned OpNo,
1068 SmallVectorImpl<MCFixup> &Fixups,
1069 const MCSubtargetInfo &STI) const {
1070 return (MI.getNumOperands() - 4);
1073 unsigned
1074 MipsMCCodeEmitter::getMovePRegPairOpValue(const MCInst &MI, unsigned OpNo,
1075 SmallVectorImpl<MCFixup> &Fixups,
1076 const MCSubtargetInfo &STI) const {
1077 unsigned res = 0;
1079 if (MI.getOperand(0).getReg() == Mips::A1 &&
1080 MI.getOperand(1).getReg() == Mips::A2)
1081 res = 0;
1082 else if (MI.getOperand(0).getReg() == Mips::A1 &&
1083 MI.getOperand(1).getReg() == Mips::A3)
1084 res = 1;
1085 else if (MI.getOperand(0).getReg() == Mips::A2 &&
1086 MI.getOperand(1).getReg() == Mips::A3)
1087 res = 2;
1088 else if (MI.getOperand(0).getReg() == Mips::A0 &&
1089 MI.getOperand(1).getReg() == Mips::S5)
1090 res = 3;
1091 else if (MI.getOperand(0).getReg() == Mips::A0 &&
1092 MI.getOperand(1).getReg() == Mips::S6)
1093 res = 4;
1094 else if (MI.getOperand(0).getReg() == Mips::A0 &&
1095 MI.getOperand(1).getReg() == Mips::A1)
1096 res = 5;
1097 else if (MI.getOperand(0).getReg() == Mips::A0 &&
1098 MI.getOperand(1).getReg() == Mips::A2)
1099 res = 6;
1100 else if (MI.getOperand(0).getReg() == Mips::A0 &&
1101 MI.getOperand(1).getReg() == Mips::A3)
1102 res = 7;
1104 return res;
1107 unsigned
1108 MipsMCCodeEmitter::getMovePRegSingleOpValue(const MCInst &MI, unsigned OpNo,
1109 SmallVectorImpl<MCFixup> &Fixups,
1110 const MCSubtargetInfo &STI) const {
1111 assert(((OpNo == 2) || (OpNo == 3)) &&
1112 "Unexpected OpNo for movep operand encoding!");
1114 MCOperand Op = MI.getOperand(OpNo);
1115 assert(Op.isReg() && "Operand of movep is not a register!");
1116 switch (Op.getReg()) {
1117 default:
1118 llvm_unreachable("Unknown register for movep!");
1119 case Mips::ZERO: return 0;
1120 case Mips::S1: return 1;
1121 case Mips::V0: return 2;
1122 case Mips::V1: return 3;
1123 case Mips::S0: return 4;
1124 case Mips::S2: return 5;
1125 case Mips::S3: return 6;
1126 case Mips::S4: return 7;
1130 unsigned
1131 MipsMCCodeEmitter::getSimm23Lsl2Encoding(const MCInst &MI, unsigned OpNo,
1132 SmallVectorImpl<MCFixup> &Fixups,
1133 const MCSubtargetInfo &STI) const {
1134 const MCOperand &MO = MI.getOperand(OpNo);
1135 assert(MO.isImm() && "getSimm23Lsl2Encoding expects only an immediate");
1136 // The immediate is encoded as 'immediate >> 2'.
1137 unsigned Res = static_cast<unsigned>(MO.getImm());
1138 assert((Res & 3) == 0);
1139 return Res >> 2;
1142 #include "MipsGenMCCodeEmitter.inc"