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" 17a1bc0f56SLang Hames #include "llvm/MC/MCContext.h" 1871928e68SAkira Hatanaka #include "llvm/MC/MCDisassembler.h" 19ecaef49fSJim Grosbach #include "llvm/MC/MCFixedLenDisassembler.h" 20ed0881b2SChandler Carruth #include "llvm/MC/MCInst.h" 21ed0881b2SChandler Carruth #include "llvm/MC/MCSubtargetInfo.h" 22ed0881b2SChandler Carruth #include "llvm/Support/MathExtras.h" 2371928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h" 2471928e68SAkira Hatanaka 2571928e68SAkira Hatanaka using namespace llvm; 2671928e68SAkira Hatanaka 27e96dd897SChandler Carruth #define DEBUG_TYPE "mips-disassembler" 28e96dd897SChandler Carruth 2971928e68SAkira Hatanaka typedef MCDisassembler::DecodeStatus DecodeStatus; 3071928e68SAkira Hatanaka 31cb3e98cfSBenjamin Kramer namespace { 32cb3e98cfSBenjamin Kramer 334aa6bea7SRafael Espindola /// A disasembler class for Mips. 349bf2b567SAkira Hatanaka class MipsDisassemblerBase : public MCDisassembler { 3571928e68SAkira Hatanaka public: 36a1bc0f56SLang Hames MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx, 374aa6bea7SRafael Espindola bool IsBigEndian) 384aa6bea7SRafael Espindola : MCDisassembler(STI, Ctx), 394aa6bea7SRafael Espindola IsN64(STI.getFeatureBits() & Mips::FeatureN64), 404aa6bea7SRafael Espindola IsBigEndian(IsBigEndian) {} 4171928e68SAkira Hatanaka 429bf2b567SAkira Hatanaka virtual ~MipsDisassemblerBase() {} 439bf2b567SAkira Hatanaka 449bfa2e2eSAkira Hatanaka bool isN64() const { return IsN64; } 459bfa2e2eSAkira Hatanaka 469bf2b567SAkira Hatanaka private: 479bfa2e2eSAkira Hatanaka bool IsN64; 489bf2b567SAkira Hatanaka protected: 494aa6bea7SRafael Espindola bool IsBigEndian; 509bf2b567SAkira Hatanaka }; 519bf2b567SAkira Hatanaka 524aa6bea7SRafael Espindola /// A disasembler class for Mips32. 539bf2b567SAkira Hatanaka class MipsDisassembler : public MipsDisassemblerBase { 54dde3d582SVladimir Medic bool IsMicroMips; 559bf2b567SAkira Hatanaka public: 56c171f65aSDaniel Sanders MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool bigEndian) 57c171f65aSDaniel Sanders : MipsDisassemblerBase(STI, Ctx, bigEndian) { 58dde3d582SVladimir Medic IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips; 59dde3d582SVladimir Medic } 6071928e68SAkira Hatanaka 61c171f65aSDaniel Sanders bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; } 62c171f65aSDaniel Sanders bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; } 63c171f65aSDaniel Sanders bool hasMips32r6() const { 645c582b2fSDaniel Sanders return STI.getFeatureBits() & Mips::FeatureMips32r6; 655c582b2fSDaniel Sanders } 665c582b2fSDaniel Sanders 670fa60416SDaniel Sanders bool isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; } 680fa60416SDaniel Sanders 69c171f65aSDaniel Sanders bool hasCOP3() const { 70c171f65aSDaniel Sanders // Only present in MIPS-I and MIPS-II 71c171f65aSDaniel Sanders return !hasMips32() && !hasMips3(); 72c171f65aSDaniel Sanders } 73c171f65aSDaniel Sanders 744aa6bea7SRafael Espindola DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 757fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address, 764aa6bea7SRafael Espindola raw_ostream &VStream, 774aa6bea7SRafael Espindola raw_ostream &CStream) const override; 7871928e68SAkira Hatanaka }; 7971928e68SAkira Hatanaka 804aa6bea7SRafael Espindola /// A disasembler class for Mips64. 819bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase { 8271928e68SAkira Hatanaka public: 83a1bc0f56SLang Hames Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 849bf2b567SAkira Hatanaka bool bigEndian) : 85a1bc0f56SLang Hames MipsDisassemblerBase(STI, Ctx, bigEndian) {} 8671928e68SAkira Hatanaka 874aa6bea7SRafael Espindola DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 887fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address, 894aa6bea7SRafael Espindola raw_ostream &VStream, 904aa6bea7SRafael Espindola raw_ostream &CStream) const override; 9171928e68SAkira Hatanaka }; 9271928e68SAkira Hatanaka 93cb3e98cfSBenjamin Kramer } // end anonymous namespace 94cb3e98cfSBenjamin Kramer 9571928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them. 9671928e68SAkira Hatanaka // Definitions are further down. 9713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 9871928e68SAkira Hatanaka unsigned RegNo, 9971928e68SAkira Hatanaka uint64_t Address, 10071928e68SAkira Hatanaka const void *Decoder); 10171928e68SAkira Hatanaka 102ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 103ec8a5490SReed Kotler unsigned RegNo, 104ec8a5490SReed Kotler uint64_t Address, 105ec8a5490SReed Kotler const void *Decoder); 106ec8a5490SReed Kotler 107b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, 108b0852e54SZoran Jovanovic unsigned RegNo, 109b0852e54SZoran Jovanovic uint64_t Address, 110b0852e54SZoran Jovanovic const void *Decoder); 111b0852e54SZoran Jovanovic 11213e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 11371928e68SAkira Hatanaka unsigned RegNo, 11471928e68SAkira Hatanaka uint64_t Address, 11571928e68SAkira Hatanaka const void *Decoder); 11671928e68SAkira Hatanaka 1179bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 1189bfa2e2eSAkira Hatanaka unsigned Insn, 1199bfa2e2eSAkira Hatanaka uint64_t Address, 1209bfa2e2eSAkira Hatanaka const void *Decoder); 1219bfa2e2eSAkira Hatanaka 122654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 123ecabd1a5SAkira Hatanaka unsigned RegNo, 124ecabd1a5SAkira Hatanaka uint64_t Address, 125ecabd1a5SAkira Hatanaka const void *Decoder); 126ecabd1a5SAkira Hatanaka 12771928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 12871928e68SAkira Hatanaka unsigned RegNo, 12971928e68SAkira Hatanaka uint64_t Address, 13071928e68SAkira Hatanaka const void *Decoder); 13171928e68SAkira Hatanaka 13271928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 13371928e68SAkira Hatanaka unsigned RegNo, 13471928e68SAkira Hatanaka uint64_t Address, 13571928e68SAkira Hatanaka const void *Decoder); 13671928e68SAkira Hatanaka 13771928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 13871928e68SAkira Hatanaka unsigned RegNo, 13971928e68SAkira Hatanaka uint64_t Address, 14071928e68SAkira Hatanaka const void *Decoder); 14171928e68SAkira Hatanaka 1421fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 1431fb1b8b8SAkira Hatanaka unsigned RegNo, 1441fb1b8b8SAkira Hatanaka uint64_t Address, 1451fb1b8b8SAkira Hatanaka const void *Decoder); 1461fb1b8b8SAkira Hatanaka 1470fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, 1480fa60416SDaniel Sanders uint64_t Address, 1490fa60416SDaniel Sanders const void *Decoder); 1500fa60416SDaniel Sanders 15171928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 15271928e68SAkira Hatanaka unsigned Insn, 15371928e68SAkira Hatanaka uint64_t Address, 15471928e68SAkira Hatanaka const void *Decoder); 15571928e68SAkira Hatanaka 15671928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 15771928e68SAkira Hatanaka unsigned RegNo, 15871928e68SAkira Hatanaka uint64_t Address, 15971928e68SAkira Hatanaka const void *Decoder); 16071928e68SAkira Hatanaka 16100fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 162ecabd1a5SAkira Hatanaka unsigned RegNo, 163ecabd1a5SAkira Hatanaka uint64_t Address, 164ecabd1a5SAkira Hatanaka const void *Decoder); 165ecabd1a5SAkira Hatanaka 1668002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 16759bfaf77SAkira Hatanaka unsigned RegNo, 16859bfaf77SAkira Hatanaka uint64_t Address, 16959bfaf77SAkira Hatanaka const void *Decoder); 17059bfaf77SAkira Hatanaka 1718002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 17259bfaf77SAkira Hatanaka unsigned RegNo, 17359bfaf77SAkira Hatanaka uint64_t Address, 17459bfaf77SAkira Hatanaka const void *Decoder); 17559bfaf77SAkira Hatanaka 1763eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, 1773eb663b0SJack Carter unsigned RegNo, 1783eb663b0SJack Carter uint64_t Address, 1793eb663b0SJack Carter const void *Decoder); 1803eb663b0SJack Carter 1815dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, 1825dc8ac92SJack Carter unsigned RegNo, 1835dc8ac92SJack Carter uint64_t Address, 1845dc8ac92SJack Carter const void *Decoder); 1855dc8ac92SJack Carter 1865dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, 1875dc8ac92SJack Carter unsigned RegNo, 1885dc8ac92SJack Carter uint64_t Address, 1895dc8ac92SJack Carter const void *Decoder); 1905dc8ac92SJack Carter 1915dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, 1925dc8ac92SJack Carter unsigned RegNo, 1935dc8ac92SJack Carter uint64_t Address, 1945dc8ac92SJack Carter const void *Decoder); 1955dc8ac92SJack Carter 196a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, 197a591fdc6SMatheus Almeida unsigned RegNo, 198a591fdc6SMatheus Almeida uint64_t Address, 199a591fdc6SMatheus Almeida const void *Decoder); 200a591fdc6SMatheus Almeida 2012a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, 2022a83d680SDaniel Sanders unsigned RegNo, 2032a83d680SDaniel Sanders uint64_t Address, 2042a83d680SDaniel Sanders const void *Decoder); 2052a83d680SDaniel Sanders 20671928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 20771928e68SAkira Hatanaka unsigned Offset, 20871928e68SAkira Hatanaka uint64_t Address, 20971928e68SAkira Hatanaka const void *Decoder); 21071928e68SAkira Hatanaka 21171928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 21271928e68SAkira Hatanaka unsigned Insn, 21371928e68SAkira Hatanaka uint64_t Address, 21471928e68SAkira Hatanaka const void *Decoder); 21571928e68SAkira Hatanaka 2163c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst, 2173c8869dcSZoran Jovanovic unsigned Offset, 2183c8869dcSZoran Jovanovic uint64_t Address, 2193c8869dcSZoran Jovanovic const void *Decoder); 2203c8869dcSZoran Jovanovic 2213c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst, 2223c8869dcSZoran Jovanovic unsigned Offset, 2233c8869dcSZoran Jovanovic uint64_t Address, 2243c8869dcSZoran Jovanovic const void *Decoder); 2253c8869dcSZoran Jovanovic 2268a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is 2278a80aa76SZoran Jovanovic // shifted left by 1 bit. 2288a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 2298a80aa76SZoran Jovanovic unsigned Offset, 2308a80aa76SZoran Jovanovic uint64_t Address, 2318a80aa76SZoran Jovanovic const void *Decoder); 2328a80aa76SZoran Jovanovic 233507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is 234507e084aSZoran Jovanovic // shifted left by 1 bit. 235507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 236507e084aSZoran Jovanovic unsigned Insn, 237507e084aSZoran Jovanovic uint64_t Address, 238507e084aSZoran Jovanovic const void *Decoder); 239507e084aSZoran Jovanovic 24071928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 24171928e68SAkira Hatanaka unsigned Insn, 24271928e68SAkira Hatanaka uint64_t Address, 24371928e68SAkira Hatanaka const void *Decoder); 24471928e68SAkira Hatanaka 24592db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 24692db6b78SDaniel Sanders unsigned Insn, 24792db6b78SDaniel Sanders uint64_t Address, 24892db6b78SDaniel Sanders const void *Decoder); 24992db6b78SDaniel Sanders 250fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 251fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder); 252fe0bf9f6SMatheus Almeida 253dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 254dde3d582SVladimir Medic unsigned Insn, 255dde3d582SVladimir Medic uint64_t Address, 256dde3d582SVladimir Medic const void *Decoder); 257dde3d582SVladimir Medic 258dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 259dde3d582SVladimir Medic unsigned Insn, 260dde3d582SVladimir Medic uint64_t Address, 261dde3d582SVladimir Medic const void *Decoder); 262dde3d582SVladimir Medic 26371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 26471928e68SAkira Hatanaka uint64_t Address, 26571928e68SAkira Hatanaka const void *Decoder); 26671928e68SAkira Hatanaka 26792db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, 26892db6b78SDaniel Sanders uint64_t Address, 26992db6b78SDaniel Sanders const void *Decoder); 27092db6b78SDaniel Sanders 27192db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, 27292db6b78SDaniel Sanders uint64_t Address, 27392db6b78SDaniel Sanders const void *Decoder); 27492db6b78SDaniel Sanders 2756a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 2766a803f61SDaniel Sanders unsigned Insn, 2776a803f61SDaniel Sanders uint64_t Address, 2786a803f61SDaniel Sanders const void *Decoder); 2796a803f61SDaniel Sanders 28071928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 28171928e68SAkira Hatanaka unsigned Insn, 28271928e68SAkira Hatanaka uint64_t Address, 28371928e68SAkira Hatanaka const void *Decoder); 28471928e68SAkira Hatanaka 285779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which 286779c5937SMatheus Almeida // is off by one. 287779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst, 288779c5937SMatheus Almeida unsigned Insn, 289779c5937SMatheus Almeida uint64_t Address, 290779c5937SMatheus Almeida const void *Decoder); 291779c5937SMatheus Almeida 29271928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 29371928e68SAkira Hatanaka unsigned Insn, 29471928e68SAkira Hatanaka uint64_t Address, 29571928e68SAkira Hatanaka const void *Decoder); 29671928e68SAkira Hatanaka 29771928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 29871928e68SAkira Hatanaka unsigned Insn, 29971928e68SAkira Hatanaka uint64_t Address, 30071928e68SAkira Hatanaka const void *Decoder); 30171928e68SAkira Hatanaka 302b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 303b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder); 304b59e1a41SDaniel Sanders 3052855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 3062855142aSZoran Jovanovic uint64_t Address, const void *Decoder); 3072855142aSZoran Jovanovic 308b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't 309b50ccf8eSDaniel Sanders /// handle. 310b50ccf8eSDaniel Sanders template <typename InsnType> 311b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 312b50ccf8eSDaniel Sanders const void *Decoder); 3135c582b2fSDaniel Sanders 3145c582b2fSDaniel Sanders template <typename InsnType> 3155c582b2fSDaniel Sanders static DecodeStatus 3165c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3175c582b2fSDaniel Sanders const void *Decoder); 3185c582b2fSDaniel Sanders 3195c582b2fSDaniel Sanders template <typename InsnType> 3205c582b2fSDaniel Sanders static DecodeStatus 3215c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3225c582b2fSDaniel Sanders const void *Decoder); 3235c582b2fSDaniel Sanders 3245c582b2fSDaniel Sanders template <typename InsnType> 3255c582b2fSDaniel Sanders static DecodeStatus 3265c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3275c582b2fSDaniel Sanders const void *Decoder); 3285c582b2fSDaniel Sanders 3295c582b2fSDaniel Sanders template <typename InsnType> 3305c582b2fSDaniel Sanders static DecodeStatus 3315c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3325c582b2fSDaniel Sanders const void *Decoder); 3335c582b2fSDaniel Sanders 3345c582b2fSDaniel Sanders template <typename InsnType> 3355c582b2fSDaniel Sanders static DecodeStatus 3365c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3375c582b2fSDaniel Sanders const void *Decoder); 3385c582b2fSDaniel Sanders 33928a0ca07SZoran Jovanovic template <typename InsnType> 34028a0ca07SZoran Jovanovic static DecodeStatus 34128a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 34228a0ca07SZoran Jovanovic const void *Decoder); 34328a0ca07SZoran Jovanovic 344a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn, 345a4c4b5fcSZoran Jovanovic uint64_t Address, 346a4c4b5fcSZoran Jovanovic const void *Decoder); 347a4c4b5fcSZoran Jovanovic 34871928e68SAkira Hatanaka namespace llvm { 34971928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 35071928e68SAkira Hatanaka TheMips64elTarget; 35171928e68SAkira Hatanaka } 35271928e68SAkira Hatanaka 35371928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler( 35471928e68SAkira Hatanaka const Target &T, 355a1bc0f56SLang Hames const MCSubtargetInfo &STI, 356a1bc0f56SLang Hames MCContext &Ctx) { 357a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, true); 35871928e68SAkira Hatanaka } 35971928e68SAkira Hatanaka 36071928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler( 36171928e68SAkira Hatanaka const Target &T, 362a1bc0f56SLang Hames const MCSubtargetInfo &STI, 363a1bc0f56SLang Hames MCContext &Ctx) { 364a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, false); 36571928e68SAkira Hatanaka } 36671928e68SAkira Hatanaka 36771928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler( 36871928e68SAkira Hatanaka const Target &T, 369a1bc0f56SLang Hames const MCSubtargetInfo &STI, 370a1bc0f56SLang Hames MCContext &Ctx) { 371a1bc0f56SLang Hames return new Mips64Disassembler(STI, Ctx, true); 37271928e68SAkira Hatanaka } 37371928e68SAkira Hatanaka 37471928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler( 37571928e68SAkira Hatanaka const Target &T, 376a1bc0f56SLang Hames const MCSubtargetInfo &STI, 377a1bc0f56SLang Hames MCContext &Ctx) { 378a1bc0f56SLang Hames return new Mips64Disassembler(STI, Ctx, false); 37971928e68SAkira Hatanaka } 38071928e68SAkira Hatanaka 38171928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() { 38271928e68SAkira Hatanaka // Register the disassembler. 38371928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 38471928e68SAkira Hatanaka createMipsDisassembler); 38571928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 38671928e68SAkira Hatanaka createMipselDisassembler); 38771928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64Target, 38871928e68SAkira Hatanaka createMips64Disassembler); 38971928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 39071928e68SAkira Hatanaka createMips64elDisassembler); 39171928e68SAkira Hatanaka } 39271928e68SAkira Hatanaka 39371928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc" 39471928e68SAkira Hatanaka 3955c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 3965c582b2fSDaniel Sanders const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D); 3975c582b2fSDaniel Sanders const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo(); 3985c582b2fSDaniel Sanders return *(RegInfo->getRegClass(RC).begin() + RegNo); 3995c582b2fSDaniel Sanders } 4005c582b2fSDaniel Sanders 401b50ccf8eSDaniel Sanders template <typename InsnType> 402b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 403b50ccf8eSDaniel Sanders const void *Decoder) { 404b50ccf8eSDaniel Sanders typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *); 405b50ccf8eSDaniel Sanders // The size of the n field depends on the element size 406b50ccf8eSDaniel Sanders // The register class also depends on this. 407b50ccf8eSDaniel Sanders InsnType tmp = fieldFromInstruction(insn, 17, 5); 408b50ccf8eSDaniel Sanders unsigned NSize = 0; 409b50ccf8eSDaniel Sanders DecodeFN RegDecoder = nullptr; 410b50ccf8eSDaniel Sanders if ((tmp & 0x18) == 0x00) { // INSVE_B 411b50ccf8eSDaniel Sanders NSize = 4; 412b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128BRegisterClass; 413b50ccf8eSDaniel Sanders } else if ((tmp & 0x1c) == 0x10) { // INSVE_H 414b50ccf8eSDaniel Sanders NSize = 3; 415b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128HRegisterClass; 416b50ccf8eSDaniel Sanders } else if ((tmp & 0x1e) == 0x18) { // INSVE_W 417b50ccf8eSDaniel Sanders NSize = 2; 418b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128WRegisterClass; 419b50ccf8eSDaniel Sanders } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D 420b50ccf8eSDaniel Sanders NSize = 1; 421b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128DRegisterClass; 422b50ccf8eSDaniel Sanders } else 423b50ccf8eSDaniel Sanders llvm_unreachable("Invalid encoding"); 424b50ccf8eSDaniel Sanders 425b50ccf8eSDaniel Sanders assert(NSize != 0 && RegDecoder != nullptr); 426b50ccf8eSDaniel Sanders 427b50ccf8eSDaniel Sanders // $wd 428b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 6, 5); 429b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 430b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 431b50ccf8eSDaniel Sanders // $wd_in 432b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 433b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 434b50ccf8eSDaniel Sanders // $n 435b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 16, NSize); 436b50ccf8eSDaniel Sanders MI.addOperand(MCOperand::CreateImm(tmp)); 437b50ccf8eSDaniel Sanders // $ws 438b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 11, 5); 439b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 440b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 441b50ccf8eSDaniel Sanders // $n2 442b50ccf8eSDaniel Sanders MI.addOperand(MCOperand::CreateImm(0)); 443b50ccf8eSDaniel Sanders 444b50ccf8eSDaniel Sanders return MCDisassembler::Success; 445b50ccf8eSDaniel Sanders } 446b50ccf8eSDaniel Sanders 4475c582b2fSDaniel Sanders template <typename InsnType> 4485c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, 4495c582b2fSDaniel Sanders uint64_t Address, 4505c582b2fSDaniel Sanders const void *Decoder) { 4515c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 4525c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 4535c582b2fSDaniel Sanders // ISA's instead). 4545c582b2fSDaniel Sanders // 4555c582b2fSDaniel Sanders // We have: 4565c582b2fSDaniel Sanders // 0b001000 sssss ttttt iiiiiiiiiiiiiiii 4575c582b2fSDaniel Sanders // BOVC if rs >= rt 4585c582b2fSDaniel Sanders // BEQZALC if rs == 0 && rt != 0 4595c582b2fSDaniel Sanders // BEQC if rs < rt && rs != 0 4605c582b2fSDaniel Sanders 4615c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 4625c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 463d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 4645c582b2fSDaniel Sanders bool HasRs = false; 4655c582b2fSDaniel Sanders 4665c582b2fSDaniel Sanders if (Rs >= Rt) { 4675c582b2fSDaniel Sanders MI.setOpcode(Mips::BOVC); 4685c582b2fSDaniel Sanders HasRs = true; 4695c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 4705c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQC); 4715c582b2fSDaniel Sanders HasRs = true; 4725c582b2fSDaniel Sanders } else 4735c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQZALC); 4745c582b2fSDaniel Sanders 4755c582b2fSDaniel Sanders if (HasRs) 4765c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 4775c582b2fSDaniel Sanders Rs))); 4785c582b2fSDaniel Sanders 4795c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 4805c582b2fSDaniel Sanders Rt))); 4815c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 4825c582b2fSDaniel Sanders 4835c582b2fSDaniel Sanders return MCDisassembler::Success; 4845c582b2fSDaniel Sanders } 4855c582b2fSDaniel Sanders 4865c582b2fSDaniel Sanders template <typename InsnType> 4875c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, 4885c582b2fSDaniel Sanders uint64_t Address, 4895c582b2fSDaniel Sanders const void *Decoder) { 4905c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 4915c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 4925c582b2fSDaniel Sanders // ISA's instead). 4935c582b2fSDaniel Sanders // 4945c582b2fSDaniel Sanders // We have: 4955c582b2fSDaniel Sanders // 0b011000 sssss ttttt iiiiiiiiiiiiiiii 4965c582b2fSDaniel Sanders // BNVC if rs >= rt 4975c582b2fSDaniel Sanders // BNEZALC if rs == 0 && rt != 0 4985c582b2fSDaniel Sanders // BNEC if rs < rt && rs != 0 4995c582b2fSDaniel Sanders 5005c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 5015c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 502d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 5035c582b2fSDaniel Sanders bool HasRs = false; 5045c582b2fSDaniel Sanders 5055c582b2fSDaniel Sanders if (Rs >= Rt) { 5065c582b2fSDaniel Sanders MI.setOpcode(Mips::BNVC); 5075c582b2fSDaniel Sanders HasRs = true; 5085c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 5095c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEC); 5105c582b2fSDaniel Sanders HasRs = true; 5115c582b2fSDaniel Sanders } else 5125c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEZALC); 5135c582b2fSDaniel Sanders 5145c582b2fSDaniel Sanders if (HasRs) 5155c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5165c582b2fSDaniel Sanders Rs))); 5175c582b2fSDaniel Sanders 5185c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5195c582b2fSDaniel Sanders Rt))); 5205c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 5215c582b2fSDaniel Sanders 5225c582b2fSDaniel Sanders return MCDisassembler::Success; 5235c582b2fSDaniel Sanders } 5245c582b2fSDaniel Sanders 5255c582b2fSDaniel Sanders template <typename InsnType> 5265c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, 5275c582b2fSDaniel Sanders uint64_t Address, 5285c582b2fSDaniel Sanders const void *Decoder) { 5295c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5305c582b2fSDaniel Sanders // (otherwise we would have matched the BLEZL instruction from the earlier 5315c582b2fSDaniel Sanders // ISA's instead). 5325c582b2fSDaniel Sanders // 5335c582b2fSDaniel Sanders // We have: 5345c582b2fSDaniel Sanders // 0b010110 sssss ttttt iiiiiiiiiiiiiiii 5355c582b2fSDaniel Sanders // Invalid if rs == 0 5365c582b2fSDaniel Sanders // BLEZC if rs == 0 && rt != 0 5375c582b2fSDaniel Sanders // BGEZC if rs == rt && rt != 0 5385c582b2fSDaniel Sanders // BGEC if rs != rt && rs != 0 && rt != 0 5395c582b2fSDaniel Sanders 5405c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 5415c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 542d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 54328a0ca07SZoran Jovanovic bool HasRs = false; 5445c582b2fSDaniel Sanders 5455c582b2fSDaniel Sanders if (Rt == 0) 5465c582b2fSDaniel Sanders return MCDisassembler::Fail; 5475c582b2fSDaniel Sanders else if (Rs == 0) 5485c582b2fSDaniel Sanders MI.setOpcode(Mips::BLEZC); 5495c582b2fSDaniel Sanders else if (Rs == Rt) 5505c582b2fSDaniel Sanders MI.setOpcode(Mips::BGEZC); 55128a0ca07SZoran Jovanovic else { 55228a0ca07SZoran Jovanovic HasRs = true; 55328a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEC); 55428a0ca07SZoran Jovanovic } 55528a0ca07SZoran Jovanovic 55628a0ca07SZoran Jovanovic if (HasRs) 55728a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 55828a0ca07SZoran Jovanovic Rs))); 5595c582b2fSDaniel Sanders 5605c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5615c582b2fSDaniel Sanders Rt))); 5625c582b2fSDaniel Sanders 5635c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 5645c582b2fSDaniel Sanders 5655c582b2fSDaniel Sanders return MCDisassembler::Success; 5665c582b2fSDaniel Sanders } 5675c582b2fSDaniel Sanders 5685c582b2fSDaniel Sanders template <typename InsnType> 5695c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, 5705c582b2fSDaniel Sanders uint64_t Address, 5715c582b2fSDaniel Sanders const void *Decoder) { 5725c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5735c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZL instruction from the earlier 5745c582b2fSDaniel Sanders // ISA's instead). 5755c582b2fSDaniel Sanders // 5765c582b2fSDaniel Sanders // We have: 5775c582b2fSDaniel Sanders // 0b010111 sssss ttttt iiiiiiiiiiiiiiii 5785c582b2fSDaniel Sanders // Invalid if rs == 0 5795c582b2fSDaniel Sanders // BGTZC if rs == 0 && rt != 0 5805c582b2fSDaniel Sanders // BLTZC if rs == rt && rt != 0 5815c582b2fSDaniel Sanders // BLTC if rs != rt && rs != 0 && rt != 0 5825c582b2fSDaniel Sanders 5835c14b069SZoran Jovanovic bool HasRs = false; 5845c14b069SZoran Jovanovic 5855c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 5865c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 587d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 5885c582b2fSDaniel Sanders 5895c582b2fSDaniel Sanders if (Rt == 0) 5905c582b2fSDaniel Sanders return MCDisassembler::Fail; 5915c582b2fSDaniel Sanders else if (Rs == 0) 5925c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZC); 5935c582b2fSDaniel Sanders else if (Rs == Rt) 5945c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZC); 5955c14b069SZoran Jovanovic else { 5965c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTC); 5975c14b069SZoran Jovanovic HasRs = true; 5985c14b069SZoran Jovanovic } 5995c14b069SZoran Jovanovic 6005c14b069SZoran Jovanovic if (HasRs) 6015c14b069SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6025c14b069SZoran Jovanovic Rs))); 6035c582b2fSDaniel Sanders 6045c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6055c582b2fSDaniel Sanders Rt))); 6065c582b2fSDaniel Sanders 6075c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 6085c582b2fSDaniel Sanders 6095c582b2fSDaniel Sanders return MCDisassembler::Success; 6105c582b2fSDaniel Sanders } 6115c582b2fSDaniel Sanders 6125c582b2fSDaniel Sanders template <typename InsnType> 6135c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, 6145c582b2fSDaniel Sanders uint64_t Address, 6155c582b2fSDaniel Sanders const void *Decoder) { 6165c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6175c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZ instruction from the earlier 6185c582b2fSDaniel Sanders // ISA's instead). 6195c582b2fSDaniel Sanders // 6205c582b2fSDaniel Sanders // We have: 6215c582b2fSDaniel Sanders // 0b000111 sssss ttttt iiiiiiiiiiiiiiii 6225c582b2fSDaniel Sanders // BGTZ if rt == 0 6235c582b2fSDaniel Sanders // BGTZALC if rs == 0 && rt != 0 6245c582b2fSDaniel Sanders // BLTZALC if rs != 0 && rs == rt 6255c582b2fSDaniel Sanders // BLTUC if rs != 0 && rs != rt 6265c582b2fSDaniel Sanders 6275c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6285c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 629d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 6305c582b2fSDaniel Sanders bool HasRs = false; 6315c582b2fSDaniel Sanders bool HasRt = false; 6325c582b2fSDaniel Sanders 6335c582b2fSDaniel Sanders if (Rt == 0) { 6345c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZ); 6355c582b2fSDaniel Sanders HasRs = true; 6365c582b2fSDaniel Sanders } else if (Rs == 0) { 6375c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZALC); 6385c582b2fSDaniel Sanders HasRt = true; 6395c582b2fSDaniel Sanders } else if (Rs == Rt) { 6405c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZALC); 6415c582b2fSDaniel Sanders HasRs = true; 6425c14b069SZoran Jovanovic } else { 6435c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTUC); 6445c14b069SZoran Jovanovic HasRs = true; 6455c14b069SZoran Jovanovic HasRt = true; 6465c14b069SZoran Jovanovic } 6475c582b2fSDaniel Sanders 6485c582b2fSDaniel Sanders if (HasRs) 6495c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6505c582b2fSDaniel Sanders Rs))); 6515c582b2fSDaniel Sanders 6525c582b2fSDaniel Sanders if (HasRt) 6535c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6545c582b2fSDaniel Sanders Rt))); 6555c582b2fSDaniel Sanders 6565c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 6575c582b2fSDaniel Sanders 6585c582b2fSDaniel Sanders return MCDisassembler::Success; 6595c582b2fSDaniel Sanders } 6605c582b2fSDaniel Sanders 66128a0ca07SZoran Jovanovic template <typename InsnType> 66228a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn, 66328a0ca07SZoran Jovanovic uint64_t Address, 66428a0ca07SZoran Jovanovic const void *Decoder) { 66528a0ca07SZoran Jovanovic // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 66628a0ca07SZoran Jovanovic // (otherwise we would have matched the BLEZL instruction from the earlier 66728a0ca07SZoran Jovanovic // ISA's instead). 66828a0ca07SZoran Jovanovic // 66928a0ca07SZoran Jovanovic // We have: 67028a0ca07SZoran Jovanovic // 0b000110 sssss ttttt iiiiiiiiiiiiiiii 67128a0ca07SZoran Jovanovic // Invalid if rs == 0 67228a0ca07SZoran Jovanovic // BLEZALC if rs == 0 && rt != 0 67328a0ca07SZoran Jovanovic // BGEZALC if rs == rt && rt != 0 67428a0ca07SZoran Jovanovic // BGEUC if rs != rt && rs != 0 && rt != 0 67528a0ca07SZoran Jovanovic 67628a0ca07SZoran Jovanovic InsnType Rs = fieldFromInstruction(insn, 21, 5); 67728a0ca07SZoran Jovanovic InsnType Rt = fieldFromInstruction(insn, 16, 5); 678d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 67928a0ca07SZoran Jovanovic bool HasRs = false; 68028a0ca07SZoran Jovanovic 68128a0ca07SZoran Jovanovic if (Rt == 0) 68228a0ca07SZoran Jovanovic return MCDisassembler::Fail; 68328a0ca07SZoran Jovanovic else if (Rs == 0) 68428a0ca07SZoran Jovanovic MI.setOpcode(Mips::BLEZALC); 68528a0ca07SZoran Jovanovic else if (Rs == Rt) 68628a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEZALC); 68728a0ca07SZoran Jovanovic else { 68828a0ca07SZoran Jovanovic HasRs = true; 68928a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEUC); 69028a0ca07SZoran Jovanovic } 69128a0ca07SZoran Jovanovic 69228a0ca07SZoran Jovanovic if (HasRs) 69328a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 69428a0ca07SZoran Jovanovic Rs))); 69528a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 69628a0ca07SZoran Jovanovic Rt))); 69728a0ca07SZoran Jovanovic 69828a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateImm(Imm)); 69928a0ca07SZoran Jovanovic 70028a0ca07SZoran Jovanovic return MCDisassembler::Success; 70128a0ca07SZoran Jovanovic } 70228a0ca07SZoran Jovanovic 703*ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted 704*ea22c4cfSJozef Kolek /// according to the given endianess. 705*ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 706*ea22c4cfSJozef Kolek uint64_t &Size, uint32_t &Insn, 707*ea22c4cfSJozef Kolek bool IsBigEndian) { 708*ea22c4cfSJozef Kolek // We want to read exactly 2 Bytes of data. 709*ea22c4cfSJozef Kolek if (Bytes.size() < 2) { 710*ea22c4cfSJozef Kolek Size = 0; 711*ea22c4cfSJozef Kolek return MCDisassembler::Fail; 712*ea22c4cfSJozef Kolek } 713*ea22c4cfSJozef Kolek 714*ea22c4cfSJozef Kolek if (IsBigEndian) { 715*ea22c4cfSJozef Kolek Insn = (Bytes[0] << 8) | Bytes[1]; 716*ea22c4cfSJozef Kolek } else { 717*ea22c4cfSJozef Kolek Insn = (Bytes[1] << 8) | Bytes[0]; 718*ea22c4cfSJozef Kolek } 719*ea22c4cfSJozef Kolek 720*ea22c4cfSJozef Kolek return MCDisassembler::Success; 721*ea22c4cfSJozef Kolek } 722*ea22c4cfSJozef Kolek 7237fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted 7244aa6bea7SRafael Espindola /// according to the given endianess 7257fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 7267fc5b874SRafael Espindola uint64_t &Size, uint32_t &Insn, 7277fc5b874SRafael Espindola bool IsBigEndian, bool IsMicroMips) { 72871928e68SAkira Hatanaka // We want to read exactly 4 Bytes of data. 7297fc5b874SRafael Espindola if (Bytes.size() < 4) { 7304aa6bea7SRafael Espindola Size = 0; 73171928e68SAkira Hatanaka return MCDisassembler::Fail; 73271928e68SAkira Hatanaka } 73371928e68SAkira Hatanaka 734*ea22c4cfSJozef Kolek // High 16 bits of a 32-bit microMIPS instruction (where the opcode is) 735*ea22c4cfSJozef Kolek // always precede the low 16 bits in the instruction stream (that is, they 736*ea22c4cfSJozef Kolek // are placed at lower addresses in the instruction stream). 737*ea22c4cfSJozef Kolek // 738*ea22c4cfSJozef Kolek // microMIPS byte ordering: 739*ea22c4cfSJozef Kolek // Big-endian: 0 | 1 | 2 | 3 740*ea22c4cfSJozef Kolek // Little-endian: 1 | 0 | 3 | 2 741*ea22c4cfSJozef Kolek 7424aa6bea7SRafael Espindola if (IsBigEndian) { 74371928e68SAkira Hatanaka // Encoded as a big-endian 32-bit word in the stream. 7444aa6bea7SRafael Espindola Insn = 7454aa6bea7SRafael Espindola (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24); 7464aa6bea7SRafael Espindola } else { 747dde3d582SVladimir Medic if (IsMicroMips) { 7484aa6bea7SRafael Espindola Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) | 749dde3d582SVladimir Medic (Bytes[1] << 24); 750dde3d582SVladimir Medic } else { 7514aa6bea7SRafael Espindola Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | 75271928e68SAkira Hatanaka (Bytes[3] << 24); 75371928e68SAkira Hatanaka } 754dde3d582SVladimir Medic } 75571928e68SAkira Hatanaka 75671928e68SAkira Hatanaka return MCDisassembler::Success; 75771928e68SAkira Hatanaka } 75871928e68SAkira Hatanaka 7594aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 7607fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 76171928e68SAkira Hatanaka uint64_t Address, 7624aa6bea7SRafael Espindola raw_ostream &VStream, 7634aa6bea7SRafael Espindola raw_ostream &CStream) const { 76471928e68SAkira Hatanaka uint32_t Insn; 765*ea22c4cfSJozef Kolek DecodeStatus Result; 76671928e68SAkira Hatanaka 767*ea22c4cfSJozef Kolek if (IsMicroMips) { 768*ea22c4cfSJozef Kolek Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); 769*ea22c4cfSJozef Kolek 770*ea22c4cfSJozef Kolek DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n"); 771*ea22c4cfSJozef Kolek // Calling the auto-generated decoder function. 772*ea22c4cfSJozef Kolek Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address, 773*ea22c4cfSJozef Kolek this, STI); 774*ea22c4cfSJozef Kolek if (Result != MCDisassembler::Fail) { 775*ea22c4cfSJozef Kolek Size = 2; 776*ea22c4cfSJozef Kolek return Result; 777*ea22c4cfSJozef Kolek } 778*ea22c4cfSJozef Kolek 779*ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true); 78071928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 78171928e68SAkira Hatanaka return MCDisassembler::Fail; 78271928e68SAkira Hatanaka 783*ea22c4cfSJozef Kolek DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); 784dde3d582SVladimir Medic // Calling the auto-generated decoder function. 7854aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, 786dde3d582SVladimir Medic this, STI); 787dde3d582SVladimir Medic if (Result != MCDisassembler::Fail) { 788dde3d582SVladimir Medic Size = 4; 789dde3d582SVladimir Medic return Result; 790dde3d582SVladimir Medic } 791dde3d582SVladimir Medic return MCDisassembler::Fail; 792dde3d582SVladimir Medic } 793dde3d582SVladimir Medic 794*ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); 795*ea22c4cfSJozef Kolek if (Result == MCDisassembler::Fail) 796*ea22c4cfSJozef Kolek return MCDisassembler::Fail; 797*ea22c4cfSJozef Kolek 798c171f65aSDaniel Sanders if (hasCOP3()) { 799c171f65aSDaniel Sanders DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n"); 800c171f65aSDaniel Sanders Result = 8014aa6bea7SRafael Espindola decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI); 802c171f65aSDaniel Sanders if (Result != MCDisassembler::Fail) { 803c171f65aSDaniel Sanders Size = 4; 804c171f65aSDaniel Sanders return Result; 805c171f65aSDaniel Sanders } 806c171f65aSDaniel Sanders } 807c171f65aSDaniel Sanders 808c171f65aSDaniel Sanders if (hasMips32r6() && isGP64()) { 8090fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n"); 8104aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn, 8110fa60416SDaniel Sanders Address, this, STI); 8120fa60416SDaniel Sanders if (Result != MCDisassembler::Fail) { 8130fa60416SDaniel Sanders Size = 4; 8140fa60416SDaniel Sanders return Result; 8150fa60416SDaniel Sanders } 8160fa60416SDaniel Sanders } 8170fa60416SDaniel Sanders 818c171f65aSDaniel Sanders if (hasMips32r6()) { 8190fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n"); 8204aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn, 8215c582b2fSDaniel Sanders Address, this, STI); 8225c582b2fSDaniel Sanders if (Result != MCDisassembler::Fail) { 8235c582b2fSDaniel Sanders Size = 4; 8245c582b2fSDaniel Sanders return Result; 8255c582b2fSDaniel Sanders } 8265c582b2fSDaniel Sanders } 8275c582b2fSDaniel Sanders 8280fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n"); 82971928e68SAkira Hatanaka // Calling the auto-generated decoder function. 8304aa6bea7SRafael Espindola Result = 8314aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI); 83271928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 83371928e68SAkira Hatanaka Size = 4; 83471928e68SAkira Hatanaka return Result; 83571928e68SAkira Hatanaka } 83671928e68SAkira Hatanaka 83771928e68SAkira Hatanaka return MCDisassembler::Fail; 83871928e68SAkira Hatanaka } 83971928e68SAkira Hatanaka 8404aa6bea7SRafael Espindola DecodeStatus Mips64Disassembler::getInstruction(MCInst &Instr, uint64_t &Size, 8417fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 84271928e68SAkira Hatanaka uint64_t Address, 8434aa6bea7SRafael Espindola raw_ostream &VStream, 8444aa6bea7SRafael Espindola raw_ostream &CStream) const { 84571928e68SAkira Hatanaka uint32_t Insn; 84671928e68SAkira Hatanaka 8474aa6bea7SRafael Espindola DecodeStatus Result = 8487fc5b874SRafael Espindola readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); 84971928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 85071928e68SAkira Hatanaka return MCDisassembler::Fail; 85171928e68SAkira Hatanaka 85271928e68SAkira Hatanaka // Calling the auto-generated decoder function. 8534aa6bea7SRafael Espindola Result = 8544aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips6432, Instr, Insn, Address, this, STI); 85571928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 85671928e68SAkira Hatanaka Size = 4; 85771928e68SAkira Hatanaka return Result; 85871928e68SAkira Hatanaka } 85971928e68SAkira Hatanaka // If we fail to decode in Mips64 decoder space we can try in Mips32 8604aa6bea7SRafael Espindola Result = 8614aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI); 86271928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 86371928e68SAkira Hatanaka Size = 4; 86471928e68SAkira Hatanaka return Result; 86571928e68SAkira Hatanaka } 86671928e68SAkira Hatanaka 86771928e68SAkira Hatanaka return MCDisassembler::Fail; 86871928e68SAkira Hatanaka } 86971928e68SAkira Hatanaka 870ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 871ec8a5490SReed Kotler unsigned RegNo, 872ec8a5490SReed Kotler uint64_t Address, 873ec8a5490SReed Kotler const void *Decoder) { 874ec8a5490SReed Kotler 875ec8a5490SReed Kotler return MCDisassembler::Fail; 876ec8a5490SReed Kotler 877ec8a5490SReed Kotler } 878ec8a5490SReed Kotler 87913e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 88071928e68SAkira Hatanaka unsigned RegNo, 88171928e68SAkira Hatanaka uint64_t Address, 88271928e68SAkira Hatanaka const void *Decoder) { 88371928e68SAkira Hatanaka 88471928e68SAkira Hatanaka if (RegNo > 31) 88571928e68SAkira Hatanaka return MCDisassembler::Fail; 88671928e68SAkira Hatanaka 88713e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); 8889bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 88971928e68SAkira Hatanaka return MCDisassembler::Success; 89071928e68SAkira Hatanaka } 89171928e68SAkira Hatanaka 892b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, 893b0852e54SZoran Jovanovic unsigned RegNo, 894b0852e54SZoran Jovanovic uint64_t Address, 895b0852e54SZoran Jovanovic const void *Decoder) { 896*ea22c4cfSJozef Kolek if (RegNo > 7) 897b0852e54SZoran Jovanovic return MCDisassembler::Fail; 898*ea22c4cfSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo); 899*ea22c4cfSJozef Kolek Inst.addOperand(MCOperand::CreateReg(Reg)); 900*ea22c4cfSJozef Kolek return MCDisassembler::Success; 901b0852e54SZoran Jovanovic } 902b0852e54SZoran Jovanovic 90313e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 90471928e68SAkira Hatanaka unsigned RegNo, 90571928e68SAkira Hatanaka uint64_t Address, 90671928e68SAkira Hatanaka const void *Decoder) { 90771928e68SAkira Hatanaka if (RegNo > 31) 90871928e68SAkira Hatanaka return MCDisassembler::Fail; 90913e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); 9109bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 91171928e68SAkira Hatanaka return MCDisassembler::Success; 91271928e68SAkira Hatanaka } 91371928e68SAkira Hatanaka 9149bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 9159bfa2e2eSAkira Hatanaka unsigned RegNo, 9169bfa2e2eSAkira Hatanaka uint64_t Address, 9179bfa2e2eSAkira Hatanaka const void *Decoder) { 9189bfa2e2eSAkira Hatanaka if (static_cast<const MipsDisassembler *>(Decoder)->isN64()) 9199bfa2e2eSAkira Hatanaka return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); 9209bfa2e2eSAkira Hatanaka 9219bfa2e2eSAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 9229bfa2e2eSAkira Hatanaka } 9239bfa2e2eSAkira Hatanaka 924654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 925ecabd1a5SAkira Hatanaka unsigned RegNo, 926ecabd1a5SAkira Hatanaka uint64_t Address, 927ecabd1a5SAkira Hatanaka const void *Decoder) { 92813e6ccf3SAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 929ecabd1a5SAkira Hatanaka } 930ecabd1a5SAkira Hatanaka 93171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 93271928e68SAkira Hatanaka unsigned RegNo, 93371928e68SAkira Hatanaka uint64_t Address, 93471928e68SAkira Hatanaka const void *Decoder) { 93571928e68SAkira Hatanaka if (RegNo > 31) 93671928e68SAkira Hatanaka return MCDisassembler::Fail; 93771928e68SAkira Hatanaka 9389bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 9399bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 94071928e68SAkira Hatanaka return MCDisassembler::Success; 94171928e68SAkira Hatanaka } 94271928e68SAkira Hatanaka 94371928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 94471928e68SAkira Hatanaka unsigned RegNo, 94571928e68SAkira Hatanaka uint64_t Address, 94671928e68SAkira Hatanaka const void *Decoder) { 94771928e68SAkira Hatanaka if (RegNo > 31) 94871928e68SAkira Hatanaka return MCDisassembler::Fail; 94971928e68SAkira Hatanaka 9509bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 9519bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 95271928e68SAkira Hatanaka return MCDisassembler::Success; 95371928e68SAkira Hatanaka } 95471928e68SAkira Hatanaka 95571928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 95671928e68SAkira Hatanaka unsigned RegNo, 95771928e68SAkira Hatanaka uint64_t Address, 95871928e68SAkira Hatanaka const void *Decoder) { 959253777fdSChad Rosier if (RegNo > 31) 960253777fdSChad Rosier return MCDisassembler::Fail; 961253777fdSChad Rosier unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); 962253777fdSChad Rosier Inst.addOperand(MCOperand::CreateReg(Reg)); 96371928e68SAkira Hatanaka return MCDisassembler::Success; 96471928e68SAkira Hatanaka } 96571928e68SAkira Hatanaka 9661fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 9671fb1b8b8SAkira Hatanaka unsigned RegNo, 9681fb1b8b8SAkira Hatanaka uint64_t Address, 9691fb1b8b8SAkira Hatanaka const void *Decoder) { 9701fb1b8b8SAkira Hatanaka if (RegNo > 7) 9711fb1b8b8SAkira Hatanaka return MCDisassembler::Fail; 9721fb1b8b8SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); 9731fb1b8b8SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 9741fb1b8b8SAkira Hatanaka return MCDisassembler::Success; 9751fb1b8b8SAkira Hatanaka } 9761fb1b8b8SAkira Hatanaka 9770fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, 9780fa60416SDaniel Sanders uint64_t Address, 9790fa60416SDaniel Sanders const void *Decoder) { 9800fa60416SDaniel Sanders if (RegNo > 31) 9810fa60416SDaniel Sanders return MCDisassembler::Fail; 9820fa60416SDaniel Sanders 9830fa60416SDaniel Sanders unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo); 9840fa60416SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 9850fa60416SDaniel Sanders return MCDisassembler::Success; 9860fa60416SDaniel Sanders } 9870fa60416SDaniel Sanders 98871928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 98971928e68SAkira Hatanaka unsigned Insn, 99071928e68SAkira Hatanaka uint64_t Address, 99171928e68SAkira Hatanaka const void *Decoder) { 99271928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 993ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 994ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 9959bf2b567SAkira Hatanaka 99613e6ccf3SAkira Hatanaka Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 99713e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 99871928e68SAkira Hatanaka 99971928e68SAkira Hatanaka if(Inst.getOpcode() == Mips::SC){ 10009bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 100171928e68SAkira Hatanaka } 100271928e68SAkira Hatanaka 10039bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 10049bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 100571928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 100671928e68SAkira Hatanaka 100771928e68SAkira Hatanaka return MCDisassembler::Success; 100871928e68SAkira Hatanaka } 100971928e68SAkira Hatanaka 101092db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 101192db6b78SDaniel Sanders unsigned Insn, 101292db6b78SDaniel Sanders uint64_t Address, 101392db6b78SDaniel Sanders const void *Decoder) { 101492db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 101592db6b78SDaniel Sanders unsigned Hint = fieldFromInstruction(Insn, 16, 5); 101692db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 101792db6b78SDaniel Sanders 101892db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 101992db6b78SDaniel Sanders 102092db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 102192db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 102292db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Hint)); 102392db6b78SDaniel Sanders 102492db6b78SDaniel Sanders return MCDisassembler::Success; 102592db6b78SDaniel Sanders } 102692db6b78SDaniel Sanders 1027fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 1028fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder) { 1029fe0bf9f6SMatheus Almeida int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10)); 1030fe0bf9f6SMatheus Almeida unsigned Reg = fieldFromInstruction(Insn, 6, 5); 1031fe0bf9f6SMatheus Almeida unsigned Base = fieldFromInstruction(Insn, 11, 5); 1032fe0bf9f6SMatheus Almeida 1033fe0bf9f6SMatheus Almeida Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg); 1034fe0bf9f6SMatheus Almeida Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1035fe0bf9f6SMatheus Almeida 1036fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Reg)); 1037fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Base)); 10386b59c449SMatheus Almeida 10396b59c449SMatheus Almeida // The immediate field of an LD/ST instruction is scaled which means it must 10406b59c449SMatheus Almeida // be multiplied (when decoding) by the size (in bytes) of the instructions' 10416b59c449SMatheus Almeida // data format. 10426b59c449SMatheus Almeida // .b - 1 byte 10436b59c449SMatheus Almeida // .h - 2 bytes 10446b59c449SMatheus Almeida // .w - 4 bytes 10456b59c449SMatheus Almeida // .d - 8 bytes 10466b59c449SMatheus Almeida switch(Inst.getOpcode()) 10476b59c449SMatheus Almeida { 10486b59c449SMatheus Almeida default: 10496b59c449SMatheus Almeida assert (0 && "Unexpected instruction"); 10506b59c449SMatheus Almeida return MCDisassembler::Fail; 10516b59c449SMatheus Almeida break; 10526b59c449SMatheus Almeida case Mips::LD_B: 10536b59c449SMatheus Almeida case Mips::ST_B: 1054fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateImm(Offset)); 10556b59c449SMatheus Almeida break; 10566b59c449SMatheus Almeida case Mips::LD_H: 10576b59c449SMatheus Almeida case Mips::ST_H: 1058d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(Offset * 2)); 10596b59c449SMatheus Almeida break; 10606b59c449SMatheus Almeida case Mips::LD_W: 10616b59c449SMatheus Almeida case Mips::ST_W: 1062d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(Offset * 4)); 10636b59c449SMatheus Almeida break; 10646b59c449SMatheus Almeida case Mips::LD_D: 10656b59c449SMatheus Almeida case Mips::ST_D: 1066d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(Offset * 8)); 10676b59c449SMatheus Almeida break; 10686b59c449SMatheus Almeida } 1069fe0bf9f6SMatheus Almeida 1070fe0bf9f6SMatheus Almeida return MCDisassembler::Success; 1071fe0bf9f6SMatheus Almeida } 1072fe0bf9f6SMatheus Almeida 1073dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 1074dde3d582SVladimir Medic unsigned Insn, 1075dde3d582SVladimir Medic uint64_t Address, 1076dde3d582SVladimir Medic const void *Decoder) { 1077dde3d582SVladimir Medic int Offset = SignExtend32<12>(Insn & 0x0fff); 1078dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1079dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1080dde3d582SVladimir Medic 1081dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1082dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1083dde3d582SVladimir Medic 1084a4c4b5fcSZoran Jovanovic switch (Inst.getOpcode()) { 1085a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 1086a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 1087a4c4b5fcSZoran Jovanovic if (DecodeRegListOperand(Inst, Insn, Address, Decoder) 1088a4c4b5fcSZoran Jovanovic == MCDisassembler::Fail) 1089a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 1090a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Base)); 1091a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(Offset)); 1092a4c4b5fcSZoran Jovanovic break; 1093a4c4b5fcSZoran Jovanovic case Mips::SC_MM: 1094285cc289SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Reg)); 1095a4c4b5fcSZoran Jovanovic // fallthrough 1096a4c4b5fcSZoran Jovanovic default: 1097dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Reg)); 1098dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Base)); 1099dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Offset)); 1100a4c4b5fcSZoran Jovanovic } 1101dde3d582SVladimir Medic 1102dde3d582SVladimir Medic return MCDisassembler::Success; 1103dde3d582SVladimir Medic } 1104dde3d582SVladimir Medic 1105dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 1106dde3d582SVladimir Medic unsigned Insn, 1107dde3d582SVladimir Medic uint64_t Address, 1108dde3d582SVladimir Medic const void *Decoder) { 1109dde3d582SVladimir Medic int Offset = SignExtend32<16>(Insn & 0xffff); 1110dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1111dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1112dde3d582SVladimir Medic 1113dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1114dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1115dde3d582SVladimir Medic 1116dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Reg)); 1117dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Base)); 1118dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Offset)); 1119dde3d582SVladimir Medic 1120dde3d582SVladimir Medic return MCDisassembler::Success; 1121dde3d582SVladimir Medic } 1122dde3d582SVladimir Medic 112371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, 112471928e68SAkira Hatanaka unsigned Insn, 112571928e68SAkira Hatanaka uint64_t Address, 112671928e68SAkira Hatanaka const void *Decoder) { 112771928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1128ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1129ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 113071928e68SAkira Hatanaka 11319bf2b567SAkira Hatanaka Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 113213e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 11339bf2b567SAkira Hatanaka 11349bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 11359bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 113671928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 113771928e68SAkira Hatanaka 113871928e68SAkira Hatanaka return MCDisassembler::Success; 113971928e68SAkira Hatanaka } 114071928e68SAkira Hatanaka 114192db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, 114292db6b78SDaniel Sanders unsigned Insn, 114392db6b78SDaniel Sanders uint64_t Address, 114492db6b78SDaniel Sanders const void *Decoder) { 114592db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 114692db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 114792db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 114892db6b78SDaniel Sanders 114992db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); 115092db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 115192db6b78SDaniel Sanders 115292db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 115392db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 115492db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 115592db6b78SDaniel Sanders 115692db6b78SDaniel Sanders return MCDisassembler::Success; 115792db6b78SDaniel Sanders } 115892db6b78SDaniel Sanders 115992db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, 116092db6b78SDaniel Sanders unsigned Insn, 116192db6b78SDaniel Sanders uint64_t Address, 116292db6b78SDaniel Sanders const void *Decoder) { 116392db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 116492db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 116592db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 116692db6b78SDaniel Sanders 116792db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP3RegClassID, Reg); 116892db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 116992db6b78SDaniel Sanders 117092db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 117192db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 117292db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 117392db6b78SDaniel Sanders 117492db6b78SDaniel Sanders return MCDisassembler::Success; 117592db6b78SDaniel Sanders } 117692db6b78SDaniel Sanders 11776a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 11786a803f61SDaniel Sanders unsigned Insn, 11796a803f61SDaniel Sanders uint64_t Address, 11806a803f61SDaniel Sanders const void *Decoder) { 11816a803f61SDaniel Sanders int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff); 11826a803f61SDaniel Sanders unsigned Rt = fieldFromInstruction(Insn, 16, 5); 11836a803f61SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 11846a803f61SDaniel Sanders 11856a803f61SDaniel Sanders Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt); 11866a803f61SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 11876a803f61SDaniel Sanders 11886a803f61SDaniel Sanders if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){ 11896a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Rt)); 11906a803f61SDaniel Sanders } 11916a803f61SDaniel Sanders 11926a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Rt)); 11936a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 11946a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 11956a803f61SDaniel Sanders 11966a803f61SDaniel Sanders return MCDisassembler::Success; 11976a803f61SDaniel Sanders } 119871928e68SAkira Hatanaka 119971928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 120071928e68SAkira Hatanaka unsigned RegNo, 120171928e68SAkira Hatanaka uint64_t Address, 120271928e68SAkira Hatanaka const void *Decoder) { 120371928e68SAkira Hatanaka // Currently only hardware register 29 is supported. 120471928e68SAkira Hatanaka if (RegNo != 29) 120571928e68SAkira Hatanaka return MCDisassembler::Fail; 120671928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); 120771928e68SAkira Hatanaka return MCDisassembler::Success; 120871928e68SAkira Hatanaka } 120971928e68SAkira Hatanaka 121071928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 121171928e68SAkira Hatanaka unsigned RegNo, 121271928e68SAkira Hatanaka uint64_t Address, 121371928e68SAkira Hatanaka const void *Decoder) { 12149bf2b567SAkira Hatanaka if (RegNo > 30 || RegNo %2) 121571928e68SAkira Hatanaka return MCDisassembler::Fail; 121671928e68SAkira Hatanaka 12179bf2b567SAkira Hatanaka ; 12189bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 12199bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 122071928e68SAkira Hatanaka return MCDisassembler::Success; 122171928e68SAkira Hatanaka } 122271928e68SAkira Hatanaka 122300fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 1224ecabd1a5SAkira Hatanaka unsigned RegNo, 1225ecabd1a5SAkira Hatanaka uint64_t Address, 1226ecabd1a5SAkira Hatanaka const void *Decoder) { 1227ecabd1a5SAkira Hatanaka if (RegNo >= 4) 1228ecabd1a5SAkira Hatanaka return MCDisassembler::Fail; 1229ecabd1a5SAkira Hatanaka 123000fcf2e1SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo); 1231ecabd1a5SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 1232ecabd1a5SAkira Hatanaka return MCDisassembler::Success; 1233ecabd1a5SAkira Hatanaka } 1234ecabd1a5SAkira Hatanaka 12358002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 123659bfaf77SAkira Hatanaka unsigned RegNo, 123759bfaf77SAkira Hatanaka uint64_t Address, 123859bfaf77SAkira Hatanaka const void *Decoder) { 123959bfaf77SAkira Hatanaka if (RegNo >= 4) 124059bfaf77SAkira Hatanaka return MCDisassembler::Fail; 124159bfaf77SAkira Hatanaka 12428002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo); 124359bfaf77SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 124459bfaf77SAkira Hatanaka return MCDisassembler::Success; 124559bfaf77SAkira Hatanaka } 124659bfaf77SAkira Hatanaka 12478002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 124859bfaf77SAkira Hatanaka unsigned RegNo, 124959bfaf77SAkira Hatanaka uint64_t Address, 125059bfaf77SAkira Hatanaka const void *Decoder) { 125159bfaf77SAkira Hatanaka if (RegNo >= 4) 125259bfaf77SAkira Hatanaka return MCDisassembler::Fail; 125359bfaf77SAkira Hatanaka 12548002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo); 125559bfaf77SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 125659bfaf77SAkira Hatanaka return MCDisassembler::Success; 125759bfaf77SAkira Hatanaka } 125859bfaf77SAkira Hatanaka 12593eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, 12603eb663b0SJack Carter unsigned RegNo, 12613eb663b0SJack Carter uint64_t Address, 12623eb663b0SJack Carter const void *Decoder) { 12633eb663b0SJack Carter if (RegNo > 31) 12643eb663b0SJack Carter return MCDisassembler::Fail; 12653eb663b0SJack Carter 12663eb663b0SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo); 12673eb663b0SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 12683eb663b0SJack Carter return MCDisassembler::Success; 12693eb663b0SJack Carter } 12703eb663b0SJack Carter 12715dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, 12725dc8ac92SJack Carter unsigned RegNo, 12735dc8ac92SJack Carter uint64_t Address, 12745dc8ac92SJack Carter const void *Decoder) { 12755dc8ac92SJack Carter if (RegNo > 31) 12765dc8ac92SJack Carter return MCDisassembler::Fail; 12775dc8ac92SJack Carter 12785dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo); 12795dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 12805dc8ac92SJack Carter return MCDisassembler::Success; 12815dc8ac92SJack Carter } 12825dc8ac92SJack Carter 12835dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, 12845dc8ac92SJack Carter unsigned RegNo, 12855dc8ac92SJack Carter uint64_t Address, 12865dc8ac92SJack Carter const void *Decoder) { 12875dc8ac92SJack Carter if (RegNo > 31) 12885dc8ac92SJack Carter return MCDisassembler::Fail; 12895dc8ac92SJack Carter 12905dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo); 12915dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 12925dc8ac92SJack Carter return MCDisassembler::Success; 12935dc8ac92SJack Carter } 12945dc8ac92SJack Carter 12955dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, 12965dc8ac92SJack Carter unsigned RegNo, 12975dc8ac92SJack Carter uint64_t Address, 12985dc8ac92SJack Carter const void *Decoder) { 12995dc8ac92SJack Carter if (RegNo > 31) 13005dc8ac92SJack Carter return MCDisassembler::Fail; 13015dc8ac92SJack Carter 13025dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo); 13035dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 13045dc8ac92SJack Carter return MCDisassembler::Success; 13055dc8ac92SJack Carter } 13065dc8ac92SJack Carter 1307a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, 1308a591fdc6SMatheus Almeida unsigned RegNo, 1309a591fdc6SMatheus Almeida uint64_t Address, 1310a591fdc6SMatheus Almeida const void *Decoder) { 1311a591fdc6SMatheus Almeida if (RegNo > 7) 1312a591fdc6SMatheus Almeida return MCDisassembler::Fail; 1313a591fdc6SMatheus Almeida 1314a591fdc6SMatheus Almeida unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo); 1315a591fdc6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Reg)); 1316a591fdc6SMatheus Almeida return MCDisassembler::Success; 1317a591fdc6SMatheus Almeida } 1318a591fdc6SMatheus Almeida 13192a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, 13202a83d680SDaniel Sanders unsigned RegNo, 13212a83d680SDaniel Sanders uint64_t Address, 13222a83d680SDaniel Sanders const void *Decoder) { 13232a83d680SDaniel Sanders if (RegNo > 31) 13242a83d680SDaniel Sanders return MCDisassembler::Fail; 13252a83d680SDaniel Sanders 13262a83d680SDaniel Sanders unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo); 13272a83d680SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 13282a83d680SDaniel Sanders return MCDisassembler::Success; 13292a83d680SDaniel Sanders } 13302a83d680SDaniel Sanders 133171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 133271928e68SAkira Hatanaka unsigned Offset, 133371928e68SAkira Hatanaka uint64_t Address, 133471928e68SAkira Hatanaka const void *Decoder) { 1335d37bab61SAlexey Samsonov int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4; 133671928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 133771928e68SAkira Hatanaka return MCDisassembler::Success; 133871928e68SAkira Hatanaka } 133971928e68SAkira Hatanaka 134071928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 134171928e68SAkira Hatanaka unsigned Insn, 134271928e68SAkira Hatanaka uint64_t Address, 134371928e68SAkira Hatanaka const void *Decoder) { 134471928e68SAkira Hatanaka 1345ecaef49fSJim Grosbach unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 134671928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 134771928e68SAkira Hatanaka return MCDisassembler::Success; 134871928e68SAkira Hatanaka } 134971928e68SAkira Hatanaka 13503c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst, 13513c8869dcSZoran Jovanovic unsigned Offset, 13523c8869dcSZoran Jovanovic uint64_t Address, 13533c8869dcSZoran Jovanovic const void *Decoder) { 1354d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<21>(Offset) * 4; 13553c8869dcSZoran Jovanovic 13563c8869dcSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 13573c8869dcSZoran Jovanovic return MCDisassembler::Success; 13583c8869dcSZoran Jovanovic } 13593c8869dcSZoran Jovanovic 13603c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst, 13613c8869dcSZoran Jovanovic unsigned Offset, 13623c8869dcSZoran Jovanovic uint64_t Address, 13633c8869dcSZoran Jovanovic const void *Decoder) { 1364d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<26>(Offset) * 4; 13653c8869dcSZoran Jovanovic 13663c8869dcSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 13673c8869dcSZoran Jovanovic return MCDisassembler::Success; 13683c8869dcSZoran Jovanovic } 13693c8869dcSZoran Jovanovic 13708a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 13718a80aa76SZoran Jovanovic unsigned Offset, 13728a80aa76SZoran Jovanovic uint64_t Address, 13738a80aa76SZoran Jovanovic const void *Decoder) { 1374d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<16>(Offset) * 2; 13758a80aa76SZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 13768a80aa76SZoran Jovanovic return MCDisassembler::Success; 13778a80aa76SZoran Jovanovic } 13788a80aa76SZoran Jovanovic 1379507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 1380507e084aSZoran Jovanovic unsigned Insn, 1381507e084aSZoran Jovanovic uint64_t Address, 1382507e084aSZoran Jovanovic const void *Decoder) { 1383507e084aSZoran Jovanovic unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1; 1384507e084aSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 1385507e084aSZoran Jovanovic return MCDisassembler::Success; 1386507e084aSZoran Jovanovic } 138771928e68SAkira Hatanaka 138871928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 138971928e68SAkira Hatanaka unsigned Insn, 139071928e68SAkira Hatanaka uint64_t Address, 139171928e68SAkira Hatanaka const void *Decoder) { 139271928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); 139371928e68SAkira Hatanaka return MCDisassembler::Success; 139471928e68SAkira Hatanaka } 139571928e68SAkira Hatanaka 1396779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst, 1397779c5937SMatheus Almeida unsigned Insn, 1398779c5937SMatheus Almeida uint64_t Address, 1399779c5937SMatheus Almeida const void *Decoder) { 1400779c5937SMatheus Almeida // We add one to the immediate field as it was encoded as 'imm - 1'. 1401779c5937SMatheus Almeida Inst.addOperand(MCOperand::CreateImm(Insn + 1)); 1402779c5937SMatheus Almeida return MCDisassembler::Success; 1403779c5937SMatheus Almeida } 1404779c5937SMatheus Almeida 140571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 140671928e68SAkira Hatanaka unsigned Insn, 140771928e68SAkira Hatanaka uint64_t Address, 140871928e68SAkira Hatanaka const void *Decoder) { 140971928e68SAkira Hatanaka // First we need to grab the pos(lsb) from MCInst. 141071928e68SAkira Hatanaka int Pos = Inst.getOperand(2).getImm(); 141171928e68SAkira Hatanaka int Size = (int) Insn - Pos + 1; 141271928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 141371928e68SAkira Hatanaka return MCDisassembler::Success; 141471928e68SAkira Hatanaka } 141571928e68SAkira Hatanaka 141671928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 141771928e68SAkira Hatanaka unsigned Insn, 141871928e68SAkira Hatanaka uint64_t Address, 141971928e68SAkira Hatanaka const void *Decoder) { 142071928e68SAkira Hatanaka int Size = (int) Insn + 1; 142171928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 142271928e68SAkira Hatanaka return MCDisassembler::Success; 142371928e68SAkira Hatanaka } 1424b59e1a41SDaniel Sanders 1425b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 1426b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder) { 1427d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) * 4)); 1428b59e1a41SDaniel Sanders return MCDisassembler::Success; 1429b59e1a41SDaniel Sanders } 14302855142aSZoran Jovanovic 14312855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 14322855142aSZoran Jovanovic uint64_t Address, const void *Decoder) { 1433d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) * 8)); 14342855142aSZoran Jovanovic return MCDisassembler::Success; 14352855142aSZoran Jovanovic } 1436a4c4b5fcSZoran Jovanovic 1437a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, 1438a4c4b5fcSZoran Jovanovic unsigned Insn, 1439a4c4b5fcSZoran Jovanovic uint64_t Address, 1440a4c4b5fcSZoran Jovanovic const void *Decoder) { 1441a4c4b5fcSZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5, 1442a4c4b5fcSZoran Jovanovic Mips::S6, Mips::FP}; 1443a4c4b5fcSZoran Jovanovic unsigned RegNum; 1444a4c4b5fcSZoran Jovanovic 1445a4c4b5fcSZoran Jovanovic unsigned RegLst = fieldFromInstruction(Insn, 21, 5); 1446a4c4b5fcSZoran Jovanovic // Empty register lists are not allowed. 1447a4c4b5fcSZoran Jovanovic if (RegLst == 0) 1448a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 1449a4c4b5fcSZoran Jovanovic 1450a4c4b5fcSZoran Jovanovic RegNum = RegLst & 0xf; 1451a4c4b5fcSZoran Jovanovic for (unsigned i = 0; i < RegNum; i++) 1452a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Regs[i])); 1453a4c4b5fcSZoran Jovanovic 1454a4c4b5fcSZoran Jovanovic if (RegLst & 0x10) 1455a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Mips::RA)); 1456a4c4b5fcSZoran Jovanovic 1457a4c4b5fcSZoran Jovanovic return MCDisassembler::Success; 1458a4c4b5fcSZoran Jovanovic } 1459