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" 1571928e68SAkira Hatanaka #include "MipsSubtarget.h" 169bf2b567SAkira Hatanaka #include "MipsRegisterInfo.h" 1771928e68SAkira Hatanaka #include "llvm/MC/EDInstInfo.h" 1871928e68SAkira Hatanaka #include "llvm/MC/MCDisassembler.h" 19*ecaef49fSJim Grosbach #include "llvm/MC/MCFixedLenDisassembler.h" 2071928e68SAkira Hatanaka #include "llvm/Support/MemoryObject.h" 2171928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h" 2271928e68SAkira Hatanaka #include "llvm/MC/MCSubtargetInfo.h" 2371928e68SAkira Hatanaka #include "llvm/MC/MCInst.h" 2471928e68SAkira Hatanaka #include "llvm/Support/MathExtras.h" 2571928e68SAkira Hatanaka 2671928e68SAkira Hatanaka #include "MipsGenEDInfo.inc" 2771928e68SAkira Hatanaka 2871928e68SAkira Hatanaka using namespace llvm; 2971928e68SAkira Hatanaka 3071928e68SAkira Hatanaka typedef MCDisassembler::DecodeStatus DecodeStatus; 3171928e68SAkira Hatanaka 32cb3e98cfSBenjamin Kramer namespace { 33cb3e98cfSBenjamin Kramer 349bf2b567SAkira Hatanaka /// MipsDisassemblerBase - a disasembler class for Mips. 359bf2b567SAkira Hatanaka class MipsDisassemblerBase : public MCDisassembler { 3671928e68SAkira Hatanaka public: 3771928e68SAkira Hatanaka /// Constructor - Initializes the disassembler. 3871928e68SAkira Hatanaka /// 399bf2b567SAkira Hatanaka MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 409bf2b567SAkira Hatanaka bool bigEndian) : 419bf2b567SAkira Hatanaka MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {} 4271928e68SAkira Hatanaka 439bf2b567SAkira Hatanaka virtual ~MipsDisassemblerBase() {} 449bf2b567SAkira Hatanaka 459bf2b567SAkira Hatanaka /// getEDInfo - See MCDisassembler. 469bf2b567SAkira Hatanaka const EDInstInfo *getEDInfo() const; 479bf2b567SAkira Hatanaka 489bf2b567SAkira Hatanaka const MCRegisterInfo *getRegInfo() const { return RegInfo; } 499bf2b567SAkira Hatanaka 509bf2b567SAkira Hatanaka private: 519bf2b567SAkira Hatanaka const MCRegisterInfo *RegInfo; 529bf2b567SAkira Hatanaka protected: 539bf2b567SAkira Hatanaka bool isBigEndian; 549bf2b567SAkira Hatanaka }; 559bf2b567SAkira Hatanaka 569bf2b567SAkira Hatanaka /// MipsDisassembler - a disasembler class for Mips32. 579bf2b567SAkira Hatanaka class MipsDisassembler : public MipsDisassemblerBase { 589bf2b567SAkira Hatanaka public: 599bf2b567SAkira Hatanaka /// Constructor - Initializes the disassembler. 609bf2b567SAkira Hatanaka /// 619bf2b567SAkira Hatanaka MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 629bf2b567SAkira Hatanaka bool bigEndian) : 639bf2b567SAkira Hatanaka MipsDisassemblerBase(STI, Info, bigEndian) {} 6471928e68SAkira Hatanaka 6571928e68SAkira Hatanaka /// getInstruction - See MCDisassembler. 669bf2b567SAkira Hatanaka virtual DecodeStatus getInstruction(MCInst &instr, 6771928e68SAkira Hatanaka uint64_t &size, 6871928e68SAkira Hatanaka const MemoryObject ®ion, 6971928e68SAkira Hatanaka uint64_t address, 7071928e68SAkira Hatanaka raw_ostream &vStream, 7171928e68SAkira Hatanaka raw_ostream &cStream) const; 7271928e68SAkira Hatanaka }; 7371928e68SAkira Hatanaka 7471928e68SAkira Hatanaka 7571928e68SAkira Hatanaka /// Mips64Disassembler - a disasembler class for Mips64. 769bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase { 7771928e68SAkira Hatanaka public: 7871928e68SAkira Hatanaka /// Constructor - Initializes the disassembler. 7971928e68SAkira Hatanaka /// 809bf2b567SAkira Hatanaka Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 819bf2b567SAkira Hatanaka bool bigEndian) : 829bf2b567SAkira Hatanaka MipsDisassemblerBase(STI, Info, bigEndian) {} 8371928e68SAkira Hatanaka 8471928e68SAkira Hatanaka /// getInstruction - See MCDisassembler. 859bf2b567SAkira Hatanaka virtual DecodeStatus getInstruction(MCInst &instr, 8671928e68SAkira Hatanaka uint64_t &size, 8771928e68SAkira Hatanaka const MemoryObject ®ion, 8871928e68SAkira Hatanaka uint64_t address, 8971928e68SAkira Hatanaka raw_ostream &vStream, 9071928e68SAkira Hatanaka raw_ostream &cStream) const; 9171928e68SAkira Hatanaka }; 9271928e68SAkira Hatanaka 93cb3e98cfSBenjamin Kramer } // end anonymous namespace 94cb3e98cfSBenjamin Kramer 959bf2b567SAkira Hatanaka const EDInstInfo *MipsDisassemblerBase::getEDInfo() const { 9671928e68SAkira Hatanaka return instInfoMips; 9771928e68SAkira Hatanaka } 9871928e68SAkira Hatanaka 9971928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them. 10071928e68SAkira Hatanaka // Definitions are further down. 10171928e68SAkira Hatanaka static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, 10271928e68SAkira Hatanaka unsigned RegNo, 10371928e68SAkira Hatanaka uint64_t Address, 10471928e68SAkira Hatanaka const void *Decoder); 10571928e68SAkira Hatanaka 10671928e68SAkira Hatanaka static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, 10771928e68SAkira Hatanaka unsigned RegNo, 10871928e68SAkira Hatanaka uint64_t Address, 10971928e68SAkira Hatanaka const void *Decoder); 11071928e68SAkira Hatanaka 11171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 11271928e68SAkira Hatanaka unsigned RegNo, 11371928e68SAkira Hatanaka uint64_t Address, 11471928e68SAkira Hatanaka const void *Decoder); 11571928e68SAkira Hatanaka 11671928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 11771928e68SAkira Hatanaka unsigned RegNo, 11871928e68SAkira Hatanaka uint64_t Address, 11971928e68SAkira Hatanaka const void *Decoder); 12071928e68SAkira Hatanaka 12171928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 12271928e68SAkira Hatanaka unsigned RegNo, 12371928e68SAkira Hatanaka uint64_t Address, 12471928e68SAkira Hatanaka const void *Decoder); 12571928e68SAkira Hatanaka 12671928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 12771928e68SAkira Hatanaka unsigned Insn, 12871928e68SAkira Hatanaka uint64_t Address, 12971928e68SAkira Hatanaka const void *Decoder); 13071928e68SAkira Hatanaka 13171928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 13271928e68SAkira Hatanaka unsigned RegNo, 13371928e68SAkira Hatanaka uint64_t Address, 13471928e68SAkira Hatanaka const void *Decoder); 13571928e68SAkira Hatanaka 13671928e68SAkira Hatanaka static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, 13771928e68SAkira Hatanaka unsigned Insn, 13871928e68SAkira Hatanaka uint64_t Address, 13971928e68SAkira Hatanaka const void *Decoder); 14071928e68SAkira Hatanaka 14171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 14271928e68SAkira Hatanaka unsigned Offset, 14371928e68SAkira Hatanaka uint64_t Address, 14471928e68SAkira Hatanaka const void *Decoder); 14571928e68SAkira Hatanaka 14671928e68SAkira Hatanaka static DecodeStatus DecodeBC1(MCInst &Inst, 14771928e68SAkira Hatanaka unsigned Insn, 14871928e68SAkira Hatanaka uint64_t Address, 14971928e68SAkira Hatanaka const void *Decoder); 15071928e68SAkira Hatanaka 15171928e68SAkira Hatanaka 15271928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 15371928e68SAkira Hatanaka unsigned Insn, 15471928e68SAkira Hatanaka uint64_t Address, 15571928e68SAkira Hatanaka const void *Decoder); 15671928e68SAkira Hatanaka 15771928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 15871928e68SAkira Hatanaka unsigned Insn, 15971928e68SAkira Hatanaka uint64_t Address, 16071928e68SAkira Hatanaka const void *Decoder); 16171928e68SAkira Hatanaka 16271928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 16371928e68SAkira Hatanaka uint64_t Address, 16471928e68SAkira Hatanaka const void *Decoder); 16571928e68SAkira Hatanaka 16671928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 16771928e68SAkira Hatanaka unsigned Insn, 16871928e68SAkira Hatanaka uint64_t Address, 16971928e68SAkira Hatanaka const void *Decoder); 17071928e68SAkira Hatanaka 17171928e68SAkira Hatanaka static DecodeStatus DecodeCondCode(MCInst &Inst, 17271928e68SAkira Hatanaka unsigned Insn, 17371928e68SAkira Hatanaka uint64_t Address, 17471928e68SAkira Hatanaka const void *Decoder); 17571928e68SAkira Hatanaka 17671928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 17771928e68SAkira Hatanaka unsigned Insn, 17871928e68SAkira Hatanaka uint64_t Address, 17971928e68SAkira Hatanaka const void *Decoder); 18071928e68SAkira Hatanaka 18171928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 18271928e68SAkira Hatanaka unsigned Insn, 18371928e68SAkira Hatanaka uint64_t Address, 18471928e68SAkira Hatanaka const void *Decoder); 18571928e68SAkira Hatanaka 18671928e68SAkira Hatanaka namespace llvm { 18771928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 18871928e68SAkira Hatanaka TheMips64elTarget; 18971928e68SAkira Hatanaka } 19071928e68SAkira Hatanaka 19171928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler( 19271928e68SAkira Hatanaka const Target &T, 19371928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 1949bf2b567SAkira Hatanaka return new MipsDisassembler(STI, T.createMCRegInfo(""), true); 19571928e68SAkira Hatanaka } 19671928e68SAkira Hatanaka 19771928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler( 19871928e68SAkira Hatanaka const Target &T, 19971928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2009bf2b567SAkira Hatanaka return new MipsDisassembler(STI, T.createMCRegInfo(""), false); 20171928e68SAkira Hatanaka } 20271928e68SAkira Hatanaka 20371928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler( 20471928e68SAkira Hatanaka const Target &T, 20571928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2069bf2b567SAkira Hatanaka return new Mips64Disassembler(STI, T.createMCRegInfo(""), true); 20771928e68SAkira Hatanaka } 20871928e68SAkira Hatanaka 20971928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler( 21071928e68SAkira Hatanaka const Target &T, 21171928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2129bf2b567SAkira Hatanaka return new Mips64Disassembler(STI, T.createMCRegInfo(""), false); 21371928e68SAkira Hatanaka } 21471928e68SAkira Hatanaka 21571928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() { 21671928e68SAkira Hatanaka // Register the disassembler. 21771928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 21871928e68SAkira Hatanaka createMipsDisassembler); 21971928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 22071928e68SAkira Hatanaka createMipselDisassembler); 22171928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64Target, 22271928e68SAkira Hatanaka createMips64Disassembler); 22371928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 22471928e68SAkira Hatanaka createMips64elDisassembler); 22571928e68SAkira Hatanaka } 22671928e68SAkira Hatanaka 22771928e68SAkira Hatanaka 22871928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc" 22971928e68SAkira Hatanaka 23071928e68SAkira Hatanaka /// readInstruction - read four bytes from the MemoryObject 23171928e68SAkira Hatanaka /// and return 32 bit word sorted according to the given endianess 23271928e68SAkira Hatanaka static DecodeStatus readInstruction32(const MemoryObject ®ion, 23371928e68SAkira Hatanaka uint64_t address, 23471928e68SAkira Hatanaka uint64_t &size, 23571928e68SAkira Hatanaka uint32_t &insn, 23671928e68SAkira Hatanaka bool isBigEndian) { 23771928e68SAkira Hatanaka uint8_t Bytes[4]; 23871928e68SAkira Hatanaka 23971928e68SAkira Hatanaka // We want to read exactly 4 Bytes of data. 24071928e68SAkira Hatanaka if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) { 24171928e68SAkira Hatanaka size = 0; 24271928e68SAkira Hatanaka return MCDisassembler::Fail; 24371928e68SAkira Hatanaka } 24471928e68SAkira Hatanaka 24571928e68SAkira Hatanaka if (isBigEndian) { 24671928e68SAkira Hatanaka // Encoded as a big-endian 32-bit word in the stream. 24771928e68SAkira Hatanaka insn = (Bytes[3] << 0) | 24871928e68SAkira Hatanaka (Bytes[2] << 8) | 24971928e68SAkira Hatanaka (Bytes[1] << 16) | 25071928e68SAkira Hatanaka (Bytes[0] << 24); 25171928e68SAkira Hatanaka } 25271928e68SAkira Hatanaka else { 25371928e68SAkira Hatanaka // Encoded as a small-endian 32-bit word in the stream. 25471928e68SAkira Hatanaka insn = (Bytes[0] << 0) | 25571928e68SAkira Hatanaka (Bytes[1] << 8) | 25671928e68SAkira Hatanaka (Bytes[2] << 16) | 25771928e68SAkira Hatanaka (Bytes[3] << 24); 25871928e68SAkira Hatanaka } 25971928e68SAkira Hatanaka 26071928e68SAkira Hatanaka return MCDisassembler::Success; 26171928e68SAkira Hatanaka } 26271928e68SAkira Hatanaka 26371928e68SAkira Hatanaka DecodeStatus 26471928e68SAkira Hatanaka MipsDisassembler::getInstruction(MCInst &instr, 26571928e68SAkira Hatanaka uint64_t &Size, 26671928e68SAkira Hatanaka const MemoryObject &Region, 26771928e68SAkira Hatanaka uint64_t Address, 26871928e68SAkira Hatanaka raw_ostream &vStream, 26971928e68SAkira Hatanaka raw_ostream &cStream) const { 27071928e68SAkira Hatanaka uint32_t Insn; 27171928e68SAkira Hatanaka 27271928e68SAkira Hatanaka DecodeStatus Result = readInstruction32(Region, Address, Size, 27371928e68SAkira Hatanaka Insn, isBigEndian); 27471928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 27571928e68SAkira Hatanaka return MCDisassembler::Fail; 27671928e68SAkira Hatanaka 27771928e68SAkira Hatanaka // Calling the auto-generated decoder function. 278*ecaef49fSJim Grosbach Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 279*ecaef49fSJim Grosbach this, STI); 28071928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 28171928e68SAkira Hatanaka Size = 4; 28271928e68SAkira Hatanaka return Result; 28371928e68SAkira Hatanaka } 28471928e68SAkira Hatanaka 28571928e68SAkira Hatanaka return MCDisassembler::Fail; 28671928e68SAkira Hatanaka } 28771928e68SAkira Hatanaka 28871928e68SAkira Hatanaka DecodeStatus 28971928e68SAkira Hatanaka Mips64Disassembler::getInstruction(MCInst &instr, 29071928e68SAkira Hatanaka uint64_t &Size, 29171928e68SAkira Hatanaka const MemoryObject &Region, 29271928e68SAkira Hatanaka uint64_t Address, 29371928e68SAkira Hatanaka raw_ostream &vStream, 29471928e68SAkira Hatanaka raw_ostream &cStream) const { 29571928e68SAkira Hatanaka uint32_t Insn; 29671928e68SAkira Hatanaka 29771928e68SAkira Hatanaka DecodeStatus Result = readInstruction32(Region, Address, Size, 29871928e68SAkira Hatanaka Insn, isBigEndian); 29971928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 30071928e68SAkira Hatanaka return MCDisassembler::Fail; 30171928e68SAkira Hatanaka 30271928e68SAkira Hatanaka // Calling the auto-generated decoder function. 303*ecaef49fSJim Grosbach Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address, 304*ecaef49fSJim Grosbach this, STI); 30571928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 30671928e68SAkira Hatanaka Size = 4; 30771928e68SAkira Hatanaka return Result; 30871928e68SAkira Hatanaka } 30971928e68SAkira Hatanaka // If we fail to decode in Mips64 decoder space we can try in Mips32 310*ecaef49fSJim Grosbach Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 311*ecaef49fSJim Grosbach this, STI); 31271928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 31371928e68SAkira Hatanaka Size = 4; 31471928e68SAkira Hatanaka return Result; 31571928e68SAkira Hatanaka } 31671928e68SAkira Hatanaka 31771928e68SAkira Hatanaka return MCDisassembler::Fail; 31871928e68SAkira Hatanaka } 31971928e68SAkira Hatanaka 3209bf2b567SAkira Hatanaka static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 3219bf2b567SAkira Hatanaka const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D); 3229bf2b567SAkira Hatanaka return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo); 3239bf2b567SAkira Hatanaka } 3249bf2b567SAkira Hatanaka 32571928e68SAkira Hatanaka static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, 32671928e68SAkira Hatanaka unsigned RegNo, 32771928e68SAkira Hatanaka uint64_t Address, 32871928e68SAkira Hatanaka const void *Decoder) { 32971928e68SAkira Hatanaka 33071928e68SAkira Hatanaka if (RegNo > 31) 33171928e68SAkira Hatanaka return MCDisassembler::Fail; 33271928e68SAkira Hatanaka 3339bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo); 3349bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 33571928e68SAkira Hatanaka return MCDisassembler::Success; 33671928e68SAkira Hatanaka } 33771928e68SAkira Hatanaka 33871928e68SAkira Hatanaka static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, 33971928e68SAkira Hatanaka unsigned RegNo, 34071928e68SAkira Hatanaka uint64_t Address, 34171928e68SAkira Hatanaka const void *Decoder) { 34271928e68SAkira Hatanaka if (RegNo > 31) 34371928e68SAkira Hatanaka return MCDisassembler::Fail; 3449bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo); 3459bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 34671928e68SAkira Hatanaka return MCDisassembler::Success; 34771928e68SAkira Hatanaka } 34871928e68SAkira Hatanaka 34971928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 35071928e68SAkira Hatanaka unsigned RegNo, 35171928e68SAkira Hatanaka uint64_t Address, 35271928e68SAkira Hatanaka const void *Decoder) { 35371928e68SAkira Hatanaka if (RegNo > 31) 35471928e68SAkira Hatanaka return MCDisassembler::Fail; 35571928e68SAkira Hatanaka 3569bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 3579bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 35871928e68SAkira Hatanaka return MCDisassembler::Success; 35971928e68SAkira Hatanaka } 36071928e68SAkira Hatanaka 36171928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 36271928e68SAkira Hatanaka unsigned RegNo, 36371928e68SAkira Hatanaka uint64_t Address, 36471928e68SAkira Hatanaka const void *Decoder) { 36571928e68SAkira Hatanaka if (RegNo > 31) 36671928e68SAkira Hatanaka return MCDisassembler::Fail; 36771928e68SAkira Hatanaka 3689bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 3699bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 37071928e68SAkira Hatanaka return MCDisassembler::Success; 37171928e68SAkira Hatanaka } 37271928e68SAkira Hatanaka 37371928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 37471928e68SAkira Hatanaka unsigned RegNo, 37571928e68SAkira Hatanaka uint64_t Address, 37671928e68SAkira Hatanaka const void *Decoder) { 37771928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(RegNo)); 37871928e68SAkira Hatanaka return MCDisassembler::Success; 37971928e68SAkira Hatanaka } 38071928e68SAkira Hatanaka 38171928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 38271928e68SAkira Hatanaka unsigned Insn, 38371928e68SAkira Hatanaka uint64_t Address, 38471928e68SAkira Hatanaka const void *Decoder) { 38571928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 386*ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 387*ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 3889bf2b567SAkira Hatanaka 3899bf2b567SAkira Hatanaka Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg); 3909bf2b567SAkira Hatanaka Base = getReg(Decoder, Mips::CPURegsRegClassID, Base); 39171928e68SAkira Hatanaka 39271928e68SAkira Hatanaka if(Inst.getOpcode() == Mips::SC){ 3939bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 39471928e68SAkira Hatanaka } 39571928e68SAkira Hatanaka 3969bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 3979bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 39871928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 39971928e68SAkira Hatanaka 40071928e68SAkira Hatanaka return MCDisassembler::Success; 40171928e68SAkira Hatanaka } 40271928e68SAkira Hatanaka 40371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, 40471928e68SAkira Hatanaka unsigned Insn, 40571928e68SAkira Hatanaka uint64_t Address, 40671928e68SAkira Hatanaka const void *Decoder) { 40771928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 408*ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 409*ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 41071928e68SAkira Hatanaka 4119bf2b567SAkira Hatanaka Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 4129bf2b567SAkira Hatanaka Base = getReg(Decoder, Mips::CPURegsRegClassID, Base); 4139bf2b567SAkira Hatanaka 4149bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 4159bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 41671928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 41771928e68SAkira Hatanaka 41871928e68SAkira Hatanaka return MCDisassembler::Success; 41971928e68SAkira Hatanaka } 42071928e68SAkira Hatanaka 42171928e68SAkira Hatanaka 42271928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 42371928e68SAkira Hatanaka unsigned RegNo, 42471928e68SAkira Hatanaka uint64_t Address, 42571928e68SAkira Hatanaka const void *Decoder) { 42671928e68SAkira Hatanaka // Currently only hardware register 29 is supported. 42771928e68SAkira Hatanaka if (RegNo != 29) 42871928e68SAkira Hatanaka return MCDisassembler::Fail; 42971928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); 43071928e68SAkira Hatanaka return MCDisassembler::Success; 43171928e68SAkira Hatanaka } 43271928e68SAkira Hatanaka 43371928e68SAkira Hatanaka static DecodeStatus DecodeCondCode(MCInst &Inst, 43471928e68SAkira Hatanaka unsigned Insn, 43571928e68SAkira Hatanaka uint64_t Address, 43671928e68SAkira Hatanaka const void *Decoder) { 43771928e68SAkira Hatanaka int CondCode = Insn & 0xf; 43871928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(CondCode)); 43971928e68SAkira Hatanaka return MCDisassembler::Success; 44071928e68SAkira Hatanaka } 44171928e68SAkira Hatanaka 44271928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 44371928e68SAkira Hatanaka unsigned RegNo, 44471928e68SAkira Hatanaka uint64_t Address, 44571928e68SAkira Hatanaka const void *Decoder) { 4469bf2b567SAkira Hatanaka if (RegNo > 30 || RegNo %2) 44771928e68SAkira Hatanaka return MCDisassembler::Fail; 44871928e68SAkira Hatanaka 4499bf2b567SAkira Hatanaka ; 4509bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 4519bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 45271928e68SAkira Hatanaka return MCDisassembler::Success; 45371928e68SAkira Hatanaka } 45471928e68SAkira Hatanaka 45571928e68SAkira Hatanaka static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, 45671928e68SAkira Hatanaka unsigned RegNo, 45771928e68SAkira Hatanaka uint64_t Address, 45871928e68SAkira Hatanaka const void *Decoder) { 45971928e68SAkira Hatanaka //Currently only hardware register 29 is supported 46071928e68SAkira Hatanaka if (RegNo != 29) 46171928e68SAkira Hatanaka return MCDisassembler::Fail; 4629bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64)); 46371928e68SAkira Hatanaka return MCDisassembler::Success; 46471928e68SAkira Hatanaka } 46571928e68SAkira Hatanaka 46671928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 46771928e68SAkira Hatanaka unsigned Offset, 46871928e68SAkira Hatanaka uint64_t Address, 46971928e68SAkira Hatanaka const void *Decoder) { 47071928e68SAkira Hatanaka unsigned BranchOffset = Offset & 0xffff; 47171928e68SAkira Hatanaka BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 47271928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 47371928e68SAkira Hatanaka return MCDisassembler::Success; 47471928e68SAkira Hatanaka } 47571928e68SAkira Hatanaka 47671928e68SAkira Hatanaka static DecodeStatus DecodeBC1(MCInst &Inst, 47771928e68SAkira Hatanaka unsigned Insn, 47871928e68SAkira Hatanaka uint64_t Address, 47971928e68SAkira Hatanaka const void *Decoder) { 48071928e68SAkira Hatanaka unsigned BranchOffset = Insn & 0xffff; 48171928e68SAkira Hatanaka BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 48271928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 48371928e68SAkira Hatanaka return MCDisassembler::Success; 48471928e68SAkira Hatanaka } 48571928e68SAkira Hatanaka 48671928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 48771928e68SAkira Hatanaka unsigned Insn, 48871928e68SAkira Hatanaka uint64_t Address, 48971928e68SAkira Hatanaka const void *Decoder) { 49071928e68SAkira Hatanaka 491*ecaef49fSJim Grosbach unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 49271928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 49371928e68SAkira Hatanaka return MCDisassembler::Success; 49471928e68SAkira Hatanaka } 49571928e68SAkira Hatanaka 49671928e68SAkira Hatanaka 49771928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 49871928e68SAkira Hatanaka unsigned Insn, 49971928e68SAkira Hatanaka uint64_t Address, 50071928e68SAkira Hatanaka const void *Decoder) { 50171928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); 50271928e68SAkira Hatanaka return MCDisassembler::Success; 50371928e68SAkira Hatanaka } 50471928e68SAkira Hatanaka 50571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 50671928e68SAkira Hatanaka unsigned Insn, 50771928e68SAkira Hatanaka uint64_t Address, 50871928e68SAkira Hatanaka const void *Decoder) { 50971928e68SAkira Hatanaka // First we need to grab the pos(lsb) from MCInst. 51071928e68SAkira Hatanaka int Pos = Inst.getOperand(2).getImm(); 51171928e68SAkira Hatanaka int Size = (int) Insn - Pos + 1; 51271928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 51371928e68SAkira Hatanaka return MCDisassembler::Success; 51471928e68SAkira Hatanaka } 51571928e68SAkira Hatanaka 51671928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 51771928e68SAkira Hatanaka unsigned Insn, 51871928e68SAkira Hatanaka uint64_t Address, 51971928e68SAkira Hatanaka const void *Decoder) { 52071928e68SAkira Hatanaka int Size = (int) Insn + 1; 52171928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 52271928e68SAkira Hatanaka return MCDisassembler::Success; 52371928e68SAkira Hatanaka } 524