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) : 389bf2b567SAkira Hatanaka MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {} 3971928e68SAkira Hatanaka 409bf2b567SAkira Hatanaka virtual ~MipsDisassemblerBase() {} 419bf2b567SAkira Hatanaka 429bf2b567SAkira Hatanaka const MCRegisterInfo *getRegInfo() const { return RegInfo; } 439bf2b567SAkira Hatanaka 449bf2b567SAkira Hatanaka private: 459bf2b567SAkira Hatanaka const MCRegisterInfo *RegInfo; 469bf2b567SAkira Hatanaka protected: 479bf2b567SAkira Hatanaka bool isBigEndian; 489bf2b567SAkira Hatanaka }; 499bf2b567SAkira Hatanaka 509bf2b567SAkira Hatanaka /// MipsDisassembler - a disasembler class for Mips32. 519bf2b567SAkira Hatanaka class MipsDisassembler : public MipsDisassemblerBase { 529bf2b567SAkira Hatanaka public: 539bf2b567SAkira Hatanaka /// Constructor - Initializes the disassembler. 549bf2b567SAkira Hatanaka /// 559bf2b567SAkira Hatanaka MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 569bf2b567SAkira Hatanaka bool bigEndian) : 579bf2b567SAkira Hatanaka MipsDisassemblerBase(STI, Info, bigEndian) {} 5871928e68SAkira Hatanaka 5971928e68SAkira Hatanaka /// getInstruction - See MCDisassembler. 609bf2b567SAkira Hatanaka virtual DecodeStatus getInstruction(MCInst &instr, 6171928e68SAkira Hatanaka uint64_t &size, 6271928e68SAkira Hatanaka const MemoryObject ®ion, 6371928e68SAkira Hatanaka uint64_t address, 6471928e68SAkira Hatanaka raw_ostream &vStream, 6571928e68SAkira Hatanaka raw_ostream &cStream) const; 6671928e68SAkira Hatanaka }; 6771928e68SAkira Hatanaka 6871928e68SAkira Hatanaka 6971928e68SAkira Hatanaka /// Mips64Disassembler - a disasembler class for Mips64. 709bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase { 7171928e68SAkira Hatanaka public: 7271928e68SAkira Hatanaka /// Constructor - Initializes the disassembler. 7371928e68SAkira Hatanaka /// 749bf2b567SAkira Hatanaka Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 759bf2b567SAkira Hatanaka bool bigEndian) : 769bf2b567SAkira Hatanaka MipsDisassemblerBase(STI, Info, bigEndian) {} 7771928e68SAkira Hatanaka 7871928e68SAkira Hatanaka /// getInstruction - See MCDisassembler. 799bf2b567SAkira Hatanaka virtual DecodeStatus getInstruction(MCInst &instr, 8071928e68SAkira Hatanaka uint64_t &size, 8171928e68SAkira Hatanaka const MemoryObject ®ion, 8271928e68SAkira Hatanaka uint64_t address, 8371928e68SAkira Hatanaka raw_ostream &vStream, 8471928e68SAkira Hatanaka raw_ostream &cStream) const; 8571928e68SAkira Hatanaka }; 8671928e68SAkira Hatanaka 87cb3e98cfSBenjamin Kramer } // end anonymous namespace 88cb3e98cfSBenjamin Kramer 8971928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them. 9071928e68SAkira Hatanaka // Definitions are further down. 9171928e68SAkira Hatanaka static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, 9271928e68SAkira Hatanaka unsigned RegNo, 9371928e68SAkira Hatanaka uint64_t Address, 9471928e68SAkira Hatanaka const void *Decoder); 9571928e68SAkira Hatanaka 96*ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 97*ec8a5490SReed Kotler unsigned RegNo, 98*ec8a5490SReed Kotler uint64_t Address, 99*ec8a5490SReed Kotler const void *Decoder); 100*ec8a5490SReed Kotler 10171928e68SAkira Hatanaka static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, 10271928e68SAkira Hatanaka unsigned RegNo, 10371928e68SAkira Hatanaka uint64_t Address, 10471928e68SAkira Hatanaka const void *Decoder); 10571928e68SAkira Hatanaka 106ecabd1a5SAkira Hatanaka static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst, 107ecabd1a5SAkira Hatanaka unsigned RegNo, 108ecabd1a5SAkira Hatanaka uint64_t Address, 109ecabd1a5SAkira Hatanaka const void *Decoder); 110ecabd1a5SAkira 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 1362a74a87bSJack Carter static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, 1372a74a87bSJack Carter unsigned Insn, 1382a74a87bSJack Carter uint64_t Address, 1392a74a87bSJack Carter const void *Decoder); 1402a74a87bSJack Carter 141ecabd1a5SAkira Hatanaka static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst, 142ecabd1a5SAkira Hatanaka unsigned RegNo, 143ecabd1a5SAkira Hatanaka uint64_t Address, 144ecabd1a5SAkira Hatanaka const void *Decoder); 145ecabd1a5SAkira Hatanaka 14671928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 14771928e68SAkira Hatanaka unsigned Offset, 14871928e68SAkira Hatanaka uint64_t Address, 14971928e68SAkira Hatanaka const void *Decoder); 15071928e68SAkira Hatanaka 15171928e68SAkira Hatanaka static DecodeStatus DecodeBC1(MCInst &Inst, 15271928e68SAkira Hatanaka unsigned Insn, 15371928e68SAkira Hatanaka uint64_t Address, 15471928e68SAkira Hatanaka const void *Decoder); 15571928e68SAkira Hatanaka 15671928e68SAkira Hatanaka 15771928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 15871928e68SAkira Hatanaka unsigned Insn, 15971928e68SAkira Hatanaka uint64_t Address, 16071928e68SAkira Hatanaka const void *Decoder); 16171928e68SAkira Hatanaka 16271928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 16371928e68SAkira Hatanaka unsigned Insn, 16471928e68SAkira Hatanaka uint64_t Address, 16571928e68SAkira Hatanaka const void *Decoder); 16671928e68SAkira Hatanaka 16771928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 16871928e68SAkira Hatanaka uint64_t Address, 16971928e68SAkira Hatanaka const void *Decoder); 17071928e68SAkira Hatanaka 17171928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 17271928e68SAkira Hatanaka unsigned Insn, 17371928e68SAkira Hatanaka uint64_t Address, 17471928e68SAkira Hatanaka const void *Decoder); 17571928e68SAkira Hatanaka 17671928e68SAkira Hatanaka static DecodeStatus DecodeCondCode(MCInst &Inst, 17771928e68SAkira Hatanaka unsigned Insn, 17871928e68SAkira Hatanaka uint64_t Address, 17971928e68SAkira Hatanaka const void *Decoder); 18071928e68SAkira Hatanaka 18171928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 18271928e68SAkira Hatanaka unsigned Insn, 18371928e68SAkira Hatanaka uint64_t Address, 18471928e68SAkira Hatanaka const void *Decoder); 18571928e68SAkira Hatanaka 18671928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 18771928e68SAkira Hatanaka unsigned Insn, 18871928e68SAkira Hatanaka uint64_t Address, 18971928e68SAkira Hatanaka const void *Decoder); 19071928e68SAkira Hatanaka 19171928e68SAkira Hatanaka namespace llvm { 19271928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 19371928e68SAkira Hatanaka TheMips64elTarget; 19471928e68SAkira Hatanaka } 19571928e68SAkira Hatanaka 19671928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler( 19771928e68SAkira Hatanaka const Target &T, 19871928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 1999bf2b567SAkira Hatanaka return new MipsDisassembler(STI, T.createMCRegInfo(""), true); 20071928e68SAkira Hatanaka } 20171928e68SAkira Hatanaka 20271928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler( 20371928e68SAkira Hatanaka const Target &T, 20471928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2059bf2b567SAkira Hatanaka return new MipsDisassembler(STI, T.createMCRegInfo(""), false); 20671928e68SAkira Hatanaka } 20771928e68SAkira Hatanaka 20871928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler( 20971928e68SAkira Hatanaka const Target &T, 21071928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2119bf2b567SAkira Hatanaka return new Mips64Disassembler(STI, T.createMCRegInfo(""), true); 21271928e68SAkira Hatanaka } 21371928e68SAkira Hatanaka 21471928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler( 21571928e68SAkira Hatanaka const Target &T, 21671928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2179bf2b567SAkira Hatanaka return new Mips64Disassembler(STI, T.createMCRegInfo(""), false); 21871928e68SAkira Hatanaka } 21971928e68SAkira Hatanaka 22071928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() { 22171928e68SAkira Hatanaka // Register the disassembler. 22271928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 22371928e68SAkira Hatanaka createMipsDisassembler); 22471928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 22571928e68SAkira Hatanaka createMipselDisassembler); 22671928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64Target, 22771928e68SAkira Hatanaka createMips64Disassembler); 22871928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 22971928e68SAkira Hatanaka createMips64elDisassembler); 23071928e68SAkira Hatanaka } 23171928e68SAkira Hatanaka 23271928e68SAkira Hatanaka 23371928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc" 23471928e68SAkira Hatanaka 23571928e68SAkira Hatanaka /// readInstruction - read four bytes from the MemoryObject 23671928e68SAkira Hatanaka /// and return 32 bit word sorted according to the given endianess 23771928e68SAkira Hatanaka static DecodeStatus readInstruction32(const MemoryObject ®ion, 23871928e68SAkira Hatanaka uint64_t address, 23971928e68SAkira Hatanaka uint64_t &size, 24071928e68SAkira Hatanaka uint32_t &insn, 24171928e68SAkira Hatanaka bool isBigEndian) { 24271928e68SAkira Hatanaka uint8_t Bytes[4]; 24371928e68SAkira Hatanaka 24471928e68SAkira Hatanaka // We want to read exactly 4 Bytes of data. 24571928e68SAkira Hatanaka if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) { 24671928e68SAkira Hatanaka size = 0; 24771928e68SAkira Hatanaka return MCDisassembler::Fail; 24871928e68SAkira Hatanaka } 24971928e68SAkira Hatanaka 25071928e68SAkira Hatanaka if (isBigEndian) { 25171928e68SAkira Hatanaka // Encoded as a big-endian 32-bit word in the stream. 25271928e68SAkira Hatanaka insn = (Bytes[3] << 0) | 25371928e68SAkira Hatanaka (Bytes[2] << 8) | 25471928e68SAkira Hatanaka (Bytes[1] << 16) | 25571928e68SAkira Hatanaka (Bytes[0] << 24); 25671928e68SAkira Hatanaka } 25771928e68SAkira Hatanaka else { 25871928e68SAkira Hatanaka // Encoded as a small-endian 32-bit word in the stream. 25971928e68SAkira Hatanaka insn = (Bytes[0] << 0) | 26071928e68SAkira Hatanaka (Bytes[1] << 8) | 26171928e68SAkira Hatanaka (Bytes[2] << 16) | 26271928e68SAkira Hatanaka (Bytes[3] << 24); 26371928e68SAkira Hatanaka } 26471928e68SAkira Hatanaka 26571928e68SAkira Hatanaka return MCDisassembler::Success; 26671928e68SAkira Hatanaka } 26771928e68SAkira Hatanaka 26871928e68SAkira Hatanaka DecodeStatus 26971928e68SAkira Hatanaka MipsDisassembler::getInstruction(MCInst &instr, 27071928e68SAkira Hatanaka uint64_t &Size, 27171928e68SAkira Hatanaka const MemoryObject &Region, 27271928e68SAkira Hatanaka uint64_t Address, 27371928e68SAkira Hatanaka raw_ostream &vStream, 27471928e68SAkira Hatanaka raw_ostream &cStream) const { 27571928e68SAkira Hatanaka uint32_t Insn; 27671928e68SAkira Hatanaka 27771928e68SAkira Hatanaka DecodeStatus Result = readInstruction32(Region, Address, Size, 27871928e68SAkira Hatanaka Insn, isBigEndian); 27971928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 28071928e68SAkira Hatanaka return MCDisassembler::Fail; 28171928e68SAkira Hatanaka 28271928e68SAkira Hatanaka // Calling the auto-generated decoder function. 283ecaef49fSJim Grosbach Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 284ecaef49fSJim Grosbach this, STI); 28571928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 28671928e68SAkira Hatanaka Size = 4; 28771928e68SAkira Hatanaka return Result; 28871928e68SAkira Hatanaka } 28971928e68SAkira Hatanaka 29071928e68SAkira Hatanaka return MCDisassembler::Fail; 29171928e68SAkira Hatanaka } 29271928e68SAkira Hatanaka 29371928e68SAkira Hatanaka DecodeStatus 29471928e68SAkira Hatanaka Mips64Disassembler::getInstruction(MCInst &instr, 29571928e68SAkira Hatanaka uint64_t &Size, 29671928e68SAkira Hatanaka const MemoryObject &Region, 29771928e68SAkira Hatanaka uint64_t Address, 29871928e68SAkira Hatanaka raw_ostream &vStream, 29971928e68SAkira Hatanaka raw_ostream &cStream) const { 30071928e68SAkira Hatanaka uint32_t Insn; 30171928e68SAkira Hatanaka 30271928e68SAkira Hatanaka DecodeStatus Result = readInstruction32(Region, Address, Size, 30371928e68SAkira Hatanaka Insn, isBigEndian); 30471928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 30571928e68SAkira Hatanaka return MCDisassembler::Fail; 30671928e68SAkira Hatanaka 30771928e68SAkira Hatanaka // Calling the auto-generated decoder function. 308ecaef49fSJim Grosbach Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address, 309ecaef49fSJim Grosbach this, STI); 31071928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 31171928e68SAkira Hatanaka Size = 4; 31271928e68SAkira Hatanaka return Result; 31371928e68SAkira Hatanaka } 31471928e68SAkira Hatanaka // If we fail to decode in Mips64 decoder space we can try in Mips32 315ecaef49fSJim Grosbach Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 316ecaef49fSJim Grosbach this, STI); 31771928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 31871928e68SAkira Hatanaka Size = 4; 31971928e68SAkira Hatanaka return Result; 32071928e68SAkira Hatanaka } 32171928e68SAkira Hatanaka 32271928e68SAkira Hatanaka return MCDisassembler::Fail; 32371928e68SAkira Hatanaka } 32471928e68SAkira Hatanaka 3259bf2b567SAkira Hatanaka static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 3269bf2b567SAkira Hatanaka const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D); 3279bf2b567SAkira Hatanaka return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo); 3289bf2b567SAkira Hatanaka } 3299bf2b567SAkira Hatanaka 330*ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 331*ec8a5490SReed Kotler unsigned RegNo, 332*ec8a5490SReed Kotler uint64_t Address, 333*ec8a5490SReed Kotler const void *Decoder) { 334*ec8a5490SReed Kotler 335*ec8a5490SReed Kotler return MCDisassembler::Fail; 336*ec8a5490SReed Kotler 337*ec8a5490SReed Kotler } 338*ec8a5490SReed Kotler 33971928e68SAkira Hatanaka static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst, 34071928e68SAkira Hatanaka unsigned RegNo, 34171928e68SAkira Hatanaka uint64_t Address, 34271928e68SAkira Hatanaka const void *Decoder) { 34371928e68SAkira Hatanaka 34471928e68SAkira Hatanaka if (RegNo > 31) 34571928e68SAkira Hatanaka return MCDisassembler::Fail; 34671928e68SAkira Hatanaka 3479bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo); 3489bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 34971928e68SAkira Hatanaka return MCDisassembler::Success; 35071928e68SAkira Hatanaka } 35171928e68SAkira Hatanaka 35271928e68SAkira Hatanaka static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst, 35371928e68SAkira Hatanaka unsigned RegNo, 35471928e68SAkira Hatanaka uint64_t Address, 35571928e68SAkira Hatanaka const void *Decoder) { 35671928e68SAkira Hatanaka if (RegNo > 31) 35771928e68SAkira Hatanaka return MCDisassembler::Fail; 3589bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo); 3599bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 36071928e68SAkira Hatanaka return MCDisassembler::Success; 36171928e68SAkira Hatanaka } 36271928e68SAkira Hatanaka 363ecabd1a5SAkira Hatanaka static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst, 364ecabd1a5SAkira Hatanaka unsigned RegNo, 365ecabd1a5SAkira Hatanaka uint64_t Address, 366ecabd1a5SAkira Hatanaka const void *Decoder) { 367ecabd1a5SAkira Hatanaka return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder); 368ecabd1a5SAkira Hatanaka } 369ecabd1a5SAkira Hatanaka 37071928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 37171928e68SAkira Hatanaka unsigned RegNo, 37271928e68SAkira Hatanaka uint64_t Address, 37371928e68SAkira Hatanaka const void *Decoder) { 37471928e68SAkira Hatanaka if (RegNo > 31) 37571928e68SAkira Hatanaka return MCDisassembler::Fail; 37671928e68SAkira Hatanaka 3779bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 3789bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 37971928e68SAkira Hatanaka return MCDisassembler::Success; 38071928e68SAkira Hatanaka } 38171928e68SAkira Hatanaka 38271928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 38371928e68SAkira Hatanaka unsigned RegNo, 38471928e68SAkira Hatanaka uint64_t Address, 38571928e68SAkira Hatanaka const void *Decoder) { 38671928e68SAkira Hatanaka if (RegNo > 31) 38771928e68SAkira Hatanaka return MCDisassembler::Fail; 38871928e68SAkira Hatanaka 3899bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 3909bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 39171928e68SAkira Hatanaka return MCDisassembler::Success; 39271928e68SAkira Hatanaka } 39371928e68SAkira Hatanaka 39471928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 39571928e68SAkira Hatanaka unsigned RegNo, 39671928e68SAkira Hatanaka uint64_t Address, 39771928e68SAkira Hatanaka const void *Decoder) { 39871928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(RegNo)); 39971928e68SAkira Hatanaka return MCDisassembler::Success; 40071928e68SAkira Hatanaka } 40171928e68SAkira Hatanaka 40271928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 40371928e68SAkira Hatanaka unsigned Insn, 40471928e68SAkira Hatanaka uint64_t Address, 40571928e68SAkira Hatanaka const void *Decoder) { 40671928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 407ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 408ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 4099bf2b567SAkira Hatanaka 4109bf2b567SAkira Hatanaka Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg); 4119bf2b567SAkira Hatanaka Base = getReg(Decoder, Mips::CPURegsRegClassID, Base); 41271928e68SAkira Hatanaka 41371928e68SAkira Hatanaka if(Inst.getOpcode() == Mips::SC){ 4149bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 41571928e68SAkira Hatanaka } 41671928e68SAkira Hatanaka 4179bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 4189bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 41971928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 42071928e68SAkira Hatanaka 42171928e68SAkira Hatanaka return MCDisassembler::Success; 42271928e68SAkira Hatanaka } 42371928e68SAkira Hatanaka 42471928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, 42571928e68SAkira Hatanaka unsigned Insn, 42671928e68SAkira Hatanaka uint64_t Address, 42771928e68SAkira Hatanaka const void *Decoder) { 42871928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 429ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 430ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 43171928e68SAkira Hatanaka 4329bf2b567SAkira Hatanaka Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 4339bf2b567SAkira Hatanaka Base = getReg(Decoder, Mips::CPURegsRegClassID, Base); 4349bf2b567SAkira Hatanaka 4359bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 4369bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 43771928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 43871928e68SAkira Hatanaka 43971928e68SAkira Hatanaka return MCDisassembler::Success; 44071928e68SAkira Hatanaka } 44171928e68SAkira Hatanaka 44271928e68SAkira Hatanaka 44371928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 44471928e68SAkira Hatanaka unsigned RegNo, 44571928e68SAkira Hatanaka uint64_t Address, 44671928e68SAkira Hatanaka const void *Decoder) { 44771928e68SAkira Hatanaka // Currently only hardware register 29 is supported. 44871928e68SAkira Hatanaka if (RegNo != 29) 44971928e68SAkira Hatanaka return MCDisassembler::Fail; 45071928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); 45171928e68SAkira Hatanaka return MCDisassembler::Success; 45271928e68SAkira Hatanaka } 45371928e68SAkira Hatanaka 45471928e68SAkira Hatanaka static DecodeStatus DecodeCondCode(MCInst &Inst, 45571928e68SAkira Hatanaka unsigned Insn, 45671928e68SAkira Hatanaka uint64_t Address, 45771928e68SAkira Hatanaka const void *Decoder) { 45871928e68SAkira Hatanaka int CondCode = Insn & 0xf; 45971928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(CondCode)); 46071928e68SAkira Hatanaka return MCDisassembler::Success; 46171928e68SAkira Hatanaka } 46271928e68SAkira Hatanaka 46371928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 46471928e68SAkira Hatanaka unsigned RegNo, 46571928e68SAkira Hatanaka uint64_t Address, 46671928e68SAkira Hatanaka const void *Decoder) { 4679bf2b567SAkira Hatanaka if (RegNo > 30 || RegNo %2) 46871928e68SAkira Hatanaka return MCDisassembler::Fail; 46971928e68SAkira Hatanaka 4709bf2b567SAkira Hatanaka ; 4719bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 4729bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 47371928e68SAkira Hatanaka return MCDisassembler::Success; 47471928e68SAkira Hatanaka } 47571928e68SAkira Hatanaka 4762a74a87bSJack Carter static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst, 4772a74a87bSJack Carter unsigned RegNo, 4782a74a87bSJack Carter uint64_t Address, 4792a74a87bSJack Carter const void *Decoder) { 4802a74a87bSJack Carter //Currently only hardware register 29 is supported 4812a74a87bSJack Carter if (RegNo != 29) 4822a74a87bSJack Carter return MCDisassembler::Fail; 4832a74a87bSJack Carter Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64)); 4842a74a87bSJack Carter return MCDisassembler::Success; 4852a74a87bSJack Carter } 4862a74a87bSJack Carter 487ecabd1a5SAkira Hatanaka static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst, 488ecabd1a5SAkira Hatanaka unsigned RegNo, 489ecabd1a5SAkira Hatanaka uint64_t Address, 490ecabd1a5SAkira Hatanaka const void *Decoder) { 491ecabd1a5SAkira Hatanaka if (RegNo >= 4) 492ecabd1a5SAkira Hatanaka return MCDisassembler::Fail; 493ecabd1a5SAkira Hatanaka 494ecabd1a5SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::ACRegsRegClassID, RegNo); 495ecabd1a5SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 496ecabd1a5SAkira Hatanaka return MCDisassembler::Success; 497ecabd1a5SAkira Hatanaka } 498ecabd1a5SAkira Hatanaka 49971928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 50071928e68SAkira Hatanaka unsigned Offset, 50171928e68SAkira Hatanaka uint64_t Address, 50271928e68SAkira Hatanaka const void *Decoder) { 50371928e68SAkira Hatanaka unsigned BranchOffset = Offset & 0xffff; 50471928e68SAkira Hatanaka BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 50571928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 50671928e68SAkira Hatanaka return MCDisassembler::Success; 50771928e68SAkira Hatanaka } 50871928e68SAkira Hatanaka 50971928e68SAkira Hatanaka static DecodeStatus DecodeBC1(MCInst &Inst, 51071928e68SAkira Hatanaka unsigned Insn, 51171928e68SAkira Hatanaka uint64_t Address, 51271928e68SAkira Hatanaka const void *Decoder) { 51371928e68SAkira Hatanaka unsigned BranchOffset = Insn & 0xffff; 51471928e68SAkira Hatanaka BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 51571928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 51671928e68SAkira Hatanaka return MCDisassembler::Success; 51771928e68SAkira Hatanaka } 51871928e68SAkira Hatanaka 51971928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 52071928e68SAkira Hatanaka unsigned Insn, 52171928e68SAkira Hatanaka uint64_t Address, 52271928e68SAkira Hatanaka const void *Decoder) { 52371928e68SAkira Hatanaka 524ecaef49fSJim Grosbach unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 52571928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 52671928e68SAkira Hatanaka return MCDisassembler::Success; 52771928e68SAkira Hatanaka } 52871928e68SAkira Hatanaka 52971928e68SAkira Hatanaka 53071928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 53171928e68SAkira Hatanaka unsigned Insn, 53271928e68SAkira Hatanaka uint64_t Address, 53371928e68SAkira Hatanaka const void *Decoder) { 53471928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); 53571928e68SAkira Hatanaka return MCDisassembler::Success; 53671928e68SAkira Hatanaka } 53771928e68SAkira Hatanaka 53871928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 53971928e68SAkira Hatanaka unsigned Insn, 54071928e68SAkira Hatanaka uint64_t Address, 54171928e68SAkira Hatanaka const void *Decoder) { 54271928e68SAkira Hatanaka // First we need to grab the pos(lsb) from MCInst. 54371928e68SAkira Hatanaka int Pos = Inst.getOperand(2).getImm(); 54471928e68SAkira Hatanaka int Size = (int) Insn - Pos + 1; 54571928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 54671928e68SAkira Hatanaka return MCDisassembler::Success; 54771928e68SAkira Hatanaka } 54871928e68SAkira Hatanaka 54971928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 55071928e68SAkira Hatanaka unsigned Insn, 55171928e68SAkira Hatanaka uint64_t Address, 55271928e68SAkira Hatanaka const void *Decoder) { 55371928e68SAkira Hatanaka int Size = (int) Insn + 1; 55471928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 55571928e68SAkira Hatanaka return MCDisassembler::Success; 55671928e68SAkira Hatanaka } 557