1 //===-- MipsMCCodeEmitter.cpp - Convert Mips Code to Machine Code ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the MipsMCCodeEmitter class.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "mccodeemitter"
15 #include "MCTargetDesc/MipsBaseInfo.h"
16 #include "MCTargetDesc/MipsFixupKinds.h"
17 #include "MCTargetDesc/MipsMCExpr.h"
18 #include "MCTargetDesc/MipsMCTargetDesc.h"
19 #include "llvm/ADT/APFloat.h"
20 #include "llvm/ADT/Statistic.h"
21 #include "llvm/MC/MCCodeEmitter.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCExpr.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCInstrInfo.h"
26 #include "llvm/MC/MCRegisterInfo.h"
27 #include "llvm/MC/MCSubtargetInfo.h"
28 #include "llvm/Support/raw_ostream.h"
30 #define GET_INSTRMAP_INFO
31 #include "MipsGenInstrInfo.inc"
36 class MipsMCCodeEmitter : public MCCodeEmitter {
37 MipsMCCodeEmitter(const MipsMCCodeEmitter &) LLVM_DELETED_FUNCTION;
38 void operator=(const MipsMCCodeEmitter &) LLVM_DELETED_FUNCTION;
39 const MCInstrInfo &MCII;
43 bool isMicroMips(const MCSubtargetInfo &STI) const {
44 return STI.getFeatureBits() & Mips::FeatureMicroMips;
48 MipsMCCodeEmitter(const MCInstrInfo &mcii, MCContext &Ctx_, bool IsLittle) :
49 MCII(mcii), Ctx(Ctx_), IsLittleEndian(IsLittle) { }
51 ~MipsMCCodeEmitter() {}
53 void EmitByte(unsigned char C, raw_ostream &OS) const {
57 void EmitInstruction(uint64_t Val, unsigned Size, const MCSubtargetInfo &STI,
58 raw_ostream &OS) const {
59 // Output the instruction encoding in little endian byte order.
60 // Little-endian byte ordering:
61 // mips32r2: 4 | 3 | 2 | 1
62 // microMIPS: 2 | 1 | 4 | 3
63 if (IsLittleEndian && Size == 4 && isMicroMips(STI)) {
64 EmitInstruction(Val>>16, 2, STI, OS);
65 EmitInstruction(Val, 2, STI, OS);
67 for (unsigned i = 0; i < Size; ++i) {
68 unsigned Shift = IsLittleEndian ? i * 8 : (Size - 1 - i) * 8;
69 EmitByte((Val >> Shift) & 0xff, OS);
74 void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
75 SmallVectorImpl<MCFixup> &Fixups,
76 const MCSubtargetInfo &STI) const;
78 // getBinaryCodeForInstr - TableGen'erated function for getting the
79 // binary encoding for an instruction.
80 uint64_t getBinaryCodeForInstr(const MCInst &MI,
81 SmallVectorImpl<MCFixup> &Fixups,
82 const MCSubtargetInfo &STI) const;
84 // getBranchJumpOpValue - Return binary encoding of the jump
85 // target operand. If the machine operand requires relocation,
86 // record the relocation and return zero.
87 unsigned getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
88 SmallVectorImpl<MCFixup> &Fixups,
89 const MCSubtargetInfo &STI) const;
91 // getBranchJumpOpValueMM - Return binary encoding of the microMIPS jump
92 // target operand. If the machine operand requires relocation,
93 // record the relocation and return zero.
94 unsigned getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
95 SmallVectorImpl<MCFixup> &Fixups,
96 const MCSubtargetInfo &STI) const;
98 // getBranchTargetOpValue - Return binary encoding of the branch
99 // target operand. If the machine operand requires relocation,
100 // record the relocation and return zero.
101 unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
102 SmallVectorImpl<MCFixup> &Fixups,
103 const MCSubtargetInfo &STI) const;
105 // getBranchTargetOpValue - Return binary encoding of the microMIPS branch
106 // target operand. If the machine operand requires relocation,
107 // record the relocation and return zero.
108 unsigned getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
109 SmallVectorImpl<MCFixup> &Fixups,
110 const MCSubtargetInfo &STI) const;
112 // getMachineOpValue - Return binary encoding of operand. If the machin
113 // operand requires relocation, record the relocation and return zero.
114 unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
115 SmallVectorImpl<MCFixup> &Fixups,
116 const MCSubtargetInfo &STI) const;
118 unsigned getMSAMemEncoding(const MCInst &MI, unsigned OpNo,
119 SmallVectorImpl<MCFixup> &Fixups,
120 const MCSubtargetInfo &STI) const;
122 unsigned getMemEncoding(const MCInst &MI, unsigned OpNo,
123 SmallVectorImpl<MCFixup> &Fixups,
124 const MCSubtargetInfo &STI) const;
125 unsigned getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
126 SmallVectorImpl<MCFixup> &Fixups,
127 const MCSubtargetInfo &STI) const;
128 unsigned getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
129 SmallVectorImpl<MCFixup> &Fixups,
130 const MCSubtargetInfo &STI) const;
131 unsigned getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
132 SmallVectorImpl<MCFixup> &Fixups,
133 const MCSubtargetInfo &STI) const;
135 // getLSAImmEncoding - Return binary encoding of LSA immediate.
136 unsigned getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
137 SmallVectorImpl<MCFixup> &Fixups,
138 const MCSubtargetInfo &STI) const;
141 getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups,
142 const MCSubtargetInfo &STI) const;
144 }; // class MipsMCCodeEmitter
147 MCCodeEmitter *llvm::createMipsMCCodeEmitterEB(const MCInstrInfo &MCII,
148 const MCRegisterInfo &MRI,
149 const MCSubtargetInfo &STI,
152 return new MipsMCCodeEmitter(MCII, Ctx, false);
155 MCCodeEmitter *llvm::createMipsMCCodeEmitterEL(const MCInstrInfo &MCII,
156 const MCRegisterInfo &MRI,
157 const MCSubtargetInfo &STI,
160 return new MipsMCCodeEmitter(MCII, Ctx, true);
164 // If the D<shift> instruction has a shift amount that is greater
165 // than 31 (checked in calling routine), lower it to a D<shift>32 instruction
166 static void LowerLargeShift(MCInst& Inst) {
168 assert(Inst.getNumOperands() == 3 && "Invalid no. of operands for shift!");
169 assert(Inst.getOperand(2).isImm());
171 int64_t Shift = Inst.getOperand(2).getImm();
173 return; // Do nothing
177 Inst.getOperand(2).setImm(Shift);
179 switch (Inst.getOpcode()) {
181 // Calling function is not synchronized
182 llvm_unreachable("Unexpected shift instruction");
184 Inst.setOpcode(Mips::DSLL32);
187 Inst.setOpcode(Mips::DSRL32);
190 Inst.setOpcode(Mips::DSRA32);
193 Inst.setOpcode(Mips::DROTR32);
198 // Pick a DEXT or DINS instruction variant based on the pos and size operands
199 static void LowerDextDins(MCInst& InstIn) {
200 int Opcode = InstIn.getOpcode();
202 if (Opcode == Mips::DEXT)
203 assert(InstIn.getNumOperands() == 4 &&
204 "Invalid no. of machine operands for DEXT!");
205 else // Only DEXT and DINS are possible
206 assert(InstIn.getNumOperands() == 5 &&
207 "Invalid no. of machine operands for DINS!");
209 assert(InstIn.getOperand(2).isImm());
210 int64_t pos = InstIn.getOperand(2).getImm();
211 assert(InstIn.getOperand(3).isImm());
212 int64_t size = InstIn.getOperand(3).getImm();
215 if (pos < 32) // DEXT/DINS, do nothing
218 InstIn.getOperand(2).setImm(pos - 32);
219 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTU : Mips::DINSU);
223 assert(pos < 32 && "DEXT/DINS cannot have both size and pos > 32");
224 InstIn.getOperand(3).setImm(size - 32);
225 InstIn.setOpcode((Opcode == Mips::DEXT) ? Mips::DEXTM : Mips::DINSM);
229 /// EncodeInstruction - Emit the instruction.
230 /// Size the instruction with Desc.getSize().
231 void MipsMCCodeEmitter::
232 EncodeInstruction(const MCInst &MI, raw_ostream &OS,
233 SmallVectorImpl<MCFixup> &Fixups,
234 const MCSubtargetInfo &STI) const
237 // Non-pseudo instructions that get changed for direct object
238 // only based on operand values.
239 // If this list of instructions get much longer we will move
240 // the check to a function call. Until then, this is more efficient.
242 switch (MI.getOpcode()) {
243 // If shift amount is >= 32 it the inst needs to be lowered further
248 LowerLargeShift(TmpInst);
250 // Double extract instruction is chosen by pos and size operands
253 LowerDextDins(TmpInst);
256 unsigned long N = Fixups.size();
257 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
259 // Check for unimplemented opcodes.
260 // Unfortunately in MIPS both NOP and SLL will come in with Binary == 0
261 // so we have to special check for them.
262 unsigned Opcode = TmpInst.getOpcode();
263 if ((Opcode != Mips::NOP) && (Opcode != Mips::SLL) && !Binary)
264 llvm_unreachable("unimplemented opcode in EncodeInstruction()");
266 if (STI.getFeatureBits() & Mips::FeatureMicroMips) {
267 int NewOpcode = Mips::Std2MicroMips (Opcode, Mips::Arch_micromips);
268 if (NewOpcode != -1) {
269 if (Fixups.size() > N)
272 TmpInst.setOpcode (NewOpcode);
273 Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
277 const MCInstrDesc &Desc = MCII.get(TmpInst.getOpcode());
279 // Get byte count of instruction
280 unsigned Size = Desc.getSize();
282 llvm_unreachable("Desc.getSize() returns 0");
284 EmitInstruction(Binary, Size, STI, OS);
287 /// getBranchTargetOpValue - Return binary encoding of the branch
288 /// target operand. If the machine operand requires relocation,
289 /// record the relocation and return zero.
290 unsigned MipsMCCodeEmitter::
291 getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
292 SmallVectorImpl<MCFixup> &Fixups,
293 const MCSubtargetInfo &STI) const {
295 const MCOperand &MO = MI.getOperand(OpNo);
297 // If the destination is an immediate, divide by 4.
298 if (MO.isImm()) return MO.getImm() >> 2;
300 assert(MO.isExpr() &&
301 "getBranchTargetOpValue expects only expressions or immediates");
303 const MCExpr *Expr = MO.getExpr();
304 Fixups.push_back(MCFixup::Create(0, Expr,
305 MCFixupKind(Mips::fixup_Mips_PC16)));
309 /// getBranchTargetOpValue - Return binary encoding of the microMIPS branch
310 /// target operand. If the machine operand requires relocation,
311 /// record the relocation and return zero.
312 unsigned MipsMCCodeEmitter::
313 getBranchTargetOpValueMM(const MCInst &MI, unsigned OpNo,
314 SmallVectorImpl<MCFixup> &Fixups,
315 const MCSubtargetInfo &STI) const {
317 const MCOperand &MO = MI.getOperand(OpNo);
319 // If the destination is an immediate, divide by 2.
320 if (MO.isImm()) return MO.getImm() >> 1;
322 assert(MO.isExpr() &&
323 "getBranchTargetOpValueMM expects only expressions or immediates");
325 const MCExpr *Expr = MO.getExpr();
326 Fixups.push_back(MCFixup::Create(0, Expr,
328 fixup_MICROMIPS_PC16_S1)));
332 /// getJumpTargetOpValue - Return binary encoding of the jump
333 /// target operand. If the machine operand requires relocation,
334 /// record the relocation and return zero.
335 unsigned MipsMCCodeEmitter::
336 getJumpTargetOpValue(const MCInst &MI, unsigned OpNo,
337 SmallVectorImpl<MCFixup> &Fixups,
338 const MCSubtargetInfo &STI) const {
340 const MCOperand &MO = MI.getOperand(OpNo);
341 // If the destination is an immediate, divide by 4.
342 if (MO.isImm()) return MO.getImm()>>2;
344 assert(MO.isExpr() &&
345 "getJumpTargetOpValue expects only expressions or an immediate");
347 const MCExpr *Expr = MO.getExpr();
348 Fixups.push_back(MCFixup::Create(0, Expr,
349 MCFixupKind(Mips::fixup_Mips_26)));
353 unsigned MipsMCCodeEmitter::
354 getJumpTargetOpValueMM(const MCInst &MI, unsigned OpNo,
355 SmallVectorImpl<MCFixup> &Fixups,
356 const MCSubtargetInfo &STI) const {
358 const MCOperand &MO = MI.getOperand(OpNo);
359 // If the destination is an immediate, divide by 2.
360 if (MO.isImm()) return MO.getImm() >> 1;
362 assert(MO.isExpr() &&
363 "getJumpTargetOpValueMM expects only expressions or an immediate");
365 const MCExpr *Expr = MO.getExpr();
366 Fixups.push_back(MCFixup::Create(0, Expr,
367 MCFixupKind(Mips::fixup_MICROMIPS_26_S1)));
371 unsigned MipsMCCodeEmitter::
372 getExprOpValue(const MCExpr *Expr,SmallVectorImpl<MCFixup> &Fixups,
373 const MCSubtargetInfo &STI) const {
376 if (Expr->EvaluateAsAbsolute(Res))
379 MCExpr::ExprKind Kind = Expr->getKind();
380 if (Kind == MCExpr::Constant) {
381 return cast<MCConstantExpr>(Expr)->getValue();
384 if (Kind == MCExpr::Binary) {
385 unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(), Fixups, STI);
386 Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups, STI);
390 if (Kind == MCExpr::Target) {
391 const MipsMCExpr *MipsExpr = cast<MipsMCExpr>(Expr);
393 Mips::Fixups FixupKind = Mips::Fixups(0);
394 switch (MipsExpr->getKind()) {
395 default: llvm_unreachable("Unsupported fixup kind for target expression!");
396 case MipsMCExpr::VK_Mips_ABS_HI:
397 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
398 : Mips::fixup_Mips_HI16;
400 case MipsMCExpr::VK_Mips_ABS_LO:
401 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
402 : Mips::fixup_Mips_LO16;
405 Fixups.push_back(MCFixup::Create(0, MipsExpr, MCFixupKind(FixupKind)));
409 if (Kind == MCExpr::SymbolRef) {
410 Mips::Fixups FixupKind = Mips::Fixups(0);
412 switch(cast<MCSymbolRefExpr>(Expr)->getKind()) {
413 default: llvm_unreachable("Unknown fixup kind!");
415 case MCSymbolRefExpr::VK_Mips_GPOFF_HI :
416 FixupKind = Mips::fixup_Mips_GPOFF_HI;
418 case MCSymbolRefExpr::VK_Mips_GPOFF_LO :
419 FixupKind = Mips::fixup_Mips_GPOFF_LO;
421 case MCSymbolRefExpr::VK_Mips_GOT_PAGE :
422 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_PAGE
423 : Mips::fixup_Mips_GOT_PAGE;
425 case MCSymbolRefExpr::VK_Mips_GOT_OFST :
426 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_OFST
427 : Mips::fixup_Mips_GOT_OFST;
429 case MCSymbolRefExpr::VK_Mips_GOT_DISP :
430 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT_DISP
431 : Mips::fixup_Mips_GOT_DISP;
433 case MCSymbolRefExpr::VK_Mips_GPREL:
434 FixupKind = Mips::fixup_Mips_GPREL16;
436 case MCSymbolRefExpr::VK_Mips_GOT_CALL:
437 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_CALL16
438 : Mips::fixup_Mips_CALL16;
440 case MCSymbolRefExpr::VK_Mips_GOT16:
441 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
442 : Mips::fixup_Mips_GOT_Global;
444 case MCSymbolRefExpr::VK_Mips_GOT:
445 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_GOT16
446 : Mips::fixup_Mips_GOT_Local;
448 case MCSymbolRefExpr::VK_Mips_ABS_HI:
449 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_HI16
450 : Mips::fixup_Mips_HI16;
452 case MCSymbolRefExpr::VK_Mips_ABS_LO:
453 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_LO16
454 : Mips::fixup_Mips_LO16;
456 case MCSymbolRefExpr::VK_Mips_TLSGD:
457 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_GD
458 : Mips::fixup_Mips_TLSGD;
460 case MCSymbolRefExpr::VK_Mips_TLSLDM:
461 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_LDM
462 : Mips::fixup_Mips_TLSLDM;
464 case MCSymbolRefExpr::VK_Mips_DTPREL_HI:
465 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_HI16
466 : Mips::fixup_Mips_DTPREL_HI;
468 case MCSymbolRefExpr::VK_Mips_DTPREL_LO:
469 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_DTPREL_LO16
470 : Mips::fixup_Mips_DTPREL_LO;
472 case MCSymbolRefExpr::VK_Mips_GOTTPREL:
473 FixupKind = Mips::fixup_Mips_GOTTPREL;
475 case MCSymbolRefExpr::VK_Mips_TPREL_HI:
476 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_HI16
477 : Mips::fixup_Mips_TPREL_HI;
479 case MCSymbolRefExpr::VK_Mips_TPREL_LO:
480 FixupKind = isMicroMips(STI) ? Mips::fixup_MICROMIPS_TLS_TPREL_LO16
481 : Mips::fixup_Mips_TPREL_LO;
483 case MCSymbolRefExpr::VK_Mips_HIGHER:
484 FixupKind = Mips::fixup_Mips_HIGHER;
486 case MCSymbolRefExpr::VK_Mips_HIGHEST:
487 FixupKind = Mips::fixup_Mips_HIGHEST;
489 case MCSymbolRefExpr::VK_Mips_GOT_HI16:
490 FixupKind = Mips::fixup_Mips_GOT_HI16;
492 case MCSymbolRefExpr::VK_Mips_GOT_LO16:
493 FixupKind = Mips::fixup_Mips_GOT_LO16;
495 case MCSymbolRefExpr::VK_Mips_CALL_HI16:
496 FixupKind = Mips::fixup_Mips_CALL_HI16;
498 case MCSymbolRefExpr::VK_Mips_CALL_LO16:
499 FixupKind = Mips::fixup_Mips_CALL_LO16;
503 Fixups.push_back(MCFixup::Create(0, Expr, MCFixupKind(FixupKind)));
509 /// getMachineOpValue - Return binary encoding of operand. If the machine
510 /// operand requires relocation, record the relocation and return zero.
511 unsigned MipsMCCodeEmitter::
512 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
513 SmallVectorImpl<MCFixup> &Fixups,
514 const MCSubtargetInfo &STI) const {
516 unsigned Reg = MO.getReg();
517 unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
519 } else if (MO.isImm()) {
520 return static_cast<unsigned>(MO.getImm());
521 } else if (MO.isFPImm()) {
522 return static_cast<unsigned>(APFloat(MO.getFPImm())
523 .bitcastToAPInt().getHiBits(32).getLimitedValue());
525 // MO must be an Expr.
527 return getExprOpValue(MO.getExpr(),Fixups, STI);
530 /// getMSAMemEncoding - Return binary encoding of memory operand for LD/ST
533 MipsMCCodeEmitter::getMSAMemEncoding(const MCInst &MI, unsigned OpNo,
534 SmallVectorImpl<MCFixup> &Fixups,
535 const MCSubtargetInfo &STI) const {
536 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
537 assert(MI.getOperand(OpNo).isReg());
538 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
539 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
541 // The immediate field of an LD/ST instruction is scaled which means it must
542 // be divided (when encoding) by the size (in bytes) of the instructions'
548 switch(MI.getOpcode())
551 assert (0 && "Unexpected instruction");
555 // We don't need to scale the offset in this case
571 return (OffBits & 0xFFFF) | RegBits;
574 /// getMemEncoding - Return binary encoding of memory related operand.
575 /// If the offset operand requires relocation, record the relocation.
577 MipsMCCodeEmitter::getMemEncoding(const MCInst &MI, unsigned OpNo,
578 SmallVectorImpl<MCFixup> &Fixups,
579 const MCSubtargetInfo &STI) const {
580 // Base register is encoded in bits 20-16, offset is encoded in bits 15-0.
581 assert(MI.getOperand(OpNo).isReg());
582 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo),Fixups, STI) << 16;
583 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
585 return (OffBits & 0xFFFF) | RegBits;
588 unsigned MipsMCCodeEmitter::
589 getMemEncodingMMImm12(const MCInst &MI, unsigned OpNo,
590 SmallVectorImpl<MCFixup> &Fixups,
591 const MCSubtargetInfo &STI) const {
592 // Base register is encoded in bits 20-16, offset is encoded in bits 11-0.
593 assert(MI.getOperand(OpNo).isReg());
594 unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) << 16;
595 unsigned OffBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI);
597 return (OffBits & 0x0FFF) | RegBits;
601 MipsMCCodeEmitter::getSizeExtEncoding(const MCInst &MI, unsigned OpNo,
602 SmallVectorImpl<MCFixup> &Fixups,
603 const MCSubtargetInfo &STI) const {
604 assert(MI.getOperand(OpNo).isImm());
605 unsigned SizeEncoding = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
606 return SizeEncoding - 1;
609 // FIXME: should be called getMSBEncoding
612 MipsMCCodeEmitter::getSizeInsEncoding(const MCInst &MI, unsigned OpNo,
613 SmallVectorImpl<MCFixup> &Fixups,
614 const MCSubtargetInfo &STI) const {
615 assert(MI.getOperand(OpNo-1).isImm());
616 assert(MI.getOperand(OpNo).isImm());
617 unsigned Position = getMachineOpValue(MI, MI.getOperand(OpNo-1), Fixups, STI);
618 unsigned Size = getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI);
620 return Position + Size - 1;
624 MipsMCCodeEmitter::getLSAImmEncoding(const MCInst &MI, unsigned OpNo,
625 SmallVectorImpl<MCFixup> &Fixups,
626 const MCSubtargetInfo &STI) const {
627 assert(MI.getOperand(OpNo).isImm());
628 // The immediate is encoded as 'immediate - 1'.
629 return getMachineOpValue(MI, MI.getOperand(OpNo), Fixups, STI) - 1;
632 #include "MipsGenMCCodeEmitter.inc"