1 //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
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 is part of the Mips Disassembler.
12 //===----------------------------------------------------------------------===//
15 #include "MipsRegisterInfo.h"
16 #include "MipsSubtarget.h"
17 #include "llvm/MC/MCDisassembler.h"
18 #include "llvm/MC/MCFixedLenDisassembler.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCSubtargetInfo.h"
21 #include "llvm/Support/MathExtras.h"
22 #include "llvm/Support/MemoryObject.h"
23 #include "llvm/Support/TargetRegistry.h"
27 typedef MCDisassembler::DecodeStatus DecodeStatus;
31 /// MipsDisassemblerBase - a disasembler class for Mips.
32 class MipsDisassemblerBase : public MCDisassembler {
34 /// Constructor - Initializes the disassembler.
36 MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
38 MCDisassembler(STI), RegInfo(Info),
39 IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {}
41 virtual ~MipsDisassemblerBase() {}
43 const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
45 bool isN64() const { return IsN64; }
48 OwningPtr<const MCRegisterInfo> RegInfo;
54 /// MipsDisassembler - a disasembler class for Mips32.
55 class MipsDisassembler : public MipsDisassemblerBase {
58 /// Constructor - Initializes the disassembler.
60 MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
62 MipsDisassemblerBase(STI, Info, bigEndian) {
63 IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
66 /// getInstruction - See MCDisassembler.
67 virtual DecodeStatus getInstruction(MCInst &instr,
69 const MemoryObject ®ion,
72 raw_ostream &cStream) const;
76 /// Mips64Disassembler - a disasembler class for Mips64.
77 class Mips64Disassembler : public MipsDisassemblerBase {
79 /// Constructor - Initializes the disassembler.
81 Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
83 MipsDisassemblerBase(STI, Info, bigEndian) {}
85 /// getInstruction - See MCDisassembler.
86 virtual DecodeStatus getInstruction(MCInst &instr,
88 const MemoryObject ®ion,
91 raw_ostream &cStream) const;
94 } // end anonymous namespace
96 // Forward declare these because the autogenerated code will reference them.
97 // Definitions are further down.
98 static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
101 const void *Decoder);
103 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
106 const void *Decoder);
108 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
111 const void *Decoder);
113 static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
116 const void *Decoder);
118 static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
121 const void *Decoder);
123 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
126 const void *Decoder);
128 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
131 const void *Decoder);
133 static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
136 const void *Decoder);
138 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
141 const void *Decoder);
143 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
146 const void *Decoder);
148 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
151 const void *Decoder);
153 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
156 const void *Decoder);
158 static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
161 const void *Decoder);
163 static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
166 const void *Decoder);
168 static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
171 const void *Decoder);
173 static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
176 const void *Decoder);
178 static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
181 const void *Decoder);
183 static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
186 const void *Decoder);
188 static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
191 const void *Decoder);
193 static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
196 const void *Decoder);
198 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
201 const void *Decoder);
203 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
206 const void *Decoder);
208 // DecodeBranchTargetMM - Decode microMIPS branch offset, which is
209 // shifted left by 1 bit.
210 static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
213 const void *Decoder);
215 // DecodeJumpTargetMM - Decode microMIPS jump target, which is
216 // shifted left by 1 bit.
217 static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
220 const void *Decoder);
222 static DecodeStatus DecodeMem(MCInst &Inst,
225 const void *Decoder);
227 static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
228 uint64_t Address, const void *Decoder);
230 static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
233 const void *Decoder);
235 static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
238 const void *Decoder);
240 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
242 const void *Decoder);
244 static DecodeStatus DecodeSimm16(MCInst &Inst,
247 const void *Decoder);
249 // Decode the immediate field of an LSA instruction which
251 static DecodeStatus DecodeLSAImm(MCInst &Inst,
254 const void *Decoder);
256 static DecodeStatus DecodeInsSize(MCInst &Inst,
259 const void *Decoder);
261 static DecodeStatus DecodeExtSize(MCInst &Inst,
264 const void *Decoder);
267 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
271 static MCDisassembler *createMipsDisassembler(
273 const MCSubtargetInfo &STI) {
274 return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
277 static MCDisassembler *createMipselDisassembler(
279 const MCSubtargetInfo &STI) {
280 return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
283 static MCDisassembler *createMips64Disassembler(
285 const MCSubtargetInfo &STI) {
286 return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
289 static MCDisassembler *createMips64elDisassembler(
291 const MCSubtargetInfo &STI) {
292 return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
295 extern "C" void LLVMInitializeMipsDisassembler() {
296 // Register the disassembler.
297 TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
298 createMipsDisassembler);
299 TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
300 createMipselDisassembler);
301 TargetRegistry::RegisterMCDisassembler(TheMips64Target,
302 createMips64Disassembler);
303 TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
304 createMips64elDisassembler);
308 #include "MipsGenDisassemblerTables.inc"
310 /// readInstruction - read four bytes from the MemoryObject
311 /// and return 32 bit word sorted according to the given endianess
312 static DecodeStatus readInstruction32(const MemoryObject ®ion,
320 // We want to read exactly 4 Bytes of data.
321 if (region.readBytes(address, 4, Bytes) == -1) {
323 return MCDisassembler::Fail;
327 // Encoded as a big-endian 32-bit word in the stream.
328 insn = (Bytes[3] << 0) |
334 // Encoded as a small-endian 32-bit word in the stream.
335 // Little-endian byte ordering:
336 // mips32r2: 4 | 3 | 2 | 1
337 // microMIPS: 2 | 1 | 4 | 3
339 insn = (Bytes[2] << 0) |
344 insn = (Bytes[0] << 0) |
351 return MCDisassembler::Success;
355 MipsDisassembler::getInstruction(MCInst &instr,
357 const MemoryObject &Region,
359 raw_ostream &vStream,
360 raw_ostream &cStream) const {
363 DecodeStatus Result = readInstruction32(Region, Address, Size,
364 Insn, isBigEndian, IsMicroMips);
365 if (Result == MCDisassembler::Fail)
366 return MCDisassembler::Fail;
369 // Calling the auto-generated decoder function.
370 Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address,
372 if (Result != MCDisassembler::Fail) {
376 return MCDisassembler::Fail;
379 // Calling the auto-generated decoder function.
380 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
382 if (Result != MCDisassembler::Fail) {
387 return MCDisassembler::Fail;
391 Mips64Disassembler::getInstruction(MCInst &instr,
393 const MemoryObject &Region,
395 raw_ostream &vStream,
396 raw_ostream &cStream) const {
399 DecodeStatus Result = readInstruction32(Region, Address, Size,
400 Insn, isBigEndian, false);
401 if (Result == MCDisassembler::Fail)
402 return MCDisassembler::Fail;
404 // Calling the auto-generated decoder function.
405 Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
407 if (Result != MCDisassembler::Fail) {
411 // If we fail to decode in Mips64 decoder space we can try in Mips32
412 Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
414 if (Result != MCDisassembler::Fail) {
419 return MCDisassembler::Fail;
422 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
423 const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
424 return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
427 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
430 const void *Decoder) {
432 return MCDisassembler::Fail;
436 static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
439 const void *Decoder) {
442 return MCDisassembler::Fail;
444 unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
445 Inst.addOperand(MCOperand::CreateReg(Reg));
446 return MCDisassembler::Success;
449 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
452 const void *Decoder) {
454 return MCDisassembler::Fail;
455 unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
456 Inst.addOperand(MCOperand::CreateReg(Reg));
457 return MCDisassembler::Success;
460 static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
463 const void *Decoder) {
464 if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
465 return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
467 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
470 static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
473 const void *Decoder) {
474 return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
477 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
480 const void *Decoder) {
482 return MCDisassembler::Fail;
484 unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
485 Inst.addOperand(MCOperand::CreateReg(Reg));
486 return MCDisassembler::Success;
489 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
492 const void *Decoder) {
494 return MCDisassembler::Fail;
496 unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
497 Inst.addOperand(MCOperand::CreateReg(Reg));
498 return MCDisassembler::Success;
501 static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
504 const void *Decoder) {
506 return MCDisassembler::Fail;
508 unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
509 Inst.addOperand(MCOperand::CreateReg(Reg));
510 return MCDisassembler::Success;
513 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
516 const void *Decoder) {
518 return MCDisassembler::Fail;
519 unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
520 Inst.addOperand(MCOperand::CreateReg(Reg));
521 return MCDisassembler::Success;
524 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
527 const void *Decoder) {
529 return MCDisassembler::Fail;
530 unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
531 Inst.addOperand(MCOperand::CreateReg(Reg));
532 return MCDisassembler::Success;
535 static DecodeStatus DecodeMem(MCInst &Inst,
538 const void *Decoder) {
539 int Offset = SignExtend32<16>(Insn & 0xffff);
540 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
541 unsigned Base = fieldFromInstruction(Insn, 21, 5);
543 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
544 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
546 if(Inst.getOpcode() == Mips::SC){
547 Inst.addOperand(MCOperand::CreateReg(Reg));
550 Inst.addOperand(MCOperand::CreateReg(Reg));
551 Inst.addOperand(MCOperand::CreateReg(Base));
552 Inst.addOperand(MCOperand::CreateImm(Offset));
554 return MCDisassembler::Success;
557 static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
558 uint64_t Address, const void *Decoder) {
559 int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
560 unsigned Reg = fieldFromInstruction(Insn, 6, 5);
561 unsigned Base = fieldFromInstruction(Insn, 11, 5);
563 Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
564 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
566 Inst.addOperand(MCOperand::CreateReg(Reg));
567 Inst.addOperand(MCOperand::CreateReg(Base));
569 // The immediate field of an LD/ST instruction is scaled which means it must
570 // be multiplied (when decoding) by the size (in bytes) of the instructions'
576 switch(Inst.getOpcode())
579 assert (0 && "Unexpected instruction");
580 return MCDisassembler::Fail;
584 Inst.addOperand(MCOperand::CreateImm(Offset));
588 Inst.addOperand(MCOperand::CreateImm(Offset << 1));
592 Inst.addOperand(MCOperand::CreateImm(Offset << 2));
596 Inst.addOperand(MCOperand::CreateImm(Offset << 3));
600 return MCDisassembler::Success;
603 static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
606 const void *Decoder) {
607 int Offset = SignExtend32<12>(Insn & 0x0fff);
608 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
609 unsigned Base = fieldFromInstruction(Insn, 16, 5);
611 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
612 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
614 if (Inst.getOpcode() == Mips::SC_MM)
615 Inst.addOperand(MCOperand::CreateReg(Reg));
617 Inst.addOperand(MCOperand::CreateReg(Reg));
618 Inst.addOperand(MCOperand::CreateReg(Base));
619 Inst.addOperand(MCOperand::CreateImm(Offset));
621 return MCDisassembler::Success;
624 static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
627 const void *Decoder) {
628 int Offset = SignExtend32<16>(Insn & 0xffff);
629 unsigned Reg = fieldFromInstruction(Insn, 21, 5);
630 unsigned Base = fieldFromInstruction(Insn, 16, 5);
632 Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
633 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
635 Inst.addOperand(MCOperand::CreateReg(Reg));
636 Inst.addOperand(MCOperand::CreateReg(Base));
637 Inst.addOperand(MCOperand::CreateImm(Offset));
639 return MCDisassembler::Success;
642 static DecodeStatus DecodeFMem(MCInst &Inst,
645 const void *Decoder) {
646 int Offset = SignExtend32<16>(Insn & 0xffff);
647 unsigned Reg = fieldFromInstruction(Insn, 16, 5);
648 unsigned Base = fieldFromInstruction(Insn, 21, 5);
650 Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
651 Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
653 Inst.addOperand(MCOperand::CreateReg(Reg));
654 Inst.addOperand(MCOperand::CreateReg(Base));
655 Inst.addOperand(MCOperand::CreateImm(Offset));
657 return MCDisassembler::Success;
661 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
664 const void *Decoder) {
665 // Currently only hardware register 29 is supported.
667 return MCDisassembler::Fail;
668 Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
669 return MCDisassembler::Success;
672 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
675 const void *Decoder) {
676 if (RegNo > 30 || RegNo %2)
677 return MCDisassembler::Fail;
680 unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
681 Inst.addOperand(MCOperand::CreateReg(Reg));
682 return MCDisassembler::Success;
685 static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
688 const void *Decoder) {
690 return MCDisassembler::Fail;
692 unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
693 Inst.addOperand(MCOperand::CreateReg(Reg));
694 return MCDisassembler::Success;
697 static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
700 const void *Decoder) {
702 return MCDisassembler::Fail;
704 unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
705 Inst.addOperand(MCOperand::CreateReg(Reg));
706 return MCDisassembler::Success;
709 static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
712 const void *Decoder) {
714 return MCDisassembler::Fail;
716 unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
717 Inst.addOperand(MCOperand::CreateReg(Reg));
718 return MCDisassembler::Success;
721 static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
724 const void *Decoder) {
726 return MCDisassembler::Fail;
728 unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
729 Inst.addOperand(MCOperand::CreateReg(Reg));
730 return MCDisassembler::Success;
733 static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
736 const void *Decoder) {
738 return MCDisassembler::Fail;
740 unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
741 Inst.addOperand(MCOperand::CreateReg(Reg));
742 return MCDisassembler::Success;
745 static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
748 const void *Decoder) {
750 return MCDisassembler::Fail;
752 unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
753 Inst.addOperand(MCOperand::CreateReg(Reg));
754 return MCDisassembler::Success;
757 static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
760 const void *Decoder) {
762 return MCDisassembler::Fail;
764 unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
765 Inst.addOperand(MCOperand::CreateReg(Reg));
766 return MCDisassembler::Success;
769 static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
772 const void *Decoder) {
774 return MCDisassembler::Fail;
776 unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
777 Inst.addOperand(MCOperand::CreateReg(Reg));
778 return MCDisassembler::Success;
781 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
784 const void *Decoder) {
785 unsigned BranchOffset = Offset & 0xffff;
786 BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
787 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
788 return MCDisassembler::Success;
791 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
794 const void *Decoder) {
796 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
797 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
798 return MCDisassembler::Success;
801 static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
804 const void *Decoder) {
805 unsigned BranchOffset = Offset & 0xffff;
806 BranchOffset = SignExtend32<18>(BranchOffset << 1);
807 Inst.addOperand(MCOperand::CreateImm(BranchOffset));
808 return MCDisassembler::Success;
811 static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
814 const void *Decoder) {
815 unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
816 Inst.addOperand(MCOperand::CreateImm(JumpOffset));
817 return MCDisassembler::Success;
820 static DecodeStatus DecodeSimm16(MCInst &Inst,
823 const void *Decoder) {
824 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
825 return MCDisassembler::Success;
828 static DecodeStatus DecodeLSAImm(MCInst &Inst,
831 const void *Decoder) {
832 // We add one to the immediate field as it was encoded as 'imm - 1'.
833 Inst.addOperand(MCOperand::CreateImm(Insn + 1));
834 return MCDisassembler::Success;
837 static DecodeStatus DecodeInsSize(MCInst &Inst,
840 const void *Decoder) {
841 // First we need to grab the pos(lsb) from MCInst.
842 int Pos = Inst.getOperand(2).getImm();
843 int Size = (int) Insn - Pos + 1;
844 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
845 return MCDisassembler::Success;
848 static DecodeStatus DecodeExtSize(MCInst &Inst,
851 const void *Decoder) {
852 int Size = (int) Insn + 1;
853 Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
854 return MCDisassembler::Success;