171928e68SAkira Hatanaka //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===// 271928e68SAkira Hatanaka // 371928e68SAkira Hatanaka // The LLVM Compiler Infrastructure 471928e68SAkira Hatanaka // 571928e68SAkira Hatanaka // This file is distributed under the University of Illinois Open Source 671928e68SAkira Hatanaka // License. See LICENSE.TXT for details. 771928e68SAkira Hatanaka // 871928e68SAkira Hatanaka //===----------------------------------------------------------------------===// 971928e68SAkira Hatanaka // 1071928e68SAkira Hatanaka // This file is part of the Mips Disassembler. 1171928e68SAkira Hatanaka // 1271928e68SAkira Hatanaka //===----------------------------------------------------------------------===// 1371928e68SAkira Hatanaka 1471928e68SAkira Hatanaka #include "Mips.h" 159bf2b567SAkira Hatanaka #include "MipsRegisterInfo.h" 16ed0881b2SChandler Carruth #include "MipsSubtarget.h" 1771928e68SAkira Hatanaka #include "llvm/MC/MCDisassembler.h" 18ecaef49fSJim Grosbach #include "llvm/MC/MCFixedLenDisassembler.h" 19ed0881b2SChandler Carruth #include "llvm/MC/MCInst.h" 20ed0881b2SChandler Carruth #include "llvm/MC/MCSubtargetInfo.h" 21ed0881b2SChandler Carruth #include "llvm/Support/MathExtras.h" 2271928e68SAkira Hatanaka #include "llvm/Support/MemoryObject.h" 2371928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h" 2471928e68SAkira Hatanaka 2571928e68SAkira Hatanaka using namespace llvm; 2671928e68SAkira Hatanaka 2771928e68SAkira Hatanaka typedef MCDisassembler::DecodeStatus DecodeStatus; 2871928e68SAkira Hatanaka 29cb3e98cfSBenjamin Kramer namespace { 30cb3e98cfSBenjamin Kramer 319bf2b567SAkira Hatanaka /// MipsDisassemblerBase - a disasembler class for Mips. 329bf2b567SAkira Hatanaka class MipsDisassemblerBase : public MCDisassembler { 3371928e68SAkira Hatanaka public: 3471928e68SAkira Hatanaka /// Constructor - Initializes the disassembler. 3571928e68SAkira Hatanaka /// 369bf2b567SAkira Hatanaka MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 379bf2b567SAkira Hatanaka bool bigEndian) : 38*9bfa2e2eSAkira Hatanaka MCDisassembler(STI), RegInfo(Info), 39*9bfa2e2eSAkira Hatanaka IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {} 4071928e68SAkira Hatanaka 419bf2b567SAkira Hatanaka virtual ~MipsDisassemblerBase() {} 429bf2b567SAkira Hatanaka 43dcfd5b52SBenjamin Kramer const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); } 449bf2b567SAkira Hatanaka 45*9bfa2e2eSAkira Hatanaka bool isN64() const { return IsN64; } 46*9bfa2e2eSAkira Hatanaka 479bf2b567SAkira Hatanaka private: 48dcfd5b52SBenjamin Kramer OwningPtr<const MCRegisterInfo> RegInfo; 49*9bfa2e2eSAkira Hatanaka bool IsN64; 509bf2b567SAkira Hatanaka protected: 519bf2b567SAkira Hatanaka bool isBigEndian; 529bf2b567SAkira Hatanaka }; 539bf2b567SAkira Hatanaka 549bf2b567SAkira Hatanaka /// MipsDisassembler - a disasembler class for Mips32. 559bf2b567SAkira Hatanaka class MipsDisassembler : public MipsDisassemblerBase { 569bf2b567SAkira Hatanaka public: 579bf2b567SAkira Hatanaka /// Constructor - Initializes the disassembler. 589bf2b567SAkira Hatanaka /// 599bf2b567SAkira Hatanaka MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 609bf2b567SAkira Hatanaka bool bigEndian) : 619bf2b567SAkira Hatanaka MipsDisassemblerBase(STI, Info, bigEndian) {} 6271928e68SAkira Hatanaka 6371928e68SAkira Hatanaka /// getInstruction - See MCDisassembler. 649bf2b567SAkira Hatanaka virtual DecodeStatus getInstruction(MCInst &instr, 6571928e68SAkira Hatanaka uint64_t &size, 6671928e68SAkira Hatanaka const MemoryObject ®ion, 6771928e68SAkira Hatanaka uint64_t address, 6871928e68SAkira Hatanaka raw_ostream &vStream, 6971928e68SAkira Hatanaka raw_ostream &cStream) const; 7071928e68SAkira Hatanaka }; 7171928e68SAkira Hatanaka 7271928e68SAkira Hatanaka 7371928e68SAkira Hatanaka /// Mips64Disassembler - a disasembler class for Mips64. 749bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase { 7571928e68SAkira Hatanaka public: 7671928e68SAkira Hatanaka /// Constructor - Initializes the disassembler. 7771928e68SAkira Hatanaka /// 789bf2b567SAkira Hatanaka Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 799bf2b567SAkira Hatanaka bool bigEndian) : 809bf2b567SAkira Hatanaka MipsDisassemblerBase(STI, Info, bigEndian) {} 8171928e68SAkira Hatanaka 8271928e68SAkira Hatanaka /// getInstruction - See MCDisassembler. 839bf2b567SAkira Hatanaka virtual DecodeStatus getInstruction(MCInst &instr, 8471928e68SAkira Hatanaka uint64_t &size, 8571928e68SAkira Hatanaka const MemoryObject ®ion, 8671928e68SAkira Hatanaka uint64_t address, 8771928e68SAkira Hatanaka raw_ostream &vStream, 8871928e68SAkira Hatanaka raw_ostream &cStream) const; 8971928e68SAkira Hatanaka }; 9071928e68SAkira Hatanaka 91cb3e98cfSBenjamin Kramer } // end anonymous namespace 92cb3e98cfSBenjamin Kramer 9371928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them. 9471928e68SAkira Hatanaka // Definitions are further down. 9513e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 9671928e68SAkira Hatanaka unsigned RegNo, 9771928e68SAkira Hatanaka uint64_t Address, 9871928e68SAkira Hatanaka const void *Decoder); 9971928e68SAkira Hatanaka 100ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 101ec8a5490SReed Kotler unsigned RegNo, 102ec8a5490SReed Kotler uint64_t Address, 103ec8a5490SReed Kotler const void *Decoder); 104ec8a5490SReed Kotler 10513e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 10671928e68SAkira Hatanaka unsigned RegNo, 10771928e68SAkira Hatanaka uint64_t Address, 10871928e68SAkira Hatanaka const void *Decoder); 10971928e68SAkira Hatanaka 110*9bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 111*9bfa2e2eSAkira Hatanaka unsigned Insn, 112*9bfa2e2eSAkira Hatanaka uint64_t Address, 113*9bfa2e2eSAkira Hatanaka const void *Decoder); 114*9bfa2e2eSAkira Hatanaka 115654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 116ecabd1a5SAkira Hatanaka unsigned RegNo, 117ecabd1a5SAkira Hatanaka uint64_t Address, 118ecabd1a5SAkira Hatanaka const void *Decoder); 119ecabd1a5SAkira Hatanaka 12071928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 12171928e68SAkira Hatanaka unsigned RegNo, 12271928e68SAkira Hatanaka uint64_t Address, 12371928e68SAkira Hatanaka const void *Decoder); 12471928e68SAkira Hatanaka 12571928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 12671928e68SAkira Hatanaka unsigned RegNo, 12771928e68SAkira Hatanaka uint64_t Address, 12871928e68SAkira Hatanaka const void *Decoder); 12971928e68SAkira Hatanaka 13014e31a2fSAkira Hatanaka static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst, 13114e31a2fSAkira Hatanaka unsigned RegNo, 13214e31a2fSAkira Hatanaka uint64_t Address, 13314e31a2fSAkira Hatanaka const void *Decoder); 13414e31a2fSAkira Hatanaka 13571928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 13671928e68SAkira Hatanaka unsigned RegNo, 13771928e68SAkira Hatanaka uint64_t Address, 13871928e68SAkira Hatanaka const void *Decoder); 13971928e68SAkira Hatanaka 1401fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 1411fb1b8b8SAkira Hatanaka unsigned RegNo, 1421fb1b8b8SAkira Hatanaka uint64_t Address, 1431fb1b8b8SAkira Hatanaka const void *Decoder); 1441fb1b8b8SAkira Hatanaka 14571928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 14671928e68SAkira Hatanaka unsigned Insn, 14771928e68SAkira Hatanaka uint64_t Address, 14871928e68SAkira Hatanaka const void *Decoder); 14971928e68SAkira Hatanaka 15071928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 15171928e68SAkira Hatanaka unsigned RegNo, 15271928e68SAkira Hatanaka uint64_t Address, 15371928e68SAkira Hatanaka const void *Decoder); 15471928e68SAkira Hatanaka 15500fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 156ecabd1a5SAkira Hatanaka unsigned RegNo, 157ecabd1a5SAkira Hatanaka uint64_t Address, 158ecabd1a5SAkira Hatanaka const void *Decoder); 159ecabd1a5SAkira Hatanaka 1608002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 16159bfaf77SAkira Hatanaka unsigned RegNo, 16259bfaf77SAkira Hatanaka uint64_t Address, 16359bfaf77SAkira Hatanaka const void *Decoder); 16459bfaf77SAkira Hatanaka 1658002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 16659bfaf77SAkira Hatanaka unsigned RegNo, 16759bfaf77SAkira Hatanaka uint64_t Address, 16859bfaf77SAkira Hatanaka const void *Decoder); 16959bfaf77SAkira Hatanaka 17071928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 17171928e68SAkira Hatanaka unsigned Offset, 17271928e68SAkira Hatanaka uint64_t Address, 17371928e68SAkira Hatanaka const void *Decoder); 17471928e68SAkira Hatanaka 17571928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 17671928e68SAkira Hatanaka unsigned Insn, 17771928e68SAkira Hatanaka uint64_t Address, 17871928e68SAkira Hatanaka const void *Decoder); 17971928e68SAkira Hatanaka 18071928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 18171928e68SAkira Hatanaka unsigned Insn, 18271928e68SAkira Hatanaka uint64_t Address, 18371928e68SAkira Hatanaka const void *Decoder); 18471928e68SAkira Hatanaka 18571928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 18671928e68SAkira Hatanaka uint64_t Address, 18771928e68SAkira Hatanaka const void *Decoder); 18871928e68SAkira Hatanaka 18971928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 19071928e68SAkira Hatanaka unsigned Insn, 19171928e68SAkira Hatanaka uint64_t Address, 19271928e68SAkira Hatanaka const void *Decoder); 19371928e68SAkira Hatanaka 19471928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 19571928e68SAkira Hatanaka unsigned Insn, 19671928e68SAkira Hatanaka uint64_t Address, 19771928e68SAkira Hatanaka const void *Decoder); 19871928e68SAkira Hatanaka 19971928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 20071928e68SAkira Hatanaka unsigned Insn, 20171928e68SAkira Hatanaka uint64_t Address, 20271928e68SAkira Hatanaka const void *Decoder); 20371928e68SAkira Hatanaka 20471928e68SAkira Hatanaka namespace llvm { 20571928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 20671928e68SAkira Hatanaka TheMips64elTarget; 20771928e68SAkira Hatanaka } 20871928e68SAkira Hatanaka 20971928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler( 21071928e68SAkira Hatanaka const Target &T, 21171928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2129bf2b567SAkira Hatanaka return new MipsDisassembler(STI, T.createMCRegInfo(""), true); 21371928e68SAkira Hatanaka } 21471928e68SAkira Hatanaka 21571928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler( 21671928e68SAkira Hatanaka const Target &T, 21771928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2189bf2b567SAkira Hatanaka return new MipsDisassembler(STI, T.createMCRegInfo(""), false); 21971928e68SAkira Hatanaka } 22071928e68SAkira Hatanaka 22171928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler( 22271928e68SAkira Hatanaka const Target &T, 22371928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2249bf2b567SAkira Hatanaka return new Mips64Disassembler(STI, T.createMCRegInfo(""), true); 22571928e68SAkira Hatanaka } 22671928e68SAkira Hatanaka 22771928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler( 22871928e68SAkira Hatanaka const Target &T, 22971928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2309bf2b567SAkira Hatanaka return new Mips64Disassembler(STI, T.createMCRegInfo(""), false); 23171928e68SAkira Hatanaka } 23271928e68SAkira Hatanaka 23371928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() { 23471928e68SAkira Hatanaka // Register the disassembler. 23571928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 23671928e68SAkira Hatanaka createMipsDisassembler); 23771928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 23871928e68SAkira Hatanaka createMipselDisassembler); 23971928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64Target, 24071928e68SAkira Hatanaka createMips64Disassembler); 24171928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 24271928e68SAkira Hatanaka createMips64elDisassembler); 24371928e68SAkira Hatanaka } 24471928e68SAkira Hatanaka 24571928e68SAkira Hatanaka 24671928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc" 24771928e68SAkira Hatanaka 24871928e68SAkira Hatanaka /// readInstruction - read four bytes from the MemoryObject 24971928e68SAkira Hatanaka /// and return 32 bit word sorted according to the given endianess 25071928e68SAkira Hatanaka static DecodeStatus readInstruction32(const MemoryObject ®ion, 25171928e68SAkira Hatanaka uint64_t address, 25271928e68SAkira Hatanaka uint64_t &size, 25371928e68SAkira Hatanaka uint32_t &insn, 25471928e68SAkira Hatanaka bool isBigEndian) { 25571928e68SAkira Hatanaka uint8_t Bytes[4]; 25671928e68SAkira Hatanaka 25771928e68SAkira Hatanaka // We want to read exactly 4 Bytes of data. 258534d3a46SBenjamin Kramer if (region.readBytes(address, 4, Bytes) == -1) { 25971928e68SAkira Hatanaka size = 0; 26071928e68SAkira Hatanaka return MCDisassembler::Fail; 26171928e68SAkira Hatanaka } 26271928e68SAkira Hatanaka 26371928e68SAkira Hatanaka if (isBigEndian) { 26471928e68SAkira Hatanaka // Encoded as a big-endian 32-bit word in the stream. 26571928e68SAkira Hatanaka insn = (Bytes[3] << 0) | 26671928e68SAkira Hatanaka (Bytes[2] << 8) | 26771928e68SAkira Hatanaka (Bytes[1] << 16) | 26871928e68SAkira Hatanaka (Bytes[0] << 24); 26971928e68SAkira Hatanaka } 27071928e68SAkira Hatanaka else { 27171928e68SAkira Hatanaka // Encoded as a small-endian 32-bit word in the stream. 27271928e68SAkira Hatanaka insn = (Bytes[0] << 0) | 27371928e68SAkira Hatanaka (Bytes[1] << 8) | 27471928e68SAkira Hatanaka (Bytes[2] << 16) | 27571928e68SAkira Hatanaka (Bytes[3] << 24); 27671928e68SAkira Hatanaka } 27771928e68SAkira Hatanaka 27871928e68SAkira Hatanaka return MCDisassembler::Success; 27971928e68SAkira Hatanaka } 28071928e68SAkira Hatanaka 28171928e68SAkira Hatanaka DecodeStatus 28271928e68SAkira Hatanaka MipsDisassembler::getInstruction(MCInst &instr, 28371928e68SAkira Hatanaka uint64_t &Size, 28471928e68SAkira Hatanaka const MemoryObject &Region, 28571928e68SAkira Hatanaka uint64_t Address, 28671928e68SAkira Hatanaka raw_ostream &vStream, 28771928e68SAkira Hatanaka raw_ostream &cStream) const { 28871928e68SAkira Hatanaka uint32_t Insn; 28971928e68SAkira Hatanaka 29071928e68SAkira Hatanaka DecodeStatus Result = readInstruction32(Region, Address, Size, 29171928e68SAkira Hatanaka Insn, isBigEndian); 29271928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 29371928e68SAkira Hatanaka return MCDisassembler::Fail; 29471928e68SAkira Hatanaka 29571928e68SAkira Hatanaka // Calling the auto-generated decoder function. 296ecaef49fSJim Grosbach Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 297ecaef49fSJim Grosbach this, STI); 29871928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 29971928e68SAkira Hatanaka Size = 4; 30071928e68SAkira Hatanaka return Result; 30171928e68SAkira Hatanaka } 30271928e68SAkira Hatanaka 30371928e68SAkira Hatanaka return MCDisassembler::Fail; 30471928e68SAkira Hatanaka } 30571928e68SAkira Hatanaka 30671928e68SAkira Hatanaka DecodeStatus 30771928e68SAkira Hatanaka Mips64Disassembler::getInstruction(MCInst &instr, 30871928e68SAkira Hatanaka uint64_t &Size, 30971928e68SAkira Hatanaka const MemoryObject &Region, 31071928e68SAkira Hatanaka uint64_t Address, 31171928e68SAkira Hatanaka raw_ostream &vStream, 31271928e68SAkira Hatanaka raw_ostream &cStream) const { 31371928e68SAkira Hatanaka uint32_t Insn; 31471928e68SAkira Hatanaka 31571928e68SAkira Hatanaka DecodeStatus Result = readInstruction32(Region, Address, Size, 31671928e68SAkira Hatanaka Insn, isBigEndian); 31771928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 31871928e68SAkira Hatanaka return MCDisassembler::Fail; 31971928e68SAkira Hatanaka 32071928e68SAkira Hatanaka // Calling the auto-generated decoder function. 321ecaef49fSJim Grosbach Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address, 322ecaef49fSJim Grosbach this, STI); 32371928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 32471928e68SAkira Hatanaka Size = 4; 32571928e68SAkira Hatanaka return Result; 32671928e68SAkira Hatanaka } 32771928e68SAkira Hatanaka // If we fail to decode in Mips64 decoder space we can try in Mips32 328ecaef49fSJim Grosbach Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 329ecaef49fSJim Grosbach this, STI); 33071928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 33171928e68SAkira Hatanaka Size = 4; 33271928e68SAkira Hatanaka return Result; 33371928e68SAkira Hatanaka } 33471928e68SAkira Hatanaka 33571928e68SAkira Hatanaka return MCDisassembler::Fail; 33671928e68SAkira Hatanaka } 33771928e68SAkira Hatanaka 3389bf2b567SAkira Hatanaka static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 3399bf2b567SAkira Hatanaka const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D); 3409bf2b567SAkira Hatanaka return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo); 3419bf2b567SAkira Hatanaka } 3429bf2b567SAkira Hatanaka 343ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 344ec8a5490SReed Kotler unsigned RegNo, 345ec8a5490SReed Kotler uint64_t Address, 346ec8a5490SReed Kotler const void *Decoder) { 347ec8a5490SReed Kotler 348ec8a5490SReed Kotler return MCDisassembler::Fail; 349ec8a5490SReed Kotler 350ec8a5490SReed Kotler } 351ec8a5490SReed Kotler 35213e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 35371928e68SAkira Hatanaka unsigned RegNo, 35471928e68SAkira Hatanaka uint64_t Address, 35571928e68SAkira Hatanaka const void *Decoder) { 35671928e68SAkira Hatanaka 35771928e68SAkira Hatanaka if (RegNo > 31) 35871928e68SAkira Hatanaka return MCDisassembler::Fail; 35971928e68SAkira Hatanaka 36013e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); 3619bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 36271928e68SAkira Hatanaka return MCDisassembler::Success; 36371928e68SAkira Hatanaka } 36471928e68SAkira Hatanaka 36513e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 36671928e68SAkira Hatanaka unsigned RegNo, 36771928e68SAkira Hatanaka uint64_t Address, 36871928e68SAkira Hatanaka const void *Decoder) { 36971928e68SAkira Hatanaka if (RegNo > 31) 37071928e68SAkira Hatanaka return MCDisassembler::Fail; 37113e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); 3729bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 37371928e68SAkira Hatanaka return MCDisassembler::Success; 37471928e68SAkira Hatanaka } 37571928e68SAkira Hatanaka 376*9bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 377*9bfa2e2eSAkira Hatanaka unsigned RegNo, 378*9bfa2e2eSAkira Hatanaka uint64_t Address, 379*9bfa2e2eSAkira Hatanaka const void *Decoder) { 380*9bfa2e2eSAkira Hatanaka if (static_cast<const MipsDisassembler *>(Decoder)->isN64()) 381*9bfa2e2eSAkira Hatanaka return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); 382*9bfa2e2eSAkira Hatanaka 383*9bfa2e2eSAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 384*9bfa2e2eSAkira Hatanaka } 385*9bfa2e2eSAkira Hatanaka 386654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 387ecabd1a5SAkira Hatanaka unsigned RegNo, 388ecabd1a5SAkira Hatanaka uint64_t Address, 389ecabd1a5SAkira Hatanaka const void *Decoder) { 39013e6ccf3SAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 391ecabd1a5SAkira Hatanaka } 392ecabd1a5SAkira Hatanaka 39371928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 39471928e68SAkira Hatanaka unsigned RegNo, 39571928e68SAkira Hatanaka uint64_t Address, 39671928e68SAkira Hatanaka const void *Decoder) { 39771928e68SAkira Hatanaka if (RegNo > 31) 39871928e68SAkira Hatanaka return MCDisassembler::Fail; 39971928e68SAkira Hatanaka 4009bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 4019bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 40271928e68SAkira Hatanaka return MCDisassembler::Success; 40371928e68SAkira Hatanaka } 40471928e68SAkira Hatanaka 40571928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 40671928e68SAkira Hatanaka unsigned RegNo, 40771928e68SAkira Hatanaka uint64_t Address, 40871928e68SAkira Hatanaka const void *Decoder) { 40971928e68SAkira Hatanaka if (RegNo > 31) 41071928e68SAkira Hatanaka return MCDisassembler::Fail; 41171928e68SAkira Hatanaka 4129bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 4139bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 41471928e68SAkira Hatanaka return MCDisassembler::Success; 41571928e68SAkira Hatanaka } 41671928e68SAkira Hatanaka 41714e31a2fSAkira Hatanaka static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst, 41814e31a2fSAkira Hatanaka unsigned RegNo, 41914e31a2fSAkira Hatanaka uint64_t Address, 42014e31a2fSAkira Hatanaka const void *Decoder) { 42114e31a2fSAkira Hatanaka if (RegNo > 31) 42214e31a2fSAkira Hatanaka return MCDisassembler::Fail; 42314e31a2fSAkira Hatanaka 42414e31a2fSAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo); 42514e31a2fSAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 42614e31a2fSAkira Hatanaka return MCDisassembler::Success; 42714e31a2fSAkira Hatanaka } 42814e31a2fSAkira Hatanaka 42971928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 43071928e68SAkira Hatanaka unsigned RegNo, 43171928e68SAkira Hatanaka uint64_t Address, 43271928e68SAkira Hatanaka const void *Decoder) { 433253777fdSChad Rosier if (RegNo > 31) 434253777fdSChad Rosier return MCDisassembler::Fail; 435253777fdSChad Rosier unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); 436253777fdSChad Rosier Inst.addOperand(MCOperand::CreateReg(Reg)); 43771928e68SAkira Hatanaka return MCDisassembler::Success; 43871928e68SAkira Hatanaka } 43971928e68SAkira Hatanaka 4401fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 4411fb1b8b8SAkira Hatanaka unsigned RegNo, 4421fb1b8b8SAkira Hatanaka uint64_t Address, 4431fb1b8b8SAkira Hatanaka const void *Decoder) { 4441fb1b8b8SAkira Hatanaka if (RegNo > 7) 4451fb1b8b8SAkira Hatanaka return MCDisassembler::Fail; 4461fb1b8b8SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); 4471fb1b8b8SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 4481fb1b8b8SAkira Hatanaka return MCDisassembler::Success; 4491fb1b8b8SAkira Hatanaka } 4501fb1b8b8SAkira Hatanaka 45171928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 45271928e68SAkira Hatanaka unsigned Insn, 45371928e68SAkira Hatanaka uint64_t Address, 45471928e68SAkira Hatanaka const void *Decoder) { 45571928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 456ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 457ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 4589bf2b567SAkira Hatanaka 45913e6ccf3SAkira Hatanaka Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 46013e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 46171928e68SAkira Hatanaka 46271928e68SAkira Hatanaka if(Inst.getOpcode() == Mips::SC){ 4639bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 46471928e68SAkira Hatanaka } 46571928e68SAkira Hatanaka 4669bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 4679bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 46871928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 46971928e68SAkira Hatanaka 47071928e68SAkira Hatanaka return MCDisassembler::Success; 47171928e68SAkira Hatanaka } 47271928e68SAkira Hatanaka 47371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, 47471928e68SAkira Hatanaka unsigned Insn, 47571928e68SAkira Hatanaka uint64_t Address, 47671928e68SAkira Hatanaka const void *Decoder) { 47771928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 478ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 479ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 48071928e68SAkira Hatanaka 4819bf2b567SAkira Hatanaka Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 48213e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 4839bf2b567SAkira Hatanaka 4849bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 4859bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 48671928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 48771928e68SAkira Hatanaka 48871928e68SAkira Hatanaka return MCDisassembler::Success; 48971928e68SAkira Hatanaka } 49071928e68SAkira Hatanaka 49171928e68SAkira Hatanaka 49271928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 49371928e68SAkira Hatanaka unsigned RegNo, 49471928e68SAkira Hatanaka uint64_t Address, 49571928e68SAkira Hatanaka const void *Decoder) { 49671928e68SAkira Hatanaka // Currently only hardware register 29 is supported. 49771928e68SAkira Hatanaka if (RegNo != 29) 49871928e68SAkira Hatanaka return MCDisassembler::Fail; 49971928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); 50071928e68SAkira Hatanaka return MCDisassembler::Success; 50171928e68SAkira Hatanaka } 50271928e68SAkira Hatanaka 50371928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 50471928e68SAkira Hatanaka unsigned RegNo, 50571928e68SAkira Hatanaka uint64_t Address, 50671928e68SAkira Hatanaka const void *Decoder) { 5079bf2b567SAkira Hatanaka if (RegNo > 30 || RegNo %2) 50871928e68SAkira Hatanaka return MCDisassembler::Fail; 50971928e68SAkira Hatanaka 5109bf2b567SAkira Hatanaka ; 5119bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 5129bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 51371928e68SAkira Hatanaka return MCDisassembler::Success; 51471928e68SAkira Hatanaka } 51571928e68SAkira Hatanaka 51600fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 517ecabd1a5SAkira Hatanaka unsigned RegNo, 518ecabd1a5SAkira Hatanaka uint64_t Address, 519ecabd1a5SAkira Hatanaka const void *Decoder) { 520ecabd1a5SAkira Hatanaka if (RegNo >= 4) 521ecabd1a5SAkira Hatanaka return MCDisassembler::Fail; 522ecabd1a5SAkira Hatanaka 52300fcf2e1SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo); 524ecabd1a5SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 525ecabd1a5SAkira Hatanaka return MCDisassembler::Success; 526ecabd1a5SAkira Hatanaka } 527ecabd1a5SAkira Hatanaka 5288002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 52959bfaf77SAkira Hatanaka unsigned RegNo, 53059bfaf77SAkira Hatanaka uint64_t Address, 53159bfaf77SAkira Hatanaka const void *Decoder) { 53259bfaf77SAkira Hatanaka if (RegNo >= 4) 53359bfaf77SAkira Hatanaka return MCDisassembler::Fail; 53459bfaf77SAkira Hatanaka 5358002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo); 53659bfaf77SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 53759bfaf77SAkira Hatanaka return MCDisassembler::Success; 53859bfaf77SAkira Hatanaka } 53959bfaf77SAkira Hatanaka 5408002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 54159bfaf77SAkira Hatanaka unsigned RegNo, 54259bfaf77SAkira Hatanaka uint64_t Address, 54359bfaf77SAkira Hatanaka const void *Decoder) { 54459bfaf77SAkira Hatanaka if (RegNo >= 4) 54559bfaf77SAkira Hatanaka return MCDisassembler::Fail; 54659bfaf77SAkira Hatanaka 5478002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo); 54859bfaf77SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 54959bfaf77SAkira Hatanaka return MCDisassembler::Success; 55059bfaf77SAkira Hatanaka } 55159bfaf77SAkira Hatanaka 55271928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 55371928e68SAkira Hatanaka unsigned Offset, 55471928e68SAkira Hatanaka uint64_t Address, 55571928e68SAkira Hatanaka const void *Decoder) { 55671928e68SAkira Hatanaka unsigned BranchOffset = Offset & 0xffff; 55771928e68SAkira Hatanaka BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 55871928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 55971928e68SAkira Hatanaka return MCDisassembler::Success; 56071928e68SAkira Hatanaka } 56171928e68SAkira Hatanaka 56271928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 56371928e68SAkira Hatanaka unsigned Insn, 56471928e68SAkira Hatanaka uint64_t Address, 56571928e68SAkira Hatanaka const void *Decoder) { 56671928e68SAkira Hatanaka 567ecaef49fSJim Grosbach unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 56871928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 56971928e68SAkira Hatanaka return MCDisassembler::Success; 57071928e68SAkira Hatanaka } 57171928e68SAkira Hatanaka 57271928e68SAkira Hatanaka 57371928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 57471928e68SAkira Hatanaka unsigned Insn, 57571928e68SAkira Hatanaka uint64_t Address, 57671928e68SAkira Hatanaka const void *Decoder) { 57771928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); 57871928e68SAkira Hatanaka return MCDisassembler::Success; 57971928e68SAkira Hatanaka } 58071928e68SAkira Hatanaka 58171928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 58271928e68SAkira Hatanaka unsigned Insn, 58371928e68SAkira Hatanaka uint64_t Address, 58471928e68SAkira Hatanaka const void *Decoder) { 58571928e68SAkira Hatanaka // First we need to grab the pos(lsb) from MCInst. 58671928e68SAkira Hatanaka int Pos = Inst.getOperand(2).getImm(); 58771928e68SAkira Hatanaka int Size = (int) Insn - Pos + 1; 58871928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 58971928e68SAkira Hatanaka return MCDisassembler::Success; 59071928e68SAkira Hatanaka } 59171928e68SAkira Hatanaka 59271928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 59371928e68SAkira Hatanaka unsigned Insn, 59471928e68SAkira Hatanaka uint64_t Address, 59571928e68SAkira Hatanaka const void *Decoder) { 59671928e68SAkira Hatanaka int Size = (int) Insn + 1; 59771928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 59871928e68SAkira Hatanaka return MCDisassembler::Success; 59971928e68SAkira Hatanaka } 600