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) : 389bfa2e2eSAkira Hatanaka MCDisassembler(STI), RegInfo(Info), 399bfa2e2eSAkira 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 459bfa2e2eSAkira Hatanaka bool isN64() const { return IsN64; } 469bfa2e2eSAkira Hatanaka 479bf2b567SAkira Hatanaka private: 48dcfd5b52SBenjamin Kramer OwningPtr<const MCRegisterInfo> RegInfo; 499bfa2e2eSAkira 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 { 56dde3d582SVladimir Medic bool IsMicroMips; 579bf2b567SAkira Hatanaka public: 589bf2b567SAkira Hatanaka /// Constructor - Initializes the disassembler. 599bf2b567SAkira Hatanaka /// 609bf2b567SAkira Hatanaka MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 619bf2b567SAkira Hatanaka bool bigEndian) : 62dde3d582SVladimir Medic MipsDisassemblerBase(STI, Info, bigEndian) { 63dde3d582SVladimir Medic IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips; 64dde3d582SVladimir Medic } 6571928e68SAkira Hatanaka 6671928e68SAkira Hatanaka /// getInstruction - See MCDisassembler. 679bf2b567SAkira Hatanaka virtual DecodeStatus getInstruction(MCInst &instr, 6871928e68SAkira Hatanaka uint64_t &size, 6971928e68SAkira Hatanaka const MemoryObject ®ion, 7071928e68SAkira Hatanaka uint64_t address, 7171928e68SAkira Hatanaka raw_ostream &vStream, 7271928e68SAkira Hatanaka raw_ostream &cStream) const; 7371928e68SAkira Hatanaka }; 7471928e68SAkira Hatanaka 7571928e68SAkira Hatanaka 7671928e68SAkira Hatanaka /// Mips64Disassembler - a disasembler class for Mips64. 779bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase { 7871928e68SAkira Hatanaka public: 7971928e68SAkira Hatanaka /// Constructor - Initializes the disassembler. 8071928e68SAkira Hatanaka /// 819bf2b567SAkira Hatanaka Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info, 829bf2b567SAkira Hatanaka bool bigEndian) : 839bf2b567SAkira Hatanaka MipsDisassemblerBase(STI, Info, bigEndian) {} 8471928e68SAkira Hatanaka 8571928e68SAkira Hatanaka /// getInstruction - See MCDisassembler. 869bf2b567SAkira Hatanaka virtual DecodeStatus getInstruction(MCInst &instr, 8771928e68SAkira Hatanaka uint64_t &size, 8871928e68SAkira Hatanaka const MemoryObject ®ion, 8971928e68SAkira Hatanaka uint64_t address, 9071928e68SAkira Hatanaka raw_ostream &vStream, 9171928e68SAkira Hatanaka raw_ostream &cStream) const; 9271928e68SAkira Hatanaka }; 9371928e68SAkira Hatanaka 94cb3e98cfSBenjamin Kramer } // end anonymous namespace 95cb3e98cfSBenjamin Kramer 9671928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them. 9771928e68SAkira Hatanaka // Definitions are further down. 9813e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 9971928e68SAkira Hatanaka unsigned RegNo, 10071928e68SAkira Hatanaka uint64_t Address, 10171928e68SAkira Hatanaka const void *Decoder); 10271928e68SAkira Hatanaka 103ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 104ec8a5490SReed Kotler unsigned RegNo, 105ec8a5490SReed Kotler uint64_t Address, 106ec8a5490SReed Kotler const void *Decoder); 107ec8a5490SReed Kotler 10813e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 10971928e68SAkira Hatanaka unsigned RegNo, 11071928e68SAkira Hatanaka uint64_t Address, 11171928e68SAkira Hatanaka const void *Decoder); 11271928e68SAkira Hatanaka 1139bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 1149bfa2e2eSAkira Hatanaka unsigned Insn, 1159bfa2e2eSAkira Hatanaka uint64_t Address, 1169bfa2e2eSAkira Hatanaka const void *Decoder); 1179bfa2e2eSAkira Hatanaka 118654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 119ecabd1a5SAkira Hatanaka unsigned RegNo, 120ecabd1a5SAkira Hatanaka uint64_t Address, 121ecabd1a5SAkira Hatanaka const void *Decoder); 122ecabd1a5SAkira Hatanaka 12371928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 12471928e68SAkira Hatanaka unsigned RegNo, 12571928e68SAkira Hatanaka uint64_t Address, 12671928e68SAkira Hatanaka const void *Decoder); 12771928e68SAkira Hatanaka 12871928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 12971928e68SAkira Hatanaka unsigned RegNo, 13071928e68SAkira Hatanaka uint64_t Address, 13171928e68SAkira Hatanaka const void *Decoder); 13271928e68SAkira Hatanaka 13314e31a2fSAkira Hatanaka static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst, 13414e31a2fSAkira Hatanaka unsigned RegNo, 13514e31a2fSAkira Hatanaka uint64_t Address, 13614e31a2fSAkira Hatanaka const void *Decoder); 13714e31a2fSAkira Hatanaka 13871928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 13971928e68SAkira Hatanaka unsigned RegNo, 14071928e68SAkira Hatanaka uint64_t Address, 14171928e68SAkira Hatanaka const void *Decoder); 14271928e68SAkira Hatanaka 1431fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 1441fb1b8b8SAkira Hatanaka unsigned RegNo, 1451fb1b8b8SAkira Hatanaka uint64_t Address, 1461fb1b8b8SAkira Hatanaka const void *Decoder); 1471fb1b8b8SAkira Hatanaka 14871928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 14971928e68SAkira Hatanaka unsigned Insn, 15071928e68SAkira Hatanaka uint64_t Address, 15171928e68SAkira Hatanaka const void *Decoder); 15271928e68SAkira Hatanaka 15371928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 15471928e68SAkira Hatanaka unsigned RegNo, 15571928e68SAkira Hatanaka uint64_t Address, 15671928e68SAkira Hatanaka const void *Decoder); 15771928e68SAkira Hatanaka 15800fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 159ecabd1a5SAkira Hatanaka unsigned RegNo, 160ecabd1a5SAkira Hatanaka uint64_t Address, 161ecabd1a5SAkira Hatanaka const void *Decoder); 162ecabd1a5SAkira Hatanaka 1638002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 16459bfaf77SAkira Hatanaka unsigned RegNo, 16559bfaf77SAkira Hatanaka uint64_t Address, 16659bfaf77SAkira Hatanaka const void *Decoder); 16759bfaf77SAkira Hatanaka 1688002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 16959bfaf77SAkira Hatanaka unsigned RegNo, 17059bfaf77SAkira Hatanaka uint64_t Address, 17159bfaf77SAkira Hatanaka const void *Decoder); 17259bfaf77SAkira Hatanaka 1733eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, 1743eb663b0SJack Carter unsigned RegNo, 1753eb663b0SJack Carter uint64_t Address, 1763eb663b0SJack Carter const void *Decoder); 1773eb663b0SJack Carter 1785dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, 1795dc8ac92SJack Carter unsigned RegNo, 1805dc8ac92SJack Carter uint64_t Address, 1815dc8ac92SJack Carter const void *Decoder); 1825dc8ac92SJack Carter 1835dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, 1845dc8ac92SJack Carter unsigned RegNo, 1855dc8ac92SJack Carter uint64_t Address, 1865dc8ac92SJack Carter const void *Decoder); 1875dc8ac92SJack Carter 1885dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, 1895dc8ac92SJack Carter unsigned RegNo, 1905dc8ac92SJack Carter uint64_t Address, 1915dc8ac92SJack Carter const void *Decoder); 1925dc8ac92SJack Carter 193a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, 194a591fdc6SMatheus Almeida unsigned RegNo, 195a591fdc6SMatheus Almeida uint64_t Address, 196a591fdc6SMatheus Almeida const void *Decoder); 197a591fdc6SMatheus Almeida 19871928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 19971928e68SAkira Hatanaka unsigned Offset, 20071928e68SAkira Hatanaka uint64_t Address, 20171928e68SAkira Hatanaka const void *Decoder); 20271928e68SAkira Hatanaka 20371928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 20471928e68SAkira Hatanaka unsigned Insn, 20571928e68SAkira Hatanaka uint64_t Address, 20671928e68SAkira Hatanaka const void *Decoder); 20771928e68SAkira Hatanaka 2088a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is 2098a80aa76SZoran Jovanovic // shifted left by 1 bit. 2108a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 2118a80aa76SZoran Jovanovic unsigned Offset, 2128a80aa76SZoran Jovanovic uint64_t Address, 2138a80aa76SZoran Jovanovic const void *Decoder); 2148a80aa76SZoran Jovanovic 215507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is 216507e084aSZoran Jovanovic // shifted left by 1 bit. 217507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 218507e084aSZoran Jovanovic unsigned Insn, 219507e084aSZoran Jovanovic uint64_t Address, 220507e084aSZoran Jovanovic const void *Decoder); 221507e084aSZoran Jovanovic 22271928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 22371928e68SAkira Hatanaka unsigned Insn, 22471928e68SAkira Hatanaka uint64_t Address, 22571928e68SAkira Hatanaka const void *Decoder); 22671928e68SAkira Hatanaka 227fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 228fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder); 229fe0bf9f6SMatheus Almeida 230dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 231dde3d582SVladimir Medic unsigned Insn, 232dde3d582SVladimir Medic uint64_t Address, 233dde3d582SVladimir Medic const void *Decoder); 234dde3d582SVladimir Medic 235dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 236dde3d582SVladimir Medic unsigned Insn, 237dde3d582SVladimir Medic uint64_t Address, 238dde3d582SVladimir Medic const void *Decoder); 239dde3d582SVladimir Medic 24071928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 24171928e68SAkira Hatanaka uint64_t Address, 24271928e68SAkira Hatanaka const void *Decoder); 24371928e68SAkira Hatanaka 24471928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 24571928e68SAkira Hatanaka unsigned Insn, 24671928e68SAkira Hatanaka uint64_t Address, 24771928e68SAkira Hatanaka const void *Decoder); 24871928e68SAkira Hatanaka 249779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which 250779c5937SMatheus Almeida // is off by one. 251779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst, 252779c5937SMatheus Almeida unsigned Insn, 253779c5937SMatheus Almeida uint64_t Address, 254779c5937SMatheus Almeida const void *Decoder); 255779c5937SMatheus Almeida 25671928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 25771928e68SAkira Hatanaka unsigned Insn, 25871928e68SAkira Hatanaka uint64_t Address, 25971928e68SAkira Hatanaka const void *Decoder); 26071928e68SAkira Hatanaka 26171928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 26271928e68SAkira Hatanaka unsigned Insn, 26371928e68SAkira Hatanaka uint64_t Address, 26471928e68SAkira Hatanaka const void *Decoder); 26571928e68SAkira Hatanaka 26671928e68SAkira Hatanaka namespace llvm { 26771928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 26871928e68SAkira Hatanaka TheMips64elTarget; 26971928e68SAkira Hatanaka } 27071928e68SAkira Hatanaka 27171928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler( 27271928e68SAkira Hatanaka const Target &T, 27371928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2749bf2b567SAkira Hatanaka return new MipsDisassembler(STI, T.createMCRegInfo(""), true); 27571928e68SAkira Hatanaka } 27671928e68SAkira Hatanaka 27771928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler( 27871928e68SAkira Hatanaka const Target &T, 27971928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2809bf2b567SAkira Hatanaka return new MipsDisassembler(STI, T.createMCRegInfo(""), false); 28171928e68SAkira Hatanaka } 28271928e68SAkira Hatanaka 28371928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler( 28471928e68SAkira Hatanaka const Target &T, 28571928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2869bf2b567SAkira Hatanaka return new Mips64Disassembler(STI, T.createMCRegInfo(""), true); 28771928e68SAkira Hatanaka } 28871928e68SAkira Hatanaka 28971928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler( 29071928e68SAkira Hatanaka const Target &T, 29171928e68SAkira Hatanaka const MCSubtargetInfo &STI) { 2929bf2b567SAkira Hatanaka return new Mips64Disassembler(STI, T.createMCRegInfo(""), false); 29371928e68SAkira Hatanaka } 29471928e68SAkira Hatanaka 29571928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() { 29671928e68SAkira Hatanaka // Register the disassembler. 29771928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 29871928e68SAkira Hatanaka createMipsDisassembler); 29971928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 30071928e68SAkira Hatanaka createMipselDisassembler); 30171928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64Target, 30271928e68SAkira Hatanaka createMips64Disassembler); 30371928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 30471928e68SAkira Hatanaka createMips64elDisassembler); 30571928e68SAkira Hatanaka } 30671928e68SAkira Hatanaka 30771928e68SAkira Hatanaka 30871928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc" 30971928e68SAkira Hatanaka 31071928e68SAkira Hatanaka /// readInstruction - read four bytes from the MemoryObject 31171928e68SAkira Hatanaka /// and return 32 bit word sorted according to the given endianess 31271928e68SAkira Hatanaka static DecodeStatus readInstruction32(const MemoryObject ®ion, 31371928e68SAkira Hatanaka uint64_t address, 31471928e68SAkira Hatanaka uint64_t &size, 31571928e68SAkira Hatanaka uint32_t &insn, 316dde3d582SVladimir Medic bool isBigEndian, 317dde3d582SVladimir Medic bool IsMicroMips) { 31871928e68SAkira Hatanaka uint8_t Bytes[4]; 31971928e68SAkira Hatanaka 32071928e68SAkira Hatanaka // We want to read exactly 4 Bytes of data. 321534d3a46SBenjamin Kramer if (region.readBytes(address, 4, Bytes) == -1) { 32271928e68SAkira Hatanaka size = 0; 32371928e68SAkira Hatanaka return MCDisassembler::Fail; 32471928e68SAkira Hatanaka } 32571928e68SAkira Hatanaka 32671928e68SAkira Hatanaka if (isBigEndian) { 32771928e68SAkira Hatanaka // Encoded as a big-endian 32-bit word in the stream. 32871928e68SAkira Hatanaka insn = (Bytes[3] << 0) | 32971928e68SAkira Hatanaka (Bytes[2] << 8) | 33071928e68SAkira Hatanaka (Bytes[1] << 16) | 33171928e68SAkira Hatanaka (Bytes[0] << 24); 33271928e68SAkira Hatanaka } 33371928e68SAkira Hatanaka else { 33471928e68SAkira Hatanaka // Encoded as a small-endian 32-bit word in the stream. 335dde3d582SVladimir Medic // Little-endian byte ordering: 336dde3d582SVladimir Medic // mips32r2: 4 | 3 | 2 | 1 337dde3d582SVladimir Medic // microMIPS: 2 | 1 | 4 | 3 338dde3d582SVladimir Medic if (IsMicroMips) { 339dde3d582SVladimir Medic insn = (Bytes[2] << 0) | 340dde3d582SVladimir Medic (Bytes[3] << 8) | 341dde3d582SVladimir Medic (Bytes[0] << 16) | 342dde3d582SVladimir Medic (Bytes[1] << 24); 343dde3d582SVladimir Medic } else { 34471928e68SAkira Hatanaka insn = (Bytes[0] << 0) | 34571928e68SAkira Hatanaka (Bytes[1] << 8) | 34671928e68SAkira Hatanaka (Bytes[2] << 16) | 34771928e68SAkira Hatanaka (Bytes[3] << 24); 34871928e68SAkira Hatanaka } 349dde3d582SVladimir Medic } 35071928e68SAkira Hatanaka 35171928e68SAkira Hatanaka return MCDisassembler::Success; 35271928e68SAkira Hatanaka } 35371928e68SAkira Hatanaka 35471928e68SAkira Hatanaka DecodeStatus 35571928e68SAkira Hatanaka MipsDisassembler::getInstruction(MCInst &instr, 35671928e68SAkira Hatanaka uint64_t &Size, 35771928e68SAkira Hatanaka const MemoryObject &Region, 35871928e68SAkira Hatanaka uint64_t Address, 35971928e68SAkira Hatanaka raw_ostream &vStream, 36071928e68SAkira Hatanaka raw_ostream &cStream) const { 36171928e68SAkira Hatanaka uint32_t Insn; 36271928e68SAkira Hatanaka 36371928e68SAkira Hatanaka DecodeStatus Result = readInstruction32(Region, Address, Size, 364dde3d582SVladimir Medic Insn, isBigEndian, IsMicroMips); 36571928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 36671928e68SAkira Hatanaka return MCDisassembler::Fail; 36771928e68SAkira Hatanaka 368dde3d582SVladimir Medic if (IsMicroMips) { 369dde3d582SVladimir Medic // Calling the auto-generated decoder function. 370dde3d582SVladimir Medic Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address, 371dde3d582SVladimir Medic this, STI); 372dde3d582SVladimir Medic if (Result != MCDisassembler::Fail) { 373dde3d582SVladimir Medic Size = 4; 374dde3d582SVladimir Medic return Result; 375dde3d582SVladimir Medic } 376dde3d582SVladimir Medic return MCDisassembler::Fail; 377dde3d582SVladimir Medic } 378dde3d582SVladimir Medic 37971928e68SAkira Hatanaka // Calling the auto-generated decoder function. 380ecaef49fSJim Grosbach Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 381ecaef49fSJim Grosbach this, STI); 38271928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 38371928e68SAkira Hatanaka Size = 4; 38471928e68SAkira Hatanaka return Result; 38571928e68SAkira Hatanaka } 38671928e68SAkira Hatanaka 38771928e68SAkira Hatanaka return MCDisassembler::Fail; 38871928e68SAkira Hatanaka } 38971928e68SAkira Hatanaka 39071928e68SAkira Hatanaka DecodeStatus 39171928e68SAkira Hatanaka Mips64Disassembler::getInstruction(MCInst &instr, 39271928e68SAkira Hatanaka uint64_t &Size, 39371928e68SAkira Hatanaka const MemoryObject &Region, 39471928e68SAkira Hatanaka uint64_t Address, 39571928e68SAkira Hatanaka raw_ostream &vStream, 39671928e68SAkira Hatanaka raw_ostream &cStream) const { 39771928e68SAkira Hatanaka uint32_t Insn; 39871928e68SAkira Hatanaka 39971928e68SAkira Hatanaka DecodeStatus Result = readInstruction32(Region, Address, Size, 400dde3d582SVladimir Medic Insn, isBigEndian, false); 40171928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 40271928e68SAkira Hatanaka return MCDisassembler::Fail; 40371928e68SAkira Hatanaka 40471928e68SAkira Hatanaka // Calling the auto-generated decoder function. 405ecaef49fSJim Grosbach Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address, 406ecaef49fSJim Grosbach this, STI); 40771928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 40871928e68SAkira Hatanaka Size = 4; 40971928e68SAkira Hatanaka return Result; 41071928e68SAkira Hatanaka } 41171928e68SAkira Hatanaka // If we fail to decode in Mips64 decoder space we can try in Mips32 412ecaef49fSJim Grosbach Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address, 413ecaef49fSJim Grosbach this, STI); 41471928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 41571928e68SAkira Hatanaka Size = 4; 41671928e68SAkira Hatanaka return Result; 41771928e68SAkira Hatanaka } 41871928e68SAkira Hatanaka 41971928e68SAkira Hatanaka return MCDisassembler::Fail; 42071928e68SAkira Hatanaka } 42171928e68SAkira Hatanaka 4229bf2b567SAkira Hatanaka static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 4239bf2b567SAkira Hatanaka const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D); 4249bf2b567SAkira Hatanaka return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo); 4259bf2b567SAkira Hatanaka } 4269bf2b567SAkira Hatanaka 427ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 428ec8a5490SReed Kotler unsigned RegNo, 429ec8a5490SReed Kotler uint64_t Address, 430ec8a5490SReed Kotler const void *Decoder) { 431ec8a5490SReed Kotler 432ec8a5490SReed Kotler return MCDisassembler::Fail; 433ec8a5490SReed Kotler 434ec8a5490SReed Kotler } 435ec8a5490SReed Kotler 43613e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 43771928e68SAkira Hatanaka unsigned RegNo, 43871928e68SAkira Hatanaka uint64_t Address, 43971928e68SAkira Hatanaka const void *Decoder) { 44071928e68SAkira Hatanaka 44171928e68SAkira Hatanaka if (RegNo > 31) 44271928e68SAkira Hatanaka return MCDisassembler::Fail; 44371928e68SAkira Hatanaka 44413e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); 4459bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 44671928e68SAkira Hatanaka return MCDisassembler::Success; 44771928e68SAkira Hatanaka } 44871928e68SAkira Hatanaka 44913e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 45071928e68SAkira Hatanaka unsigned RegNo, 45171928e68SAkira Hatanaka uint64_t Address, 45271928e68SAkira Hatanaka const void *Decoder) { 45371928e68SAkira Hatanaka if (RegNo > 31) 45471928e68SAkira Hatanaka return MCDisassembler::Fail; 45513e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); 4569bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 45771928e68SAkira Hatanaka return MCDisassembler::Success; 45871928e68SAkira Hatanaka } 45971928e68SAkira Hatanaka 4609bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 4619bfa2e2eSAkira Hatanaka unsigned RegNo, 4629bfa2e2eSAkira Hatanaka uint64_t Address, 4639bfa2e2eSAkira Hatanaka const void *Decoder) { 4649bfa2e2eSAkira Hatanaka if (static_cast<const MipsDisassembler *>(Decoder)->isN64()) 4659bfa2e2eSAkira Hatanaka return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); 4669bfa2e2eSAkira Hatanaka 4679bfa2e2eSAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 4689bfa2e2eSAkira Hatanaka } 4699bfa2e2eSAkira Hatanaka 470654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 471ecabd1a5SAkira Hatanaka unsigned RegNo, 472ecabd1a5SAkira Hatanaka uint64_t Address, 473ecabd1a5SAkira Hatanaka const void *Decoder) { 47413e6ccf3SAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 475ecabd1a5SAkira Hatanaka } 476ecabd1a5SAkira Hatanaka 47771928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 47871928e68SAkira Hatanaka unsigned RegNo, 47971928e68SAkira Hatanaka uint64_t Address, 48071928e68SAkira Hatanaka const void *Decoder) { 48171928e68SAkira Hatanaka if (RegNo > 31) 48271928e68SAkira Hatanaka return MCDisassembler::Fail; 48371928e68SAkira Hatanaka 4849bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 4859bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 48671928e68SAkira Hatanaka return MCDisassembler::Success; 48771928e68SAkira Hatanaka } 48871928e68SAkira Hatanaka 48971928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 49071928e68SAkira Hatanaka unsigned RegNo, 49171928e68SAkira Hatanaka uint64_t Address, 49271928e68SAkira Hatanaka const void *Decoder) { 49371928e68SAkira Hatanaka if (RegNo > 31) 49471928e68SAkira Hatanaka return MCDisassembler::Fail; 49571928e68SAkira Hatanaka 4969bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 4979bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 49871928e68SAkira Hatanaka return MCDisassembler::Success; 49971928e68SAkira Hatanaka } 50071928e68SAkira Hatanaka 50114e31a2fSAkira Hatanaka static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst, 50214e31a2fSAkira Hatanaka unsigned RegNo, 50314e31a2fSAkira Hatanaka uint64_t Address, 50414e31a2fSAkira Hatanaka const void *Decoder) { 50514e31a2fSAkira Hatanaka if (RegNo > 31) 50614e31a2fSAkira Hatanaka return MCDisassembler::Fail; 50714e31a2fSAkira Hatanaka 50814e31a2fSAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo); 50914e31a2fSAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 51014e31a2fSAkira Hatanaka return MCDisassembler::Success; 51114e31a2fSAkira Hatanaka } 51214e31a2fSAkira Hatanaka 51371928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 51471928e68SAkira Hatanaka unsigned RegNo, 51571928e68SAkira Hatanaka uint64_t Address, 51671928e68SAkira Hatanaka const void *Decoder) { 517253777fdSChad Rosier if (RegNo > 31) 518253777fdSChad Rosier return MCDisassembler::Fail; 519253777fdSChad Rosier unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); 520253777fdSChad Rosier Inst.addOperand(MCOperand::CreateReg(Reg)); 52171928e68SAkira Hatanaka return MCDisassembler::Success; 52271928e68SAkira Hatanaka } 52371928e68SAkira Hatanaka 5241fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 5251fb1b8b8SAkira Hatanaka unsigned RegNo, 5261fb1b8b8SAkira Hatanaka uint64_t Address, 5271fb1b8b8SAkira Hatanaka const void *Decoder) { 5281fb1b8b8SAkira Hatanaka if (RegNo > 7) 5291fb1b8b8SAkira Hatanaka return MCDisassembler::Fail; 5301fb1b8b8SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); 5311fb1b8b8SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 5321fb1b8b8SAkira Hatanaka return MCDisassembler::Success; 5331fb1b8b8SAkira Hatanaka } 5341fb1b8b8SAkira Hatanaka 53571928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 53671928e68SAkira Hatanaka unsigned Insn, 53771928e68SAkira Hatanaka uint64_t Address, 53871928e68SAkira Hatanaka const void *Decoder) { 53971928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 540ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 541ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 5429bf2b567SAkira Hatanaka 54313e6ccf3SAkira Hatanaka Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 54413e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 54571928e68SAkira Hatanaka 54671928e68SAkira Hatanaka if(Inst.getOpcode() == Mips::SC){ 5479bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 54871928e68SAkira Hatanaka } 54971928e68SAkira Hatanaka 5509bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 5519bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 55271928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 55371928e68SAkira Hatanaka 55471928e68SAkira Hatanaka return MCDisassembler::Success; 55571928e68SAkira Hatanaka } 55671928e68SAkira Hatanaka 557fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 558fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder) { 559fe0bf9f6SMatheus Almeida int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10)); 560fe0bf9f6SMatheus Almeida unsigned Reg = fieldFromInstruction(Insn, 6, 5); 561fe0bf9f6SMatheus Almeida unsigned Base = fieldFromInstruction(Insn, 11, 5); 562fe0bf9f6SMatheus Almeida 563fe0bf9f6SMatheus Almeida Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg); 564fe0bf9f6SMatheus Almeida Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 565fe0bf9f6SMatheus Almeida 566fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Reg)); 567fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Base)); 5686b59c449SMatheus Almeida 5696b59c449SMatheus Almeida // The immediate field of an LD/ST instruction is scaled which means it must 5706b59c449SMatheus Almeida // be multiplied (when decoding) by the size (in bytes) of the instructions' 5716b59c449SMatheus Almeida // data format. 5726b59c449SMatheus Almeida // .b - 1 byte 5736b59c449SMatheus Almeida // .h - 2 bytes 5746b59c449SMatheus Almeida // .w - 4 bytes 5756b59c449SMatheus Almeida // .d - 8 bytes 5766b59c449SMatheus Almeida switch(Inst.getOpcode()) 5776b59c449SMatheus Almeida { 5786b59c449SMatheus Almeida default: 5796b59c449SMatheus Almeida assert (0 && "Unexpected instruction"); 5806b59c449SMatheus Almeida return MCDisassembler::Fail; 5816b59c449SMatheus Almeida break; 5826b59c449SMatheus Almeida case Mips::LD_B: 5836b59c449SMatheus Almeida case Mips::ST_B: 584fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateImm(Offset)); 5856b59c449SMatheus Almeida break; 5866b59c449SMatheus Almeida case Mips::LD_H: 5876b59c449SMatheus Almeida case Mips::ST_H: 5886b59c449SMatheus Almeida Inst.addOperand(MCOperand::CreateImm(Offset << 1)); 5896b59c449SMatheus Almeida break; 5906b59c449SMatheus Almeida case Mips::LD_W: 5916b59c449SMatheus Almeida case Mips::ST_W: 5926b59c449SMatheus Almeida Inst.addOperand(MCOperand::CreateImm(Offset << 2)); 5936b59c449SMatheus Almeida break; 5946b59c449SMatheus Almeida case Mips::LD_D: 5956b59c449SMatheus Almeida case Mips::ST_D: 5966b59c449SMatheus Almeida Inst.addOperand(MCOperand::CreateImm(Offset << 3)); 5976b59c449SMatheus Almeida break; 5986b59c449SMatheus Almeida } 599fe0bf9f6SMatheus Almeida 600fe0bf9f6SMatheus Almeida return MCDisassembler::Success; 601fe0bf9f6SMatheus Almeida } 602fe0bf9f6SMatheus Almeida 603dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 604dde3d582SVladimir Medic unsigned Insn, 605dde3d582SVladimir Medic uint64_t Address, 606dde3d582SVladimir Medic const void *Decoder) { 607dde3d582SVladimir Medic int Offset = SignExtend32<12>(Insn & 0x0fff); 608dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 609dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 610dde3d582SVladimir Medic 611dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 612dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 613dde3d582SVladimir Medic 614*285cc289SZoran Jovanovic if (Inst.getOpcode() == Mips::SC_MM) 615*285cc289SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Reg)); 616*285cc289SZoran Jovanovic 617dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Reg)); 618dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Base)); 619dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Offset)); 620dde3d582SVladimir Medic 621dde3d582SVladimir Medic return MCDisassembler::Success; 622dde3d582SVladimir Medic } 623dde3d582SVladimir Medic 624dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 625dde3d582SVladimir Medic unsigned Insn, 626dde3d582SVladimir Medic uint64_t Address, 627dde3d582SVladimir Medic const void *Decoder) { 628dde3d582SVladimir Medic int Offset = SignExtend32<16>(Insn & 0xffff); 629dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 630dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 631dde3d582SVladimir Medic 632dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 633dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 634dde3d582SVladimir Medic 635dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Reg)); 636dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Base)); 637dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Offset)); 638dde3d582SVladimir Medic 639dde3d582SVladimir Medic return MCDisassembler::Success; 640dde3d582SVladimir Medic } 641dde3d582SVladimir Medic 64271928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, 64371928e68SAkira Hatanaka unsigned Insn, 64471928e68SAkira Hatanaka uint64_t Address, 64571928e68SAkira Hatanaka const void *Decoder) { 64671928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 647ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 648ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 64971928e68SAkira Hatanaka 6509bf2b567SAkira Hatanaka Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 65113e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 6529bf2b567SAkira Hatanaka 6539bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 6549bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 65571928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 65671928e68SAkira Hatanaka 65771928e68SAkira Hatanaka return MCDisassembler::Success; 65871928e68SAkira Hatanaka } 65971928e68SAkira Hatanaka 66071928e68SAkira Hatanaka 66171928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 66271928e68SAkira Hatanaka unsigned RegNo, 66371928e68SAkira Hatanaka uint64_t Address, 66471928e68SAkira Hatanaka const void *Decoder) { 66571928e68SAkira Hatanaka // Currently only hardware register 29 is supported. 66671928e68SAkira Hatanaka if (RegNo != 29) 66771928e68SAkira Hatanaka return MCDisassembler::Fail; 66871928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); 66971928e68SAkira Hatanaka return MCDisassembler::Success; 67071928e68SAkira Hatanaka } 67171928e68SAkira Hatanaka 67271928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 67371928e68SAkira Hatanaka unsigned RegNo, 67471928e68SAkira Hatanaka uint64_t Address, 67571928e68SAkira Hatanaka const void *Decoder) { 6769bf2b567SAkira Hatanaka if (RegNo > 30 || RegNo %2) 67771928e68SAkira Hatanaka return MCDisassembler::Fail; 67871928e68SAkira Hatanaka 6799bf2b567SAkira Hatanaka ; 6809bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 6819bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 68271928e68SAkira Hatanaka return MCDisassembler::Success; 68371928e68SAkira Hatanaka } 68471928e68SAkira Hatanaka 68500fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 686ecabd1a5SAkira Hatanaka unsigned RegNo, 687ecabd1a5SAkira Hatanaka uint64_t Address, 688ecabd1a5SAkira Hatanaka const void *Decoder) { 689ecabd1a5SAkira Hatanaka if (RegNo >= 4) 690ecabd1a5SAkira Hatanaka return MCDisassembler::Fail; 691ecabd1a5SAkira Hatanaka 69200fcf2e1SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo); 693ecabd1a5SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 694ecabd1a5SAkira Hatanaka return MCDisassembler::Success; 695ecabd1a5SAkira Hatanaka } 696ecabd1a5SAkira Hatanaka 6978002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 69859bfaf77SAkira Hatanaka unsigned RegNo, 69959bfaf77SAkira Hatanaka uint64_t Address, 70059bfaf77SAkira Hatanaka const void *Decoder) { 70159bfaf77SAkira Hatanaka if (RegNo >= 4) 70259bfaf77SAkira Hatanaka return MCDisassembler::Fail; 70359bfaf77SAkira Hatanaka 7048002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo); 70559bfaf77SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 70659bfaf77SAkira Hatanaka return MCDisassembler::Success; 70759bfaf77SAkira Hatanaka } 70859bfaf77SAkira Hatanaka 7098002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 71059bfaf77SAkira Hatanaka unsigned RegNo, 71159bfaf77SAkira Hatanaka uint64_t Address, 71259bfaf77SAkira Hatanaka const void *Decoder) { 71359bfaf77SAkira Hatanaka if (RegNo >= 4) 71459bfaf77SAkira Hatanaka return MCDisassembler::Fail; 71559bfaf77SAkira Hatanaka 7168002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo); 71759bfaf77SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 71859bfaf77SAkira Hatanaka return MCDisassembler::Success; 71959bfaf77SAkira Hatanaka } 72059bfaf77SAkira Hatanaka 7213eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, 7223eb663b0SJack Carter unsigned RegNo, 7233eb663b0SJack Carter uint64_t Address, 7243eb663b0SJack Carter const void *Decoder) { 7253eb663b0SJack Carter if (RegNo > 31) 7263eb663b0SJack Carter return MCDisassembler::Fail; 7273eb663b0SJack Carter 7283eb663b0SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo); 7293eb663b0SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 7303eb663b0SJack Carter return MCDisassembler::Success; 7313eb663b0SJack Carter } 7323eb663b0SJack Carter 7335dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, 7345dc8ac92SJack Carter unsigned RegNo, 7355dc8ac92SJack Carter uint64_t Address, 7365dc8ac92SJack Carter const void *Decoder) { 7375dc8ac92SJack Carter if (RegNo > 31) 7385dc8ac92SJack Carter return MCDisassembler::Fail; 7395dc8ac92SJack Carter 7405dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo); 7415dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 7425dc8ac92SJack Carter return MCDisassembler::Success; 7435dc8ac92SJack Carter } 7445dc8ac92SJack Carter 7455dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, 7465dc8ac92SJack Carter unsigned RegNo, 7475dc8ac92SJack Carter uint64_t Address, 7485dc8ac92SJack Carter const void *Decoder) { 7495dc8ac92SJack Carter if (RegNo > 31) 7505dc8ac92SJack Carter return MCDisassembler::Fail; 7515dc8ac92SJack Carter 7525dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo); 7535dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 7545dc8ac92SJack Carter return MCDisassembler::Success; 7555dc8ac92SJack Carter } 7565dc8ac92SJack Carter 7575dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, 7585dc8ac92SJack Carter unsigned RegNo, 7595dc8ac92SJack Carter uint64_t Address, 7605dc8ac92SJack Carter const void *Decoder) { 7615dc8ac92SJack Carter if (RegNo > 31) 7625dc8ac92SJack Carter return MCDisassembler::Fail; 7635dc8ac92SJack Carter 7645dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo); 7655dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 7665dc8ac92SJack Carter return MCDisassembler::Success; 7675dc8ac92SJack Carter } 7685dc8ac92SJack Carter 769a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, 770a591fdc6SMatheus Almeida unsigned RegNo, 771a591fdc6SMatheus Almeida uint64_t Address, 772a591fdc6SMatheus Almeida const void *Decoder) { 773a591fdc6SMatheus Almeida if (RegNo > 7) 774a591fdc6SMatheus Almeida return MCDisassembler::Fail; 775a591fdc6SMatheus Almeida 776a591fdc6SMatheus Almeida unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo); 777a591fdc6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Reg)); 778a591fdc6SMatheus Almeida return MCDisassembler::Success; 779a591fdc6SMatheus Almeida } 780a591fdc6SMatheus Almeida 78171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 78271928e68SAkira Hatanaka unsigned Offset, 78371928e68SAkira Hatanaka uint64_t Address, 78471928e68SAkira Hatanaka const void *Decoder) { 78571928e68SAkira Hatanaka unsigned BranchOffset = Offset & 0xffff; 78671928e68SAkira Hatanaka BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4; 78771928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 78871928e68SAkira Hatanaka return MCDisassembler::Success; 78971928e68SAkira Hatanaka } 79071928e68SAkira Hatanaka 79171928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 79271928e68SAkira Hatanaka unsigned Insn, 79371928e68SAkira Hatanaka uint64_t Address, 79471928e68SAkira Hatanaka const void *Decoder) { 79571928e68SAkira Hatanaka 796ecaef49fSJim Grosbach unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 79771928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 79871928e68SAkira Hatanaka return MCDisassembler::Success; 79971928e68SAkira Hatanaka } 80071928e68SAkira Hatanaka 8018a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 8028a80aa76SZoran Jovanovic unsigned Offset, 8038a80aa76SZoran Jovanovic uint64_t Address, 8048a80aa76SZoran Jovanovic const void *Decoder) { 8058a80aa76SZoran Jovanovic unsigned BranchOffset = Offset & 0xffff; 8068a80aa76SZoran Jovanovic BranchOffset = SignExtend32<18>(BranchOffset << 1); 8078a80aa76SZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 8088a80aa76SZoran Jovanovic return MCDisassembler::Success; 8098a80aa76SZoran Jovanovic } 8108a80aa76SZoran Jovanovic 811507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 812507e084aSZoran Jovanovic unsigned Insn, 813507e084aSZoran Jovanovic uint64_t Address, 814507e084aSZoran Jovanovic const void *Decoder) { 815507e084aSZoran Jovanovic unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1; 816507e084aSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 817507e084aSZoran Jovanovic return MCDisassembler::Success; 818507e084aSZoran Jovanovic } 81971928e68SAkira Hatanaka 82071928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 82171928e68SAkira Hatanaka unsigned Insn, 82271928e68SAkira Hatanaka uint64_t Address, 82371928e68SAkira Hatanaka const void *Decoder) { 82471928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); 82571928e68SAkira Hatanaka return MCDisassembler::Success; 82671928e68SAkira Hatanaka } 82771928e68SAkira Hatanaka 828779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst, 829779c5937SMatheus Almeida unsigned Insn, 830779c5937SMatheus Almeida uint64_t Address, 831779c5937SMatheus Almeida const void *Decoder) { 832779c5937SMatheus Almeida // We add one to the immediate field as it was encoded as 'imm - 1'. 833779c5937SMatheus Almeida Inst.addOperand(MCOperand::CreateImm(Insn + 1)); 834779c5937SMatheus Almeida return MCDisassembler::Success; 835779c5937SMatheus Almeida } 836779c5937SMatheus Almeida 83771928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 83871928e68SAkira Hatanaka unsigned Insn, 83971928e68SAkira Hatanaka uint64_t Address, 84071928e68SAkira Hatanaka const void *Decoder) { 84171928e68SAkira Hatanaka // First we need to grab the pos(lsb) from MCInst. 84271928e68SAkira Hatanaka int Pos = Inst.getOperand(2).getImm(); 84371928e68SAkira Hatanaka int Size = (int) Insn - Pos + 1; 84471928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 84571928e68SAkira Hatanaka return MCDisassembler::Success; 84671928e68SAkira Hatanaka } 84771928e68SAkira Hatanaka 84871928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 84971928e68SAkira Hatanaka unsigned Insn, 85071928e68SAkira Hatanaka uint64_t Address, 85171928e68SAkira Hatanaka const void *Decoder) { 85271928e68SAkira Hatanaka int Size = (int) Insn + 1; 85371928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 85471928e68SAkira Hatanaka return MCDisassembler::Success; 85571928e68SAkira Hatanaka } 856