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 33a19216c8SDaniel Sanders class MipsDisassembler : public MCDisassembler { 34dde3d582SVladimir Medic bool IsMicroMips; 35a19216c8SDaniel Sanders bool IsBigEndian; 369bf2b567SAkira Hatanaka public: 37a19216c8SDaniel Sanders MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian) 38a19216c8SDaniel Sanders : MCDisassembler(STI, Ctx), 39db0712f9SMichael Kuperstein IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]), 40a19216c8SDaniel Sanders IsBigEndian(IsBigEndian) {} 4171928e68SAkira Hatanaka 42db0712f9SMichael Kuperstein bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; } 43db0712f9SMichael Kuperstein bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; } 44c171f65aSDaniel Sanders bool hasMips32r6() const { 45db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMips32r6]; 465c582b2fSDaniel Sanders } 475c582b2fSDaniel Sanders 48db0712f9SMichael Kuperstein bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; } 490fa60416SDaniel Sanders 503adf9b8dSKai Nacke bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; } 513adf9b8dSKai Nacke 52c171f65aSDaniel Sanders bool hasCOP3() const { 53c171f65aSDaniel Sanders // Only present in MIPS-I and MIPS-II 54c171f65aSDaniel Sanders return !hasMips32() && !hasMips3(); 55c171f65aSDaniel Sanders } 56c171f65aSDaniel Sanders 574aa6bea7SRafael Espindola DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 587fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address, 594aa6bea7SRafael Espindola raw_ostream &VStream, 604aa6bea7SRafael Espindola raw_ostream &CStream) const override; 6171928e68SAkira Hatanaka }; 6271928e68SAkira Hatanaka 63cb3e98cfSBenjamin Kramer } // end anonymous namespace 64cb3e98cfSBenjamin Kramer 6571928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them. 6671928e68SAkira Hatanaka // Definitions are further down. 6713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 6871928e68SAkira Hatanaka unsigned RegNo, 6971928e68SAkira Hatanaka uint64_t Address, 7071928e68SAkira Hatanaka const void *Decoder); 7171928e68SAkira Hatanaka 72ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 73ec8a5490SReed Kotler unsigned RegNo, 74ec8a5490SReed Kotler uint64_t Address, 75ec8a5490SReed Kotler const void *Decoder); 76ec8a5490SReed Kotler 77b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, 78b0852e54SZoran Jovanovic unsigned RegNo, 79b0852e54SZoran Jovanovic uint64_t Address, 80b0852e54SZoran Jovanovic const void *Decoder); 81b0852e54SZoran Jovanovic 821904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, 831904fa21SJozef Kolek unsigned RegNo, 841904fa21SJozef Kolek uint64_t Address, 851904fa21SJozef Kolek const void *Decoder); 861904fa21SJozef Kolek 8741688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst, 8841688679SZoran Jovanovic unsigned RegNo, 8941688679SZoran Jovanovic uint64_t Address, 9041688679SZoran Jovanovic const void *Decoder); 9141688679SZoran Jovanovic 9213e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 9371928e68SAkira Hatanaka unsigned RegNo, 9471928e68SAkira Hatanaka uint64_t Address, 9571928e68SAkira Hatanaka const void *Decoder); 9671928e68SAkira Hatanaka 979bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 989bfa2e2eSAkira Hatanaka unsigned Insn, 999bfa2e2eSAkira Hatanaka uint64_t Address, 1009bfa2e2eSAkira Hatanaka const void *Decoder); 1019bfa2e2eSAkira Hatanaka 102654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 103ecabd1a5SAkira Hatanaka unsigned RegNo, 104ecabd1a5SAkira Hatanaka uint64_t Address, 105ecabd1a5SAkira Hatanaka const void *Decoder); 106ecabd1a5SAkira Hatanaka 10771928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 10871928e68SAkira Hatanaka unsigned RegNo, 10971928e68SAkira Hatanaka uint64_t Address, 11071928e68SAkira Hatanaka const void *Decoder); 11171928e68SAkira Hatanaka 11271928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 11371928e68SAkira Hatanaka unsigned RegNo, 11471928e68SAkira Hatanaka uint64_t Address, 11571928e68SAkira Hatanaka const void *Decoder); 11671928e68SAkira Hatanaka 11771928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 11871928e68SAkira Hatanaka unsigned RegNo, 11971928e68SAkira Hatanaka uint64_t Address, 12071928e68SAkira Hatanaka const void *Decoder); 12171928e68SAkira Hatanaka 1221fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 1231fb1b8b8SAkira Hatanaka unsigned RegNo, 1241fb1b8b8SAkira Hatanaka uint64_t Address, 1251fb1b8b8SAkira Hatanaka const void *Decoder); 1261fb1b8b8SAkira Hatanaka 1270fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, 1280fa60416SDaniel Sanders uint64_t Address, 1290fa60416SDaniel Sanders const void *Decoder); 1300fa60416SDaniel Sanders 13171928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 13271928e68SAkira Hatanaka unsigned Insn, 13371928e68SAkira Hatanaka uint64_t Address, 13471928e68SAkira Hatanaka const void *Decoder); 13571928e68SAkira Hatanaka 13671928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 13771928e68SAkira Hatanaka unsigned RegNo, 13871928e68SAkira Hatanaka uint64_t Address, 13971928e68SAkira Hatanaka const void *Decoder); 14071928e68SAkira Hatanaka 14100fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 142ecabd1a5SAkira Hatanaka unsigned RegNo, 143ecabd1a5SAkira Hatanaka uint64_t Address, 144ecabd1a5SAkira Hatanaka const void *Decoder); 145ecabd1a5SAkira Hatanaka 1468002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 14759bfaf77SAkira Hatanaka unsigned RegNo, 14859bfaf77SAkira Hatanaka uint64_t Address, 14959bfaf77SAkira Hatanaka const void *Decoder); 15059bfaf77SAkira Hatanaka 1518002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 15259bfaf77SAkira Hatanaka unsigned RegNo, 15359bfaf77SAkira Hatanaka uint64_t Address, 15459bfaf77SAkira Hatanaka const void *Decoder); 15559bfaf77SAkira Hatanaka 1563eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, 1573eb663b0SJack Carter unsigned RegNo, 1583eb663b0SJack Carter uint64_t Address, 1593eb663b0SJack Carter const void *Decoder); 1603eb663b0SJack Carter 1615dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, 1625dc8ac92SJack Carter unsigned RegNo, 1635dc8ac92SJack Carter uint64_t Address, 1645dc8ac92SJack Carter const void *Decoder); 1655dc8ac92SJack Carter 1665dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, 1675dc8ac92SJack Carter unsigned RegNo, 1685dc8ac92SJack Carter uint64_t Address, 1695dc8ac92SJack Carter const void *Decoder); 1705dc8ac92SJack Carter 1715dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, 1725dc8ac92SJack Carter unsigned RegNo, 1735dc8ac92SJack Carter uint64_t Address, 1745dc8ac92SJack Carter const void *Decoder); 1755dc8ac92SJack Carter 176a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, 177a591fdc6SMatheus Almeida unsigned RegNo, 178a591fdc6SMatheus Almeida uint64_t Address, 179a591fdc6SMatheus Almeida const void *Decoder); 180a591fdc6SMatheus Almeida 181a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, 182a3134faeSDaniel Sanders unsigned RegNo, 183a3134faeSDaniel Sanders uint64_t Address, 184a3134faeSDaniel Sanders const void *Decoder); 185a3134faeSDaniel Sanders 1862a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, 1872a83d680SDaniel Sanders unsigned RegNo, 1882a83d680SDaniel Sanders uint64_t Address, 1892a83d680SDaniel Sanders const void *Decoder); 1902a83d680SDaniel Sanders 19171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 19271928e68SAkira Hatanaka unsigned Offset, 19371928e68SAkira Hatanaka uint64_t Address, 19471928e68SAkira Hatanaka const void *Decoder); 19571928e68SAkira Hatanaka 19671928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 19771928e68SAkira Hatanaka unsigned Insn, 19871928e68SAkira Hatanaka uint64_t Address, 19971928e68SAkira Hatanaka const void *Decoder); 20071928e68SAkira Hatanaka 2013c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst, 2023c8869dcSZoran Jovanovic unsigned Offset, 2033c8869dcSZoran Jovanovic uint64_t Address, 2043c8869dcSZoran Jovanovic const void *Decoder); 2053c8869dcSZoran Jovanovic 2063c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst, 2073c8869dcSZoran Jovanovic unsigned Offset, 2083c8869dcSZoran Jovanovic uint64_t Address, 2093c8869dcSZoran Jovanovic const void *Decoder); 2103c8869dcSZoran Jovanovic 2119761e96bSJozef Kolek // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is 2129761e96bSJozef Kolek // shifted left by 1 bit. 2139761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, 2149761e96bSJozef Kolek unsigned Offset, 2159761e96bSJozef Kolek uint64_t Address, 2169761e96bSJozef Kolek const void *Decoder); 2179761e96bSJozef Kolek 2185cfebddeSJozef Kolek // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is 2195cfebddeSJozef Kolek // shifted left by 1 bit. 2205cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, 2215cfebddeSJozef Kolek unsigned Offset, 2225cfebddeSJozef Kolek uint64_t Address, 2235cfebddeSJozef Kolek const void *Decoder); 2245cfebddeSJozef Kolek 2258a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is 2268a80aa76SZoran Jovanovic // shifted left by 1 bit. 2278a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 2288a80aa76SZoran Jovanovic unsigned Offset, 2298a80aa76SZoran Jovanovic uint64_t Address, 2308a80aa76SZoran Jovanovic const void *Decoder); 2318a80aa76SZoran Jovanovic 232507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is 233507e084aSZoran Jovanovic // shifted left by 1 bit. 234507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 235507e084aSZoran Jovanovic unsigned Insn, 236507e084aSZoran Jovanovic uint64_t Address, 237507e084aSZoran Jovanovic const void *Decoder); 238507e084aSZoran Jovanovic 23971928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 24071928e68SAkira Hatanaka unsigned Insn, 24171928e68SAkira Hatanaka uint64_t Address, 24271928e68SAkira Hatanaka const void *Decoder); 24371928e68SAkira Hatanaka 244e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst, 245e4e83a7bSDaniel Sanders unsigned Insn, 246e4e83a7bSDaniel Sanders uint64_t Address, 247e4e83a7bSDaniel Sanders const void *Decoder); 248e4e83a7bSDaniel Sanders 2493c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte9(MCInst &Inst, 2503c88fbd3SHrvoje Varga unsigned Insn, 2513c88fbd3SHrvoje Varga uint64_t Address, 2523c88fbd3SHrvoje Varga const void *Decoder); 2533c88fbd3SHrvoje Varga 2543c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst, 2553c88fbd3SHrvoje Varga unsigned Insn, 2563c88fbd3SHrvoje Varga uint64_t Address, 2573c88fbd3SHrvoje Varga const void *Decoder); 2583c88fbd3SHrvoje Varga 25992db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 26092db6b78SDaniel Sanders unsigned Insn, 26192db6b78SDaniel Sanders uint64_t Address, 26292db6b78SDaniel Sanders const void *Decoder); 26392db6b78SDaniel Sanders 264e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, 265df464ae2SVladimir Medic unsigned Insn, 266df464ae2SVladimir Medic uint64_t Address, 267df464ae2SVladimir Medic const void *Decoder); 268df464ae2SVladimir Medic 269ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst, 270ab6d1cceSJozef Kolek unsigned Insn, 271ab6d1cceSJozef Kolek uint64_t Address, 272ab6d1cceSJozef Kolek const void *Decoder); 273ab6d1cceSJozef Kolek 2749eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst, 2759eaa30d2SZoran Jovanovic unsigned Insn, 2769eaa30d2SZoran Jovanovic uint64_t Address, 2779eaa30d2SZoran Jovanovic const void *Decoder); 2789eaa30d2SZoran Jovanovic 279d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst, 280d9790793SZoran Jovanovic unsigned Insn, 281d9790793SZoran Jovanovic uint64_t Address, 282d9790793SZoran Jovanovic const void *Decoder); 283d9790793SZoran Jovanovic 284b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 285b4484d62SDaniel Sanders unsigned Insn, 286b4484d62SDaniel Sanders uint64_t Address, 287b4484d62SDaniel Sanders const void *Decoder); 288b4484d62SDaniel Sanders 28918148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst, 29018148671SHrvoje Varga unsigned Insn, 29118148671SHrvoje Varga uint64_t Address, 29218148671SHrvoje Varga const void *Decoder); 29318148671SHrvoje Varga 294fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 295fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder); 296fe0bf9f6SMatheus Almeida 297315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 298315e7ecaSJozef Kolek unsigned Insn, 299315e7ecaSJozef Kolek uint64_t Address, 300315e7ecaSJozef Kolek const void *Decoder); 301315e7ecaSJozef Kolek 30212c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, 30312c6982bSJozef Kolek unsigned Insn, 30412c6982bSJozef Kolek uint64_t Address, 30512c6982bSJozef Kolek const void *Decoder); 30612c6982bSJozef Kolek 307e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, 308e10a02ecSJozef Kolek unsigned Insn, 309e10a02ecSJozef Kolek uint64_t Address, 310e10a02ecSJozef Kolek const void *Decoder); 311e10a02ecSJozef Kolek 312d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, 313d68d424aSJozef Kolek unsigned Insn, 314d68d424aSJozef Kolek uint64_t Address, 315d68d424aSJozef Kolek const void *Decoder); 316d68d424aSJozef Kolek 317a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst, 318a6593ff6SZoran Jovanovic unsigned Insn, 319a6593ff6SZoran Jovanovic uint64_t Address, 320a6593ff6SZoran Jovanovic const void *Decoder); 321a6593ff6SZoran Jovanovic 322dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 323dde3d582SVladimir Medic unsigned Insn, 324dde3d582SVladimir Medic uint64_t Address, 325dde3d582SVladimir Medic const void *Decoder); 326dde3d582SVladimir Medic 327dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 328dde3d582SVladimir Medic unsigned Insn, 329dde3d582SVladimir Medic uint64_t Address, 330dde3d582SVladimir Medic const void *Decoder); 331dde3d582SVladimir Medic 33271928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 33371928e68SAkira Hatanaka uint64_t Address, 33471928e68SAkira Hatanaka const void *Decoder); 33571928e68SAkira Hatanaka 33692db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, 33792db6b78SDaniel Sanders uint64_t Address, 33892db6b78SDaniel Sanders const void *Decoder); 33992db6b78SDaniel Sanders 34092db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, 34192db6b78SDaniel Sanders uint64_t Address, 34292db6b78SDaniel Sanders const void *Decoder); 34392db6b78SDaniel Sanders 344435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn, 345435cf8a4SVladimir Medic uint64_t Address, 346435cf8a4SVladimir Medic const void *Decoder); 347435cf8a4SVladimir Medic 3486a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 3496a803f61SDaniel Sanders unsigned Insn, 3506a803f61SDaniel Sanders uint64_t Address, 3516a803f61SDaniel Sanders const void *Decoder); 3526a803f61SDaniel Sanders 353aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 354aa2b9278SJozef Kolek unsigned Value, 355aa2b9278SJozef Kolek uint64_t Address, 356aa2b9278SJozef Kolek const void *Decoder); 357aa2b9278SJozef Kolek 358aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, 359aa2b9278SJozef Kolek unsigned Value, 360aa2b9278SJozef Kolek uint64_t Address, 361aa2b9278SJozef Kolek const void *Decoder); 362aa2b9278SJozef Kolek 363aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst, 364aa2b9278SJozef Kolek unsigned Value, 365aa2b9278SJozef Kolek uint64_t Address, 366aa2b9278SJozef Kolek const void *Decoder); 367aa2b9278SJozef Kolek 3686b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, 3696b28f09dSZoran Jovanovic unsigned Value, 3706b28f09dSZoran Jovanovic uint64_t Address, 3716b28f09dSZoran Jovanovic const void *Decoder); 3726b28f09dSZoran Jovanovic 373aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst, 374aa2b9278SJozef Kolek unsigned Value, 375aa2b9278SJozef Kolek uint64_t Address, 376aa2b9278SJozef Kolek const void *Decoder); 377aa2b9278SJozef Kolek 37871928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 37971928e68SAkira Hatanaka unsigned Insn, 38071928e68SAkira Hatanaka uint64_t Address, 38171928e68SAkira Hatanaka const void *Decoder); 38271928e68SAkira Hatanaka 383ea4f653dSDaniel Sanders template <unsigned Bits, int Offset> 384ea4f653dSDaniel Sanders static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value, 385ea4f653dSDaniel Sanders uint64_t Address, const void *Decoder); 386779c5937SMatheus Almeida 38771928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 38871928e68SAkira Hatanaka unsigned Insn, 38971928e68SAkira Hatanaka uint64_t Address, 39071928e68SAkira Hatanaka const void *Decoder); 39171928e68SAkira Hatanaka 39271928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 39371928e68SAkira Hatanaka unsigned Insn, 39471928e68SAkira Hatanaka uint64_t Address, 39571928e68SAkira Hatanaka const void *Decoder); 39671928e68SAkira Hatanaka 397b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 398b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder); 399b59e1a41SDaniel Sanders 4002855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 4012855142aSZoran Jovanovic uint64_t Address, const void *Decoder); 4022855142aSZoran Jovanovic 403b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 404b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 405b682ddf3SVladimir Medic 406b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 407b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 408b682ddf3SVladimir Medic 409b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, 410b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 411b682ddf3SVladimir Medic 4122c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, 4132c6d7320SJozef Kolek uint64_t Address, const void *Decoder); 4142c6d7320SJozef Kolek 415b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't 416b50ccf8eSDaniel Sanders /// handle. 417b50ccf8eSDaniel Sanders template <typename InsnType> 418b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 419b50ccf8eSDaniel Sanders const void *Decoder); 4205c582b2fSDaniel Sanders 4215c582b2fSDaniel Sanders template <typename InsnType> 4225c582b2fSDaniel Sanders static DecodeStatus 4235c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4245c582b2fSDaniel Sanders const void *Decoder); 4255c582b2fSDaniel Sanders 4265c582b2fSDaniel Sanders template <typename InsnType> 4275c582b2fSDaniel Sanders static DecodeStatus 4285c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4295c582b2fSDaniel Sanders const void *Decoder); 4305c582b2fSDaniel Sanders 4315c582b2fSDaniel Sanders template <typename InsnType> 4325c582b2fSDaniel Sanders static DecodeStatus 4335c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4345c582b2fSDaniel Sanders const void *Decoder); 4355c582b2fSDaniel Sanders 4365c582b2fSDaniel Sanders template <typename InsnType> 4375c582b2fSDaniel Sanders static DecodeStatus 4385c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4395c582b2fSDaniel Sanders const void *Decoder); 4405c582b2fSDaniel Sanders 4415c582b2fSDaniel Sanders template <typename InsnType> 4425c582b2fSDaniel Sanders static DecodeStatus 4435c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4445c582b2fSDaniel Sanders const void *Decoder); 4455c582b2fSDaniel Sanders 44628a0ca07SZoran Jovanovic template <typename InsnType> 44728a0ca07SZoran Jovanovic static DecodeStatus 44828a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 44928a0ca07SZoran Jovanovic const void *Decoder); 45028a0ca07SZoran Jovanovic 451a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn, 452a4c4b5fcSZoran Jovanovic uint64_t Address, 453a4c4b5fcSZoran Jovanovic const void *Decoder); 454a4c4b5fcSZoran Jovanovic 455f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 456f9a02500SZoran Jovanovic uint64_t Address, 457f9a02500SZoran Jovanovic const void *Decoder); 458f9a02500SZoran Jovanovic 45941688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn, 46041688679SZoran Jovanovic uint64_t Address, 46141688679SZoran Jovanovic const void *Decoder); 46241688679SZoran Jovanovic 46371928e68SAkira Hatanaka namespace llvm { 46471928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 46571928e68SAkira Hatanaka TheMips64elTarget; 46671928e68SAkira Hatanaka } 46771928e68SAkira Hatanaka 46871928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler( 46971928e68SAkira Hatanaka const Target &T, 470a1bc0f56SLang Hames const MCSubtargetInfo &STI, 471a1bc0f56SLang Hames MCContext &Ctx) { 472a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, true); 47371928e68SAkira Hatanaka } 47471928e68SAkira Hatanaka 47571928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler( 47671928e68SAkira Hatanaka const Target &T, 477a1bc0f56SLang Hames const MCSubtargetInfo &STI, 478a1bc0f56SLang Hames MCContext &Ctx) { 479a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, false); 48071928e68SAkira Hatanaka } 48171928e68SAkira Hatanaka 48271928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() { 48371928e68SAkira Hatanaka // Register the disassembler. 48471928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 48571928e68SAkira Hatanaka createMipsDisassembler); 48671928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 48771928e68SAkira Hatanaka createMipselDisassembler); 48871928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64Target, 489a19216c8SDaniel Sanders createMipsDisassembler); 49071928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 491a19216c8SDaniel Sanders createMipselDisassembler); 49271928e68SAkira Hatanaka } 49371928e68SAkira Hatanaka 49471928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc" 49571928e68SAkira Hatanaka 4965c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 497a19216c8SDaniel Sanders const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D); 4985c582b2fSDaniel Sanders const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo(); 4995c582b2fSDaniel Sanders return *(RegInfo->getRegClass(RC).begin() + RegNo); 5005c582b2fSDaniel Sanders } 5015c582b2fSDaniel Sanders 502b50ccf8eSDaniel Sanders template <typename InsnType> 503b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 504b50ccf8eSDaniel Sanders const void *Decoder) { 505b50ccf8eSDaniel Sanders typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *); 506b50ccf8eSDaniel Sanders // The size of the n field depends on the element size 507b50ccf8eSDaniel Sanders // The register class also depends on this. 508b50ccf8eSDaniel Sanders InsnType tmp = fieldFromInstruction(insn, 17, 5); 509b50ccf8eSDaniel Sanders unsigned NSize = 0; 510b50ccf8eSDaniel Sanders DecodeFN RegDecoder = nullptr; 511b50ccf8eSDaniel Sanders if ((tmp & 0x18) == 0x00) { // INSVE_B 512b50ccf8eSDaniel Sanders NSize = 4; 513b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128BRegisterClass; 514b50ccf8eSDaniel Sanders } else if ((tmp & 0x1c) == 0x10) { // INSVE_H 515b50ccf8eSDaniel Sanders NSize = 3; 516b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128HRegisterClass; 517b50ccf8eSDaniel Sanders } else if ((tmp & 0x1e) == 0x18) { // INSVE_W 518b50ccf8eSDaniel Sanders NSize = 2; 519b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128WRegisterClass; 520b50ccf8eSDaniel Sanders } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D 521b50ccf8eSDaniel Sanders NSize = 1; 522b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128DRegisterClass; 523b50ccf8eSDaniel Sanders } else 524b50ccf8eSDaniel Sanders llvm_unreachable("Invalid encoding"); 525b50ccf8eSDaniel Sanders 526b50ccf8eSDaniel Sanders assert(NSize != 0 && RegDecoder != nullptr); 527b50ccf8eSDaniel Sanders 528b50ccf8eSDaniel Sanders // $wd 529b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 6, 5); 530b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 531b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 532b50ccf8eSDaniel Sanders // $wd_in 533b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 534b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 535b50ccf8eSDaniel Sanders // $n 536b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 16, NSize); 537e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(tmp)); 538b50ccf8eSDaniel Sanders // $ws 539b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 11, 5); 540b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 541b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 542b50ccf8eSDaniel Sanders // $n2 543e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(0)); 544b50ccf8eSDaniel Sanders 545b50ccf8eSDaniel Sanders return MCDisassembler::Success; 546b50ccf8eSDaniel Sanders } 547b50ccf8eSDaniel Sanders 5485c582b2fSDaniel Sanders template <typename InsnType> 5495c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, 5505c582b2fSDaniel Sanders uint64_t Address, 5515c582b2fSDaniel Sanders const void *Decoder) { 5525c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5535c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 5545c582b2fSDaniel Sanders // ISA's instead). 5555c582b2fSDaniel Sanders // 5565c582b2fSDaniel Sanders // We have: 5575c582b2fSDaniel Sanders // 0b001000 sssss ttttt iiiiiiiiiiiiiiii 5585c582b2fSDaniel Sanders // BOVC if rs >= rt 5595c582b2fSDaniel Sanders // BEQZALC if rs == 0 && rt != 0 5605c582b2fSDaniel Sanders // BEQC if rs < rt && rs != 0 5615c582b2fSDaniel Sanders 5625c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 5635c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 564d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 5655c582b2fSDaniel Sanders bool HasRs = false; 5665c582b2fSDaniel Sanders 5675c582b2fSDaniel Sanders if (Rs >= Rt) { 5685c582b2fSDaniel Sanders MI.setOpcode(Mips::BOVC); 5695c582b2fSDaniel Sanders HasRs = true; 5705c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 5715c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQC); 5725c582b2fSDaniel Sanders HasRs = true; 5735c582b2fSDaniel Sanders } else 5745c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQZALC); 5755c582b2fSDaniel Sanders 5765c582b2fSDaniel Sanders if (HasRs) 577e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 5785c582b2fSDaniel Sanders Rs))); 5795c582b2fSDaniel Sanders 580e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 5815c582b2fSDaniel Sanders Rt))); 582e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 5835c582b2fSDaniel Sanders 5845c582b2fSDaniel Sanders return MCDisassembler::Success; 5855c582b2fSDaniel Sanders } 5865c582b2fSDaniel Sanders 5875c582b2fSDaniel Sanders template <typename InsnType> 5885c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, 5895c582b2fSDaniel Sanders uint64_t Address, 5905c582b2fSDaniel Sanders const void *Decoder) { 5915c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5925c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 5935c582b2fSDaniel Sanders // ISA's instead). 5945c582b2fSDaniel Sanders // 5955c582b2fSDaniel Sanders // We have: 5965c582b2fSDaniel Sanders // 0b011000 sssss ttttt iiiiiiiiiiiiiiii 5975c582b2fSDaniel Sanders // BNVC if rs >= rt 5985c582b2fSDaniel Sanders // BNEZALC if rs == 0 && rt != 0 5995c582b2fSDaniel Sanders // BNEC if rs < rt && rs != 0 6005c582b2fSDaniel Sanders 6015c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6025c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 603d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 6045c582b2fSDaniel Sanders bool HasRs = false; 6055c582b2fSDaniel Sanders 6065c582b2fSDaniel Sanders if (Rs >= Rt) { 6075c582b2fSDaniel Sanders MI.setOpcode(Mips::BNVC); 6085c582b2fSDaniel Sanders HasRs = true; 6095c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 6105c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEC); 6115c582b2fSDaniel Sanders HasRs = true; 6125c582b2fSDaniel Sanders } else 6135c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEZALC); 6145c582b2fSDaniel Sanders 6155c582b2fSDaniel Sanders if (HasRs) 616e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 6175c582b2fSDaniel Sanders Rs))); 6185c582b2fSDaniel Sanders 619e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 6205c582b2fSDaniel Sanders Rt))); 621e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 6225c582b2fSDaniel Sanders 6235c582b2fSDaniel Sanders return MCDisassembler::Success; 6245c582b2fSDaniel Sanders } 6255c582b2fSDaniel Sanders 6265c582b2fSDaniel Sanders template <typename InsnType> 6275c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, 6285c582b2fSDaniel Sanders uint64_t Address, 6295c582b2fSDaniel Sanders const void *Decoder) { 6305c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6315c582b2fSDaniel Sanders // (otherwise we would have matched the BLEZL instruction from the earlier 6325c582b2fSDaniel Sanders // ISA's instead). 6335c582b2fSDaniel Sanders // 6345c582b2fSDaniel Sanders // We have: 6355c582b2fSDaniel Sanders // 0b010110 sssss ttttt iiiiiiiiiiiiiiii 6365c582b2fSDaniel Sanders // Invalid if rs == 0 6375c582b2fSDaniel Sanders // BLEZC if rs == 0 && rt != 0 6385c582b2fSDaniel Sanders // BGEZC if rs == rt && rt != 0 6395c582b2fSDaniel Sanders // BGEC if rs != rt && rs != 0 && rt != 0 6405c582b2fSDaniel Sanders 6415c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6425c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 643d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 64428a0ca07SZoran Jovanovic bool HasRs = false; 6455c582b2fSDaniel Sanders 6465c582b2fSDaniel Sanders if (Rt == 0) 6475c582b2fSDaniel Sanders return MCDisassembler::Fail; 6485c582b2fSDaniel Sanders else if (Rs == 0) 6495c582b2fSDaniel Sanders MI.setOpcode(Mips::BLEZC); 6505c582b2fSDaniel Sanders else if (Rs == Rt) 6515c582b2fSDaniel Sanders MI.setOpcode(Mips::BGEZC); 65228a0ca07SZoran Jovanovic else { 65328a0ca07SZoran Jovanovic HasRs = true; 65428a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEC); 65528a0ca07SZoran Jovanovic } 65628a0ca07SZoran Jovanovic 65728a0ca07SZoran Jovanovic if (HasRs) 658e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 65928a0ca07SZoran Jovanovic Rs))); 6605c582b2fSDaniel Sanders 661e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 6625c582b2fSDaniel Sanders Rt))); 6635c582b2fSDaniel Sanders 664e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 6655c582b2fSDaniel Sanders 6665c582b2fSDaniel Sanders return MCDisassembler::Success; 6675c582b2fSDaniel Sanders } 6685c582b2fSDaniel Sanders 6695c582b2fSDaniel Sanders template <typename InsnType> 6705c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, 6715c582b2fSDaniel Sanders uint64_t Address, 6725c582b2fSDaniel Sanders const void *Decoder) { 6735c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6745c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZL instruction from the earlier 6755c582b2fSDaniel Sanders // ISA's instead). 6765c582b2fSDaniel Sanders // 6775c582b2fSDaniel Sanders // We have: 6785c582b2fSDaniel Sanders // 0b010111 sssss ttttt iiiiiiiiiiiiiiii 6795c582b2fSDaniel Sanders // Invalid if rs == 0 6805c582b2fSDaniel Sanders // BGTZC if rs == 0 && rt != 0 6815c582b2fSDaniel Sanders // BLTZC if rs == rt && rt != 0 6825c582b2fSDaniel Sanders // BLTC if rs != rt && rs != 0 && rt != 0 6835c582b2fSDaniel Sanders 6845c14b069SZoran Jovanovic bool HasRs = false; 6855c14b069SZoran Jovanovic 6865c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6875c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 688d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 6895c582b2fSDaniel Sanders 6905c582b2fSDaniel Sanders if (Rt == 0) 6915c582b2fSDaniel Sanders return MCDisassembler::Fail; 6925c582b2fSDaniel Sanders else if (Rs == 0) 6935c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZC); 6945c582b2fSDaniel Sanders else if (Rs == Rt) 6955c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZC); 6965c14b069SZoran Jovanovic else { 6975c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTC); 6985c14b069SZoran Jovanovic HasRs = true; 6995c14b069SZoran Jovanovic } 7005c14b069SZoran Jovanovic 7015c14b069SZoran Jovanovic if (HasRs) 702e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 7035c14b069SZoran Jovanovic Rs))); 7045c582b2fSDaniel Sanders 705e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 7065c582b2fSDaniel Sanders Rt))); 7075c582b2fSDaniel Sanders 708e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 7095c582b2fSDaniel Sanders 7105c582b2fSDaniel Sanders return MCDisassembler::Success; 7115c582b2fSDaniel Sanders } 7125c582b2fSDaniel Sanders 7135c582b2fSDaniel Sanders template <typename InsnType> 7145c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, 7155c582b2fSDaniel Sanders uint64_t Address, 7165c582b2fSDaniel Sanders const void *Decoder) { 7175c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 7185c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZ instruction from the earlier 7195c582b2fSDaniel Sanders // ISA's instead). 7205c582b2fSDaniel Sanders // 7215c582b2fSDaniel Sanders // We have: 7225c582b2fSDaniel Sanders // 0b000111 sssss ttttt iiiiiiiiiiiiiiii 7235c582b2fSDaniel Sanders // BGTZ if rt == 0 7245c582b2fSDaniel Sanders // BGTZALC if rs == 0 && rt != 0 7255c582b2fSDaniel Sanders // BLTZALC if rs != 0 && rs == rt 7265c582b2fSDaniel Sanders // BLTUC if rs != 0 && rs != rt 7275c582b2fSDaniel Sanders 7285c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 7295c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 730d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 7315c582b2fSDaniel Sanders bool HasRs = false; 7325c582b2fSDaniel Sanders bool HasRt = false; 7335c582b2fSDaniel Sanders 7345c582b2fSDaniel Sanders if (Rt == 0) { 7355c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZ); 7365c582b2fSDaniel Sanders HasRs = true; 7375c582b2fSDaniel Sanders } else if (Rs == 0) { 7385c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZALC); 7395c582b2fSDaniel Sanders HasRt = true; 7405c582b2fSDaniel Sanders } else if (Rs == Rt) { 7415c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZALC); 7425c582b2fSDaniel Sanders HasRs = true; 7435c14b069SZoran Jovanovic } else { 7445c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTUC); 7455c14b069SZoran Jovanovic HasRs = true; 7465c14b069SZoran Jovanovic HasRt = true; 7475c14b069SZoran Jovanovic } 7485c582b2fSDaniel Sanders 7495c582b2fSDaniel Sanders if (HasRs) 750e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 7515c582b2fSDaniel Sanders Rs))); 7525c582b2fSDaniel Sanders 7535c582b2fSDaniel Sanders if (HasRt) 754e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 7555c582b2fSDaniel Sanders Rt))); 7565c582b2fSDaniel Sanders 757e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 7585c582b2fSDaniel Sanders 7595c582b2fSDaniel Sanders return MCDisassembler::Success; 7605c582b2fSDaniel Sanders } 7615c582b2fSDaniel Sanders 76228a0ca07SZoran Jovanovic template <typename InsnType> 76328a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn, 76428a0ca07SZoran Jovanovic uint64_t Address, 76528a0ca07SZoran Jovanovic const void *Decoder) { 76628a0ca07SZoran Jovanovic // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 76728a0ca07SZoran Jovanovic // (otherwise we would have matched the BLEZL instruction from the earlier 76828a0ca07SZoran Jovanovic // ISA's instead). 76928a0ca07SZoran Jovanovic // 77028a0ca07SZoran Jovanovic // We have: 77128a0ca07SZoran Jovanovic // 0b000110 sssss ttttt iiiiiiiiiiiiiiii 77228a0ca07SZoran Jovanovic // Invalid if rs == 0 77328a0ca07SZoran Jovanovic // BLEZALC if rs == 0 && rt != 0 77428a0ca07SZoran Jovanovic // BGEZALC if rs == rt && rt != 0 77528a0ca07SZoran Jovanovic // BGEUC if rs != rt && rs != 0 && rt != 0 77628a0ca07SZoran Jovanovic 77728a0ca07SZoran Jovanovic InsnType Rs = fieldFromInstruction(insn, 21, 5); 77828a0ca07SZoran Jovanovic InsnType Rt = fieldFromInstruction(insn, 16, 5); 779d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 78028a0ca07SZoran Jovanovic bool HasRs = false; 78128a0ca07SZoran Jovanovic 78228a0ca07SZoran Jovanovic if (Rt == 0) 78328a0ca07SZoran Jovanovic return MCDisassembler::Fail; 78428a0ca07SZoran Jovanovic else if (Rs == 0) 78528a0ca07SZoran Jovanovic MI.setOpcode(Mips::BLEZALC); 78628a0ca07SZoran Jovanovic else if (Rs == Rt) 78728a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEZALC); 78828a0ca07SZoran Jovanovic else { 78928a0ca07SZoran Jovanovic HasRs = true; 79028a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEUC); 79128a0ca07SZoran Jovanovic } 79228a0ca07SZoran Jovanovic 79328a0ca07SZoran Jovanovic if (HasRs) 794e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 79528a0ca07SZoran Jovanovic Rs))); 796e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 79728a0ca07SZoran Jovanovic Rt))); 79828a0ca07SZoran Jovanovic 799e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 80028a0ca07SZoran Jovanovic 80128a0ca07SZoran Jovanovic return MCDisassembler::Success; 80228a0ca07SZoran Jovanovic } 80328a0ca07SZoran Jovanovic 804ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted 805ea22c4cfSJozef Kolek /// according to the given endianess. 806ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 807ea22c4cfSJozef Kolek uint64_t &Size, uint32_t &Insn, 808ea22c4cfSJozef Kolek bool IsBigEndian) { 809ea22c4cfSJozef Kolek // We want to read exactly 2 Bytes of data. 810ea22c4cfSJozef Kolek if (Bytes.size() < 2) { 811ea22c4cfSJozef Kolek Size = 0; 812ea22c4cfSJozef Kolek return MCDisassembler::Fail; 813ea22c4cfSJozef Kolek } 814ea22c4cfSJozef Kolek 815ea22c4cfSJozef Kolek if (IsBigEndian) { 816ea22c4cfSJozef Kolek Insn = (Bytes[0] << 8) | Bytes[1]; 817ea22c4cfSJozef Kolek } else { 818ea22c4cfSJozef Kolek Insn = (Bytes[1] << 8) | Bytes[0]; 819ea22c4cfSJozef Kolek } 820ea22c4cfSJozef Kolek 821ea22c4cfSJozef Kolek return MCDisassembler::Success; 822ea22c4cfSJozef Kolek } 823ea22c4cfSJozef Kolek 8247fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted 8254aa6bea7SRafael Espindola /// according to the given endianess 8267fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 8277fc5b874SRafael Espindola uint64_t &Size, uint32_t &Insn, 8287fc5b874SRafael Espindola bool IsBigEndian, bool IsMicroMips) { 82971928e68SAkira Hatanaka // We want to read exactly 4 Bytes of data. 8307fc5b874SRafael Espindola if (Bytes.size() < 4) { 8314aa6bea7SRafael Espindola Size = 0; 83271928e68SAkira Hatanaka return MCDisassembler::Fail; 83371928e68SAkira Hatanaka } 83471928e68SAkira Hatanaka 835ea22c4cfSJozef Kolek // High 16 bits of a 32-bit microMIPS instruction (where the opcode is) 836ea22c4cfSJozef Kolek // always precede the low 16 bits in the instruction stream (that is, they 837ea22c4cfSJozef Kolek // are placed at lower addresses in the instruction stream). 838ea22c4cfSJozef Kolek // 839ea22c4cfSJozef Kolek // microMIPS byte ordering: 840ea22c4cfSJozef Kolek // Big-endian: 0 | 1 | 2 | 3 841ea22c4cfSJozef Kolek // Little-endian: 1 | 0 | 3 | 2 842ea22c4cfSJozef Kolek 8434aa6bea7SRafael Espindola if (IsBigEndian) { 84471928e68SAkira Hatanaka // Encoded as a big-endian 32-bit word in the stream. 8454aa6bea7SRafael Espindola Insn = 8464aa6bea7SRafael Espindola (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24); 8474aa6bea7SRafael Espindola } else { 848dde3d582SVladimir Medic if (IsMicroMips) { 8494aa6bea7SRafael Espindola Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) | 850dde3d582SVladimir Medic (Bytes[1] << 24); 851dde3d582SVladimir Medic } else { 8524aa6bea7SRafael Espindola Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | 85371928e68SAkira Hatanaka (Bytes[3] << 24); 85471928e68SAkira Hatanaka } 855dde3d582SVladimir Medic } 85671928e68SAkira Hatanaka 85771928e68SAkira Hatanaka return MCDisassembler::Success; 85871928e68SAkira Hatanaka } 85971928e68SAkira Hatanaka 8604aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 8617fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 86271928e68SAkira Hatanaka uint64_t Address, 8634aa6bea7SRafael Espindola raw_ostream &VStream, 8644aa6bea7SRafael Espindola raw_ostream &CStream) const { 86571928e68SAkira Hatanaka uint32_t Insn; 866ea22c4cfSJozef Kolek DecodeStatus Result; 86771928e68SAkira Hatanaka 868ea22c4cfSJozef Kolek if (IsMicroMips) { 869ea22c4cfSJozef Kolek Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); 870*ebee6129SReid Kleckner if (Result == MCDisassembler::Fail) 871*ebee6129SReid Kleckner return MCDisassembler::Fail; 872ea22c4cfSJozef Kolek 873ada70918SZoran Jovanovic if (hasMips32r6()) { 874ada70918SZoran Jovanovic DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n"); 875ada70918SZoran Jovanovic // Calling the auto-generated decoder function for microMIPS32R6 876ada70918SZoran Jovanovic // (and microMIPS64R6) 16-bit instructions. 877ada70918SZoran Jovanovic Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn, 878ada70918SZoran Jovanovic Address, this, STI); 879ada70918SZoran Jovanovic if (Result != MCDisassembler::Fail) { 880ada70918SZoran Jovanovic Size = 2; 881ada70918SZoran Jovanovic return Result; 882ada70918SZoran Jovanovic } 883ada70918SZoran Jovanovic } 884ada70918SZoran Jovanovic 885ea22c4cfSJozef Kolek DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n"); 886ada70918SZoran Jovanovic // Calling the auto-generated decoder function for microMIPS 16-bit 887ada70918SZoran Jovanovic // instructions. 888ea22c4cfSJozef Kolek Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address, 889ea22c4cfSJozef Kolek this, STI); 890ea22c4cfSJozef Kolek if (Result != MCDisassembler::Fail) { 891ea22c4cfSJozef Kolek Size = 2; 892ea22c4cfSJozef Kolek return Result; 893ea22c4cfSJozef Kolek } 894ea22c4cfSJozef Kolek 895ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true); 89671928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 89771928e68SAkira Hatanaka return MCDisassembler::Fail; 89871928e68SAkira Hatanaka 899676d6012SJozef Kolek if (hasMips32r6()) { 900676d6012SJozef Kolek DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n"); 901676d6012SJozef Kolek // Calling the auto-generated decoder function. 902366783e1SZoran Jovanovic Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address, 903676d6012SJozef Kolek this, STI); 904ada70918SZoran Jovanovic if (Result != MCDisassembler::Fail) { 905ada70918SZoran Jovanovic Size = 4; 906ada70918SZoran Jovanovic return Result; 907ada70918SZoran Jovanovic } 908ada70918SZoran Jovanovic } 909ada70918SZoran Jovanovic 910ea22c4cfSJozef Kolek DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); 911dde3d582SVladimir Medic // Calling the auto-generated decoder function. 9124aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, 913dde3d582SVladimir Medic this, STI); 914dde3d582SVladimir Medic if (Result != MCDisassembler::Fail) { 915dde3d582SVladimir Medic Size = 4; 916dde3d582SVladimir Medic return Result; 917dde3d582SVladimir Medic } 918*ebee6129SReid Kleckner // This is an invalid instruction. Let the disassembler move forward by the 919*ebee6129SReid Kleckner // minimum instruction size. 920*ebee6129SReid Kleckner Size = 2; 921dde3d582SVladimir Medic return MCDisassembler::Fail; 922dde3d582SVladimir Medic } 923dde3d582SVladimir Medic 924ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); 925*ebee6129SReid Kleckner if (Result == MCDisassembler::Fail) { 926*ebee6129SReid Kleckner Size = 4; 927ea22c4cfSJozef Kolek return MCDisassembler::Fail; 928*ebee6129SReid Kleckner } 929ea22c4cfSJozef Kolek 930c171f65aSDaniel Sanders if (hasCOP3()) { 931c171f65aSDaniel Sanders DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n"); 932c171f65aSDaniel Sanders Result = 9334aa6bea7SRafael Espindola decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI); 934c171f65aSDaniel Sanders if (Result != MCDisassembler::Fail) { 935c171f65aSDaniel Sanders Size = 4; 936c171f65aSDaniel Sanders return Result; 937c171f65aSDaniel Sanders } 938c171f65aSDaniel Sanders } 939c171f65aSDaniel Sanders 940c171f65aSDaniel Sanders if (hasMips32r6() && isGP64()) { 9410fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n"); 9424aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn, 9430fa60416SDaniel Sanders Address, this, STI); 9440fa60416SDaniel Sanders if (Result != MCDisassembler::Fail) { 9450fa60416SDaniel Sanders Size = 4; 9460fa60416SDaniel Sanders return Result; 9470fa60416SDaniel Sanders } 9480fa60416SDaniel Sanders } 9490fa60416SDaniel Sanders 950c171f65aSDaniel Sanders if (hasMips32r6()) { 9510fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n"); 9524aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn, 9535c582b2fSDaniel Sanders Address, this, STI); 9545c582b2fSDaniel Sanders if (Result != MCDisassembler::Fail) { 9555c582b2fSDaniel Sanders Size = 4; 9565c582b2fSDaniel Sanders return Result; 9575c582b2fSDaniel Sanders } 9585c582b2fSDaniel Sanders } 9595c582b2fSDaniel Sanders 9603adf9b8dSKai Nacke if (hasCnMips()) { 9613adf9b8dSKai Nacke DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n"); 9623adf9b8dSKai Nacke Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn, 9633adf9b8dSKai Nacke Address, this, STI); 9643adf9b8dSKai Nacke if (Result != MCDisassembler::Fail) { 9653adf9b8dSKai Nacke Size = 4; 9663adf9b8dSKai Nacke return Result; 9673adf9b8dSKai Nacke } 9683adf9b8dSKai Nacke } 9693adf9b8dSKai Nacke 970a19216c8SDaniel Sanders if (isGP64()) { 971a19216c8SDaniel Sanders DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n"); 972a19216c8SDaniel Sanders Result = decodeInstruction(DecoderTableMips6432, Instr, Insn, 973a19216c8SDaniel Sanders Address, this, STI); 974a19216c8SDaniel Sanders if (Result != MCDisassembler::Fail) { 975a19216c8SDaniel Sanders Size = 4; 976a19216c8SDaniel Sanders return Result; 977a19216c8SDaniel Sanders } 978a19216c8SDaniel Sanders } 979a19216c8SDaniel Sanders 9800fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n"); 98171928e68SAkira Hatanaka // Calling the auto-generated decoder function. 9824aa6bea7SRafael Espindola Result = 9834aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI); 98471928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 98571928e68SAkira Hatanaka Size = 4; 98671928e68SAkira Hatanaka return Result; 98771928e68SAkira Hatanaka } 98871928e68SAkira Hatanaka 989*ebee6129SReid Kleckner Size = 4; 99071928e68SAkira Hatanaka return MCDisassembler::Fail; 99171928e68SAkira Hatanaka } 99271928e68SAkira Hatanaka 993ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 994ec8a5490SReed Kotler unsigned RegNo, 995ec8a5490SReed Kotler uint64_t Address, 996ec8a5490SReed Kotler const void *Decoder) { 997ec8a5490SReed Kotler 998ec8a5490SReed Kotler return MCDisassembler::Fail; 999ec8a5490SReed Kotler 1000ec8a5490SReed Kotler } 1001ec8a5490SReed Kotler 100213e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 100371928e68SAkira Hatanaka unsigned RegNo, 100471928e68SAkira Hatanaka uint64_t Address, 100571928e68SAkira Hatanaka const void *Decoder) { 100671928e68SAkira Hatanaka 100771928e68SAkira Hatanaka if (RegNo > 31) 100871928e68SAkira Hatanaka return MCDisassembler::Fail; 100971928e68SAkira Hatanaka 101013e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); 1011e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 101271928e68SAkira Hatanaka return MCDisassembler::Success; 101371928e68SAkira Hatanaka } 101471928e68SAkira Hatanaka 1015b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, 1016b0852e54SZoran Jovanovic unsigned RegNo, 1017b0852e54SZoran Jovanovic uint64_t Address, 1018b0852e54SZoran Jovanovic const void *Decoder) { 1019ea22c4cfSJozef Kolek if (RegNo > 7) 1020b0852e54SZoran Jovanovic return MCDisassembler::Fail; 1021ea22c4cfSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo); 1022e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1023ea22c4cfSJozef Kolek return MCDisassembler::Success; 1024b0852e54SZoran Jovanovic } 1025b0852e54SZoran Jovanovic 10261904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, 10271904fa21SJozef Kolek unsigned RegNo, 10281904fa21SJozef Kolek uint64_t Address, 10291904fa21SJozef Kolek const void *Decoder) { 1030315e7ecaSJozef Kolek if (RegNo > 7) 10311904fa21SJozef Kolek return MCDisassembler::Fail; 1032315e7ecaSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo); 1033e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1034315e7ecaSJozef Kolek return MCDisassembler::Success; 10351904fa21SJozef Kolek } 10361904fa21SJozef Kolek 103741688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst, 103841688679SZoran Jovanovic unsigned RegNo, 103941688679SZoran Jovanovic uint64_t Address, 104041688679SZoran Jovanovic const void *Decoder) { 104141688679SZoran Jovanovic if (RegNo > 7) 104241688679SZoran Jovanovic return MCDisassembler::Fail; 104341688679SZoran Jovanovic unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo); 1044e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 104541688679SZoran Jovanovic return MCDisassembler::Success; 104641688679SZoran Jovanovic } 104741688679SZoran Jovanovic 104813e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 104971928e68SAkira Hatanaka unsigned RegNo, 105071928e68SAkira Hatanaka uint64_t Address, 105171928e68SAkira Hatanaka const void *Decoder) { 105271928e68SAkira Hatanaka if (RegNo > 31) 105371928e68SAkira Hatanaka return MCDisassembler::Fail; 105413e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); 1055e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 105671928e68SAkira Hatanaka return MCDisassembler::Success; 105771928e68SAkira Hatanaka } 105871928e68SAkira Hatanaka 10599bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 10609bfa2e2eSAkira Hatanaka unsigned RegNo, 10619bfa2e2eSAkira Hatanaka uint64_t Address, 10629bfa2e2eSAkira Hatanaka const void *Decoder) { 1063a19216c8SDaniel Sanders if (static_cast<const MipsDisassembler *>(Decoder)->isGP64()) 10649bfa2e2eSAkira Hatanaka return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); 10659bfa2e2eSAkira Hatanaka 10669bfa2e2eSAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 10679bfa2e2eSAkira Hatanaka } 10689bfa2e2eSAkira Hatanaka 1069654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 1070ecabd1a5SAkira Hatanaka unsigned RegNo, 1071ecabd1a5SAkira Hatanaka uint64_t Address, 1072ecabd1a5SAkira Hatanaka const void *Decoder) { 107313e6ccf3SAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 1074ecabd1a5SAkira Hatanaka } 1075ecabd1a5SAkira Hatanaka 107671928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 107771928e68SAkira Hatanaka unsigned RegNo, 107871928e68SAkira Hatanaka uint64_t Address, 107971928e68SAkira Hatanaka const void *Decoder) { 108071928e68SAkira Hatanaka if (RegNo > 31) 108171928e68SAkira Hatanaka return MCDisassembler::Fail; 108271928e68SAkira Hatanaka 10839bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 1084e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 108571928e68SAkira Hatanaka return MCDisassembler::Success; 108671928e68SAkira Hatanaka } 108771928e68SAkira Hatanaka 108871928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 108971928e68SAkira Hatanaka unsigned RegNo, 109071928e68SAkira Hatanaka uint64_t Address, 109171928e68SAkira Hatanaka const void *Decoder) { 109271928e68SAkira Hatanaka if (RegNo > 31) 109371928e68SAkira Hatanaka return MCDisassembler::Fail; 109471928e68SAkira Hatanaka 10959bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 1096e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 109771928e68SAkira Hatanaka return MCDisassembler::Success; 109871928e68SAkira Hatanaka } 109971928e68SAkira Hatanaka 110071928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 110171928e68SAkira Hatanaka unsigned RegNo, 110271928e68SAkira Hatanaka uint64_t Address, 110371928e68SAkira Hatanaka const void *Decoder) { 1104253777fdSChad Rosier if (RegNo > 31) 1105253777fdSChad Rosier return MCDisassembler::Fail; 1106253777fdSChad Rosier unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); 1107e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 110871928e68SAkira Hatanaka return MCDisassembler::Success; 110971928e68SAkira Hatanaka } 111071928e68SAkira Hatanaka 11111fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 11121fb1b8b8SAkira Hatanaka unsigned RegNo, 11131fb1b8b8SAkira Hatanaka uint64_t Address, 11141fb1b8b8SAkira Hatanaka const void *Decoder) { 11151fb1b8b8SAkira Hatanaka if (RegNo > 7) 11161fb1b8b8SAkira Hatanaka return MCDisassembler::Fail; 11171fb1b8b8SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); 1118e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 11191fb1b8b8SAkira Hatanaka return MCDisassembler::Success; 11201fb1b8b8SAkira Hatanaka } 11211fb1b8b8SAkira Hatanaka 11220fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, 11230fa60416SDaniel Sanders uint64_t Address, 11240fa60416SDaniel Sanders const void *Decoder) { 11250fa60416SDaniel Sanders if (RegNo > 31) 11260fa60416SDaniel Sanders return MCDisassembler::Fail; 11270fa60416SDaniel Sanders 11280fa60416SDaniel Sanders unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo); 1129e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 11300fa60416SDaniel Sanders return MCDisassembler::Success; 11310fa60416SDaniel Sanders } 11320fa60416SDaniel Sanders 113371928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 113471928e68SAkira Hatanaka unsigned Insn, 113571928e68SAkira Hatanaka uint64_t Address, 113671928e68SAkira Hatanaka const void *Decoder) { 113771928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1138ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1139ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 11409bf2b567SAkira Hatanaka 114113e6ccf3SAkira Hatanaka Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 114213e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 114371928e68SAkira Hatanaka 1144d7ecf49eSVladimir Medic if (Inst.getOpcode() == Mips::SC || 1145e4e83a7bSDaniel Sanders Inst.getOpcode() == Mips::SCD) 1146e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1147e4e83a7bSDaniel Sanders 1148e4e83a7bSDaniel Sanders Inst.addOperand(MCOperand::createReg(Reg)); 1149e4e83a7bSDaniel Sanders Inst.addOperand(MCOperand::createReg(Base)); 1150e4e83a7bSDaniel Sanders Inst.addOperand(MCOperand::createImm(Offset)); 1151e4e83a7bSDaniel Sanders 1152e4e83a7bSDaniel Sanders return MCDisassembler::Success; 115371928e68SAkira Hatanaka } 115471928e68SAkira Hatanaka 1155e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst, 1156e4e83a7bSDaniel Sanders unsigned Insn, 1157e4e83a7bSDaniel Sanders uint64_t Address, 1158e4e83a7bSDaniel Sanders const void *Decoder) { 1159e4e83a7bSDaniel Sanders int Offset = SignExtend32<9>(Insn >> 7); 1160e4e83a7bSDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1161e4e83a7bSDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 1162e4e83a7bSDaniel Sanders 1163e4e83a7bSDaniel Sanders Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1164e4e83a7bSDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1165e4e83a7bSDaniel Sanders 1166e4e83a7bSDaniel Sanders if (Inst.getOpcode() == Mips::SCE) 1167e4e83a7bSDaniel Sanders Inst.addOperand(MCOperand::createReg(Reg)); 1168e4e83a7bSDaniel Sanders 1169e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1170e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1171e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 117271928e68SAkira Hatanaka 117371928e68SAkira Hatanaka return MCDisassembler::Success; 117471928e68SAkira Hatanaka } 117571928e68SAkira Hatanaka 11763c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte9(MCInst &Inst, 11773c88fbd3SHrvoje Varga unsigned Insn, 11783c88fbd3SHrvoje Varga uint64_t Address, 11793c88fbd3SHrvoje Varga const void *Decoder) { 11803c88fbd3SHrvoje Varga int Offset = SignExtend32<9>(Insn & 0x1ff); 11813c88fbd3SHrvoje Varga unsigned Base = fieldFromInstruction(Insn, 16, 5); 11823c88fbd3SHrvoje Varga unsigned Reg = fieldFromInstruction(Insn, 21, 5); 11833c88fbd3SHrvoje Varga 11843c88fbd3SHrvoje Varga Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 11853c88fbd3SHrvoje Varga Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 11863c88fbd3SHrvoje Varga 11873c88fbd3SHrvoje Varga Inst.addOperand(MCOperand::createReg(Reg)); 11883c88fbd3SHrvoje Varga Inst.addOperand(MCOperand::createReg(Base)); 11893c88fbd3SHrvoje Varga Inst.addOperand(MCOperand::createImm(Offset)); 11903c88fbd3SHrvoje Varga 11913c88fbd3SHrvoje Varga return MCDisassembler::Success; 11923c88fbd3SHrvoje Varga } 11933c88fbd3SHrvoje Varga 11943c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst, 11953c88fbd3SHrvoje Varga unsigned Insn, 11963c88fbd3SHrvoje Varga uint64_t Address, 11973c88fbd3SHrvoje Varga const void *Decoder) { 11983c88fbd3SHrvoje Varga int Offset = SignExtend32<16>(Insn & 0xffff); 11993c88fbd3SHrvoje Varga unsigned Base = fieldFromInstruction(Insn, 16, 5); 12003c88fbd3SHrvoje Varga unsigned Reg = fieldFromInstruction(Insn, 21, 5); 12013c88fbd3SHrvoje Varga 12023c88fbd3SHrvoje Varga Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 12033c88fbd3SHrvoje Varga Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 12043c88fbd3SHrvoje Varga 12053c88fbd3SHrvoje Varga Inst.addOperand(MCOperand::createReg(Reg)); 12063c88fbd3SHrvoje Varga Inst.addOperand(MCOperand::createReg(Base)); 12073c88fbd3SHrvoje Varga Inst.addOperand(MCOperand::createImm(Offset)); 12083c88fbd3SHrvoje Varga 12093c88fbd3SHrvoje Varga return MCDisassembler::Success; 12103c88fbd3SHrvoje Varga } 12113c88fbd3SHrvoje Varga 121292db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 121392db6b78SDaniel Sanders unsigned Insn, 121492db6b78SDaniel Sanders uint64_t Address, 121592db6b78SDaniel Sanders const void *Decoder) { 121692db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 121792db6b78SDaniel Sanders unsigned Hint = fieldFromInstruction(Insn, 16, 5); 121892db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 121992db6b78SDaniel Sanders 122092db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 122192db6b78SDaniel Sanders 1222e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1223e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1224e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Hint)); 122592db6b78SDaniel Sanders 122692db6b78SDaniel Sanders return MCDisassembler::Success; 122792db6b78SDaniel Sanders } 122892db6b78SDaniel Sanders 1229ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst, 1230ab6d1cceSJozef Kolek unsigned Insn, 1231ab6d1cceSJozef Kolek uint64_t Address, 1232ab6d1cceSJozef Kolek const void *Decoder) { 1233ab6d1cceSJozef Kolek int Offset = SignExtend32<12>(Insn & 0xfff); 1234ab6d1cceSJozef Kolek unsigned Base = fieldFromInstruction(Insn, 16, 5); 1235ab6d1cceSJozef Kolek unsigned Hint = fieldFromInstruction(Insn, 21, 5); 1236ab6d1cceSJozef Kolek 1237ab6d1cceSJozef Kolek Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1238ab6d1cceSJozef Kolek 1239e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1240e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1241e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Hint)); 1242ab6d1cceSJozef Kolek 1243ab6d1cceSJozef Kolek return MCDisassembler::Success; 1244ab6d1cceSJozef Kolek } 1245ab6d1cceSJozef Kolek 1246d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst, 1247d9790793SZoran Jovanovic unsigned Insn, 1248d9790793SZoran Jovanovic uint64_t Address, 1249d9790793SZoran Jovanovic const void *Decoder) { 1250d9790793SZoran Jovanovic int Offset = SignExtend32<9>(Insn & 0x1ff); 1251d9790793SZoran Jovanovic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1252d9790793SZoran Jovanovic unsigned Hint = fieldFromInstruction(Insn, 21, 5); 1253d9790793SZoran Jovanovic 1254d9790793SZoran Jovanovic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1255d9790793SZoran Jovanovic 1256d9790793SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Base)); 1257d9790793SZoran Jovanovic Inst.addOperand(MCOperand::createImm(Offset)); 1258d9790793SZoran Jovanovic Inst.addOperand(MCOperand::createImm(Hint)); 1259d9790793SZoran Jovanovic 1260d9790793SZoran Jovanovic return MCDisassembler::Success; 1261d9790793SZoran Jovanovic } 1262d9790793SZoran Jovanovic 1263e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, 1264df464ae2SVladimir Medic unsigned Insn, 1265df464ae2SVladimir Medic uint64_t Address, 1266df464ae2SVladimir Medic const void *Decoder) { 1267e4e83a7bSDaniel Sanders int Offset = SignExtend32<9>(Insn >> 7); 1268df464ae2SVladimir Medic unsigned Hint = fieldFromInstruction(Insn, 16, 5); 1269df464ae2SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 21, 5); 1270df464ae2SVladimir Medic 1271df464ae2SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1272df464ae2SVladimir Medic 1273e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1274e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1275e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Hint)); 1276df464ae2SVladimir Medic 1277df464ae2SVladimir Medic return MCDisassembler::Success; 1278df464ae2SVladimir Medic } 1279df464ae2SVladimir Medic 12809eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst, 12819eaa30d2SZoran Jovanovic unsigned Insn, 12829eaa30d2SZoran Jovanovic uint64_t Address, 12839eaa30d2SZoran Jovanovic const void *Decoder) { 12849eaa30d2SZoran Jovanovic int Offset = SignExtend32<9>(Insn & 0x1ff); 12859eaa30d2SZoran Jovanovic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 12869eaa30d2SZoran Jovanovic unsigned Base = fieldFromInstruction(Insn, 16, 5); 12879eaa30d2SZoran Jovanovic 12889eaa30d2SZoran Jovanovic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 12899eaa30d2SZoran Jovanovic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 12909eaa30d2SZoran Jovanovic 12919eaa30d2SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Reg)); 12929eaa30d2SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Base)); 12939eaa30d2SZoran Jovanovic Inst.addOperand(MCOperand::createImm(Offset)); 12949eaa30d2SZoran Jovanovic 12959eaa30d2SZoran Jovanovic return MCDisassembler::Success; 12969eaa30d2SZoran Jovanovic } 12979eaa30d2SZoran Jovanovic 1298b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 1299b4484d62SDaniel Sanders unsigned Insn, 1300b4484d62SDaniel Sanders uint64_t Address, 1301b4484d62SDaniel Sanders const void *Decoder) { 1302b4484d62SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 1303b4484d62SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 1304b4484d62SDaniel Sanders 1305b4484d62SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1306b4484d62SDaniel Sanders 1307e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1308e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1309b4484d62SDaniel Sanders 1310b4484d62SDaniel Sanders return MCDisassembler::Success; 1311b4484d62SDaniel Sanders } 1312b4484d62SDaniel Sanders 131318148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst, 131418148671SHrvoje Varga unsigned Insn, 131518148671SHrvoje Varga uint64_t Address, 131618148671SHrvoje Varga const void *Decoder) { 131718148671SHrvoje Varga int Immediate = SignExtend32<16>(Insn & 0xffff); 131818148671SHrvoje Varga unsigned Base = fieldFromInstruction(Insn, 16, 5); 131918148671SHrvoje Varga 132018148671SHrvoje Varga Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 132118148671SHrvoje Varga 132218148671SHrvoje Varga Inst.addOperand(MCOperand::createReg(Base)); 132318148671SHrvoje Varga Inst.addOperand(MCOperand::createImm(Immediate)); 132418148671SHrvoje Varga 132518148671SHrvoje Varga return MCDisassembler::Success; 132618148671SHrvoje Varga } 132718148671SHrvoje Varga 1328fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 1329fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder) { 1330fe0bf9f6SMatheus Almeida int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10)); 1331fe0bf9f6SMatheus Almeida unsigned Reg = fieldFromInstruction(Insn, 6, 5); 1332fe0bf9f6SMatheus Almeida unsigned Base = fieldFromInstruction(Insn, 11, 5); 1333fe0bf9f6SMatheus Almeida 1334fe0bf9f6SMatheus Almeida Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg); 1335fe0bf9f6SMatheus Almeida Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1336fe0bf9f6SMatheus Almeida 1337e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1338e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 13396b59c449SMatheus Almeida 13406b59c449SMatheus Almeida // The immediate field of an LD/ST instruction is scaled which means it must 13416b59c449SMatheus Almeida // be multiplied (when decoding) by the size (in bytes) of the instructions' 13426b59c449SMatheus Almeida // data format. 13436b59c449SMatheus Almeida // .b - 1 byte 13446b59c449SMatheus Almeida // .h - 2 bytes 13456b59c449SMatheus Almeida // .w - 4 bytes 13466b59c449SMatheus Almeida // .d - 8 bytes 13476b59c449SMatheus Almeida switch(Inst.getOpcode()) 13486b59c449SMatheus Almeida { 13496b59c449SMatheus Almeida default: 13506b59c449SMatheus Almeida assert (0 && "Unexpected instruction"); 13516b59c449SMatheus Almeida return MCDisassembler::Fail; 13526b59c449SMatheus Almeida break; 13536b59c449SMatheus Almeida case Mips::LD_B: 13546b59c449SMatheus Almeida case Mips::ST_B: 1355e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 13566b59c449SMatheus Almeida break; 13576b59c449SMatheus Almeida case Mips::LD_H: 13586b59c449SMatheus Almeida case Mips::ST_H: 1359e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset * 2)); 13606b59c449SMatheus Almeida break; 13616b59c449SMatheus Almeida case Mips::LD_W: 13626b59c449SMatheus Almeida case Mips::ST_W: 1363e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset * 4)); 13646b59c449SMatheus Almeida break; 13656b59c449SMatheus Almeida case Mips::LD_D: 13666b59c449SMatheus Almeida case Mips::ST_D: 1367e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset * 8)); 13686b59c449SMatheus Almeida break; 13696b59c449SMatheus Almeida } 1370fe0bf9f6SMatheus Almeida 1371fe0bf9f6SMatheus Almeida return MCDisassembler::Success; 1372fe0bf9f6SMatheus Almeida } 1373fe0bf9f6SMatheus Almeida 1374315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 1375315e7ecaSJozef Kolek unsigned Insn, 1376315e7ecaSJozef Kolek uint64_t Address, 1377315e7ecaSJozef Kolek const void *Decoder) { 1378315e7ecaSJozef Kolek unsigned Offset = Insn & 0xf; 1379315e7ecaSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 7, 3); 1380315e7ecaSJozef Kolek unsigned Base = fieldFromInstruction(Insn, 4, 3); 1381315e7ecaSJozef Kolek 1382315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1383315e7ecaSJozef Kolek case Mips::LBU16_MM: 1384315e7ecaSJozef Kolek case Mips::LHU16_MM: 1385315e7ecaSJozef Kolek case Mips::LW16_MM: 1386315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder) 1387315e7ecaSJozef Kolek == MCDisassembler::Fail) 1388315e7ecaSJozef Kolek return MCDisassembler::Fail; 1389315e7ecaSJozef Kolek break; 1390315e7ecaSJozef Kolek case Mips::SB16_MM: 1391797c2aecSZlatko Buljan case Mips::SB16_MMR6: 1392315e7ecaSJozef Kolek case Mips::SH16_MM: 1393797c2aecSZlatko Buljan case Mips::SH16_MMR6: 1394315e7ecaSJozef Kolek case Mips::SW16_MM: 1395797c2aecSZlatko Buljan case Mips::SW16_MMR6: 1396315e7ecaSJozef Kolek if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder) 1397315e7ecaSJozef Kolek == MCDisassembler::Fail) 1398315e7ecaSJozef Kolek return MCDisassembler::Fail; 1399315e7ecaSJozef Kolek break; 1400315e7ecaSJozef Kolek } 1401315e7ecaSJozef Kolek 1402315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder) 1403315e7ecaSJozef Kolek == MCDisassembler::Fail) 1404315e7ecaSJozef Kolek return MCDisassembler::Fail; 1405315e7ecaSJozef Kolek 1406315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1407315e7ecaSJozef Kolek case Mips::LBU16_MM: 1408315e7ecaSJozef Kolek if (Offset == 0xf) 1409e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(-1)); 1410315e7ecaSJozef Kolek else 1411e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1412315e7ecaSJozef Kolek break; 1413315e7ecaSJozef Kolek case Mips::SB16_MM: 1414797c2aecSZlatko Buljan case Mips::SB16_MMR6: 1415e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1416315e7ecaSJozef Kolek break; 1417315e7ecaSJozef Kolek case Mips::LHU16_MM: 1418315e7ecaSJozef Kolek case Mips::SH16_MM: 1419797c2aecSZlatko Buljan case Mips::SH16_MMR6: 1420e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 1)); 1421315e7ecaSJozef Kolek break; 1422315e7ecaSJozef Kolek case Mips::LW16_MM: 1423315e7ecaSJozef Kolek case Mips::SW16_MM: 1424797c2aecSZlatko Buljan case Mips::SW16_MMR6: 1425e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 1426315e7ecaSJozef Kolek break; 1427315e7ecaSJozef Kolek } 1428315e7ecaSJozef Kolek 1429315e7ecaSJozef Kolek return MCDisassembler::Success; 1430315e7ecaSJozef Kolek } 1431315e7ecaSJozef Kolek 143212c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, 143312c6982bSJozef Kolek unsigned Insn, 143412c6982bSJozef Kolek uint64_t Address, 143512c6982bSJozef Kolek const void *Decoder) { 143612c6982bSJozef Kolek unsigned Offset = Insn & 0x1F; 143712c6982bSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 5, 5); 143812c6982bSJozef Kolek 143912c6982bSJozef Kolek Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 144012c6982bSJozef Kolek 1441e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1442e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::SP)); 1443e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 144412c6982bSJozef Kolek 144512c6982bSJozef Kolek return MCDisassembler::Success; 144612c6982bSJozef Kolek } 144712c6982bSJozef Kolek 1448e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, 1449e10a02ecSJozef Kolek unsigned Insn, 1450e10a02ecSJozef Kolek uint64_t Address, 1451e10a02ecSJozef Kolek const void *Decoder) { 1452e10a02ecSJozef Kolek unsigned Offset = Insn & 0x7F; 1453e10a02ecSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 7, 3); 1454e10a02ecSJozef Kolek 1455e10a02ecSJozef Kolek Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1456e10a02ecSJozef Kolek 1457e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1458e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::GP)); 1459e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 1460e10a02ecSJozef Kolek 1461e10a02ecSJozef Kolek return MCDisassembler::Success; 1462e10a02ecSJozef Kolek } 1463e10a02ecSJozef Kolek 1464d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, 1465d68d424aSJozef Kolek unsigned Insn, 1466d68d424aSJozef Kolek uint64_t Address, 1467d68d424aSJozef Kolek const void *Decoder) { 1468797c2aecSZlatko Buljan int Offset; 1469797c2aecSZlatko Buljan switch (Inst.getOpcode()) { 1470797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 1471797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 1472797c2aecSZlatko Buljan Offset = fieldFromInstruction(Insn, 4, 4); 1473797c2aecSZlatko Buljan break; 1474797c2aecSZlatko Buljan default: 1475797c2aecSZlatko Buljan Offset = SignExtend32<4>(Insn & 0xf); 1476797c2aecSZlatko Buljan break; 1477797c2aecSZlatko Buljan } 1478d68d424aSJozef Kolek 1479d68d424aSJozef Kolek if (DecodeRegListOperand16(Inst, Insn, Address, Decoder) 1480d68d424aSJozef Kolek == MCDisassembler::Fail) 1481d68d424aSJozef Kolek return MCDisassembler::Fail; 1482d68d424aSJozef Kolek 1483e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::SP)); 1484e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 1485d68d424aSJozef Kolek 1486d68d424aSJozef Kolek return MCDisassembler::Success; 1487d68d424aSJozef Kolek } 1488d68d424aSJozef Kolek 1489a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst, 1490a6593ff6SZoran Jovanovic unsigned Insn, 1491a6593ff6SZoran Jovanovic uint64_t Address, 1492a6593ff6SZoran Jovanovic const void *Decoder) { 1493a6593ff6SZoran Jovanovic int Offset = SignExtend32<9>(Insn & 0x1ff); 1494a6593ff6SZoran Jovanovic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1495a6593ff6SZoran Jovanovic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1496a6593ff6SZoran Jovanovic 1497a6593ff6SZoran Jovanovic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1498a6593ff6SZoran Jovanovic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1499a6593ff6SZoran Jovanovic 15003ef4dd7bSHrvoje Varga if (Inst.getOpcode() == Mips::SCE_MM) 15013ef4dd7bSHrvoje Varga Inst.addOperand(MCOperand::createReg(Reg)); 15023ef4dd7bSHrvoje Varga 1503a6593ff6SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Reg)); 1504a6593ff6SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Base)); 1505a6593ff6SZoran Jovanovic Inst.addOperand(MCOperand::createImm(Offset)); 1506a6593ff6SZoran Jovanovic 1507a6593ff6SZoran Jovanovic return MCDisassembler::Success; 1508a6593ff6SZoran Jovanovic } 1509a6593ff6SZoran Jovanovic 1510dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 1511dde3d582SVladimir Medic unsigned Insn, 1512dde3d582SVladimir Medic uint64_t Address, 1513dde3d582SVladimir Medic const void *Decoder) { 1514dde3d582SVladimir Medic int Offset = SignExtend32<12>(Insn & 0x0fff); 1515dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1516dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1517dde3d582SVladimir Medic 1518dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1519dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1520dde3d582SVladimir Medic 1521a4c4b5fcSZoran Jovanovic switch (Inst.getOpcode()) { 1522a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 1523a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 1524a4c4b5fcSZoran Jovanovic if (DecodeRegListOperand(Inst, Insn, Address, Decoder) 1525a4c4b5fcSZoran Jovanovic == MCDisassembler::Fail) 1526a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 1527e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1528e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1529a4c4b5fcSZoran Jovanovic break; 1530a4c4b5fcSZoran Jovanovic case Mips::SC_MM: 1531e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1532a4c4b5fcSZoran Jovanovic // fallthrough 1533a4c4b5fcSZoran Jovanovic default: 1534e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 15352deca348SZoran Jovanovic if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) 1536e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg+1)); 15372deca348SZoran Jovanovic 1538e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1539e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1540a4c4b5fcSZoran Jovanovic } 1541dde3d582SVladimir Medic 1542dde3d582SVladimir Medic return MCDisassembler::Success; 1543dde3d582SVladimir Medic } 1544dde3d582SVladimir Medic 1545dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 1546dde3d582SVladimir Medic unsigned Insn, 1547dde3d582SVladimir Medic uint64_t Address, 1548dde3d582SVladimir Medic const void *Decoder) { 1549dde3d582SVladimir Medic int Offset = SignExtend32<16>(Insn & 0xffff); 1550dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1551dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1552dde3d582SVladimir Medic 1553dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1554dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1555dde3d582SVladimir Medic 1556e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1557e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1558e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1559dde3d582SVladimir Medic 1560dde3d582SVladimir Medic return MCDisassembler::Success; 1561dde3d582SVladimir Medic } 1562dde3d582SVladimir Medic 156371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, 156471928e68SAkira Hatanaka unsigned Insn, 156571928e68SAkira Hatanaka uint64_t Address, 156671928e68SAkira Hatanaka const void *Decoder) { 156771928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1568ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1569ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 157071928e68SAkira Hatanaka 15719bf2b567SAkira Hatanaka Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 157213e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 15739bf2b567SAkira Hatanaka 1574e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1575e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1576e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 157771928e68SAkira Hatanaka 157871928e68SAkira Hatanaka return MCDisassembler::Success; 157971928e68SAkira Hatanaka } 158071928e68SAkira Hatanaka 158192db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, 158292db6b78SDaniel Sanders unsigned Insn, 158392db6b78SDaniel Sanders uint64_t Address, 158492db6b78SDaniel Sanders const void *Decoder) { 158592db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 158692db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 158792db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 158892db6b78SDaniel Sanders 158992db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); 159092db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 159192db6b78SDaniel Sanders 1592e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1593e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1594e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 159592db6b78SDaniel Sanders 159692db6b78SDaniel Sanders return MCDisassembler::Success; 159792db6b78SDaniel Sanders } 159892db6b78SDaniel Sanders 159992db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, 160092db6b78SDaniel Sanders unsigned Insn, 160192db6b78SDaniel Sanders uint64_t Address, 160292db6b78SDaniel Sanders const void *Decoder) { 160392db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 160492db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 160592db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 160692db6b78SDaniel Sanders 160792db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP3RegClassID, Reg); 160892db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 160992db6b78SDaniel Sanders 1610e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1611e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1612e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 161392db6b78SDaniel Sanders 161492db6b78SDaniel Sanders return MCDisassembler::Success; 161592db6b78SDaniel Sanders } 161692db6b78SDaniel Sanders 1617435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, 1618435cf8a4SVladimir Medic unsigned Insn, 1619435cf8a4SVladimir Medic uint64_t Address, 1620435cf8a4SVladimir Medic const void *Decoder) { 1621435cf8a4SVladimir Medic int Offset = SignExtend32<11>(Insn & 0x07ff); 1622435cf8a4SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1623435cf8a4SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 11, 5); 1624435cf8a4SVladimir Medic 1625435cf8a4SVladimir Medic Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); 1626435cf8a4SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1627435cf8a4SVladimir Medic 1628e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1629e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1630e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1631435cf8a4SVladimir Medic 1632435cf8a4SVladimir Medic return MCDisassembler::Success; 1633435cf8a4SVladimir Medic } 16346a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 16356a803f61SDaniel Sanders unsigned Insn, 16366a803f61SDaniel Sanders uint64_t Address, 16376a803f61SDaniel Sanders const void *Decoder) { 16386a803f61SDaniel Sanders int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff); 16396a803f61SDaniel Sanders unsigned Rt = fieldFromInstruction(Insn, 16, 5); 16406a803f61SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 16416a803f61SDaniel Sanders 16426a803f61SDaniel Sanders Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt); 16436a803f61SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 16446a803f61SDaniel Sanders 16456a803f61SDaniel Sanders if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){ 1646e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Rt)); 16476a803f61SDaniel Sanders } 16486a803f61SDaniel Sanders 1649e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Rt)); 1650e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1651e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 16526a803f61SDaniel Sanders 16536a803f61SDaniel Sanders return MCDisassembler::Success; 16546a803f61SDaniel Sanders } 165571928e68SAkira Hatanaka 165671928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 165771928e68SAkira Hatanaka unsigned RegNo, 165871928e68SAkira Hatanaka uint64_t Address, 165971928e68SAkira Hatanaka const void *Decoder) { 166071928e68SAkira Hatanaka // Currently only hardware register 29 is supported. 166171928e68SAkira Hatanaka if (RegNo != 29) 166271928e68SAkira Hatanaka return MCDisassembler::Fail; 1663e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::HWR29)); 166471928e68SAkira Hatanaka return MCDisassembler::Success; 166571928e68SAkira Hatanaka } 166671928e68SAkira Hatanaka 166771928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 166871928e68SAkira Hatanaka unsigned RegNo, 166971928e68SAkira Hatanaka uint64_t Address, 167071928e68SAkira Hatanaka const void *Decoder) { 16719bf2b567SAkira Hatanaka if (RegNo > 30 || RegNo %2) 167271928e68SAkira Hatanaka return MCDisassembler::Fail; 167371928e68SAkira Hatanaka 16749bf2b567SAkira Hatanaka ; 16759bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 1676e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 167771928e68SAkira Hatanaka return MCDisassembler::Success; 167871928e68SAkira Hatanaka } 167971928e68SAkira Hatanaka 168000fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 1681ecabd1a5SAkira Hatanaka unsigned RegNo, 1682ecabd1a5SAkira Hatanaka uint64_t Address, 1683ecabd1a5SAkira Hatanaka const void *Decoder) { 1684ecabd1a5SAkira Hatanaka if (RegNo >= 4) 1685ecabd1a5SAkira Hatanaka return MCDisassembler::Fail; 1686ecabd1a5SAkira Hatanaka 168700fcf2e1SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo); 1688e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1689ecabd1a5SAkira Hatanaka return MCDisassembler::Success; 1690ecabd1a5SAkira Hatanaka } 1691ecabd1a5SAkira Hatanaka 16928002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 169359bfaf77SAkira Hatanaka unsigned RegNo, 169459bfaf77SAkira Hatanaka uint64_t Address, 169559bfaf77SAkira Hatanaka const void *Decoder) { 169659bfaf77SAkira Hatanaka if (RegNo >= 4) 169759bfaf77SAkira Hatanaka return MCDisassembler::Fail; 169859bfaf77SAkira Hatanaka 16998002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo); 1700e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 170159bfaf77SAkira Hatanaka return MCDisassembler::Success; 170259bfaf77SAkira Hatanaka } 170359bfaf77SAkira Hatanaka 17048002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 170559bfaf77SAkira Hatanaka unsigned RegNo, 170659bfaf77SAkira Hatanaka uint64_t Address, 170759bfaf77SAkira Hatanaka const void *Decoder) { 170859bfaf77SAkira Hatanaka if (RegNo >= 4) 170959bfaf77SAkira Hatanaka return MCDisassembler::Fail; 171059bfaf77SAkira Hatanaka 17118002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo); 1712e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 171359bfaf77SAkira Hatanaka return MCDisassembler::Success; 171459bfaf77SAkira Hatanaka } 171559bfaf77SAkira Hatanaka 17163eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, 17173eb663b0SJack Carter unsigned RegNo, 17183eb663b0SJack Carter uint64_t Address, 17193eb663b0SJack Carter const void *Decoder) { 17203eb663b0SJack Carter if (RegNo > 31) 17213eb663b0SJack Carter return MCDisassembler::Fail; 17223eb663b0SJack Carter 17233eb663b0SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo); 1724e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 17253eb663b0SJack Carter return MCDisassembler::Success; 17263eb663b0SJack Carter } 17273eb663b0SJack Carter 17285dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, 17295dc8ac92SJack Carter unsigned RegNo, 17305dc8ac92SJack Carter uint64_t Address, 17315dc8ac92SJack Carter const void *Decoder) { 17325dc8ac92SJack Carter if (RegNo > 31) 17335dc8ac92SJack Carter return MCDisassembler::Fail; 17345dc8ac92SJack Carter 17355dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo); 1736e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 17375dc8ac92SJack Carter return MCDisassembler::Success; 17385dc8ac92SJack Carter } 17395dc8ac92SJack Carter 17405dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, 17415dc8ac92SJack Carter unsigned RegNo, 17425dc8ac92SJack Carter uint64_t Address, 17435dc8ac92SJack Carter const void *Decoder) { 17445dc8ac92SJack Carter if (RegNo > 31) 17455dc8ac92SJack Carter return MCDisassembler::Fail; 17465dc8ac92SJack Carter 17475dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo); 1748e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 17495dc8ac92SJack Carter return MCDisassembler::Success; 17505dc8ac92SJack Carter } 17515dc8ac92SJack Carter 17525dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, 17535dc8ac92SJack Carter unsigned RegNo, 17545dc8ac92SJack Carter uint64_t Address, 17555dc8ac92SJack Carter const void *Decoder) { 17565dc8ac92SJack Carter if (RegNo > 31) 17575dc8ac92SJack Carter return MCDisassembler::Fail; 17585dc8ac92SJack Carter 17595dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo); 1760e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 17615dc8ac92SJack Carter return MCDisassembler::Success; 17625dc8ac92SJack Carter } 17635dc8ac92SJack Carter 1764a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, 1765a591fdc6SMatheus Almeida unsigned RegNo, 1766a591fdc6SMatheus Almeida uint64_t Address, 1767a591fdc6SMatheus Almeida const void *Decoder) { 1768a591fdc6SMatheus Almeida if (RegNo > 7) 1769a591fdc6SMatheus Almeida return MCDisassembler::Fail; 1770a591fdc6SMatheus Almeida 1771a591fdc6SMatheus Almeida unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo); 1772e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1773a591fdc6SMatheus Almeida return MCDisassembler::Success; 1774a591fdc6SMatheus Almeida } 1775a591fdc6SMatheus Almeida 1776a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, 1777a3134faeSDaniel Sanders unsigned RegNo, 1778a3134faeSDaniel Sanders uint64_t Address, 1779a3134faeSDaniel Sanders const void *Decoder) { 1780a3134faeSDaniel Sanders if (RegNo > 31) 1781a3134faeSDaniel Sanders return MCDisassembler::Fail; 1782a3134faeSDaniel Sanders 1783a3134faeSDaniel Sanders unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo); 1784a3134faeSDaniel Sanders Inst.addOperand(MCOperand::createReg(Reg)); 1785a3134faeSDaniel Sanders return MCDisassembler::Success; 1786a3134faeSDaniel Sanders } 1787a3134faeSDaniel Sanders 17882a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, 17892a83d680SDaniel Sanders unsigned RegNo, 17902a83d680SDaniel Sanders uint64_t Address, 17912a83d680SDaniel Sanders const void *Decoder) { 17922a83d680SDaniel Sanders if (RegNo > 31) 17932a83d680SDaniel Sanders return MCDisassembler::Fail; 17942a83d680SDaniel Sanders 17952a83d680SDaniel Sanders unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo); 1796e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 17972a83d680SDaniel Sanders return MCDisassembler::Success; 17982a83d680SDaniel Sanders } 17992a83d680SDaniel Sanders 180071928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 180171928e68SAkira Hatanaka unsigned Offset, 180271928e68SAkira Hatanaka uint64_t Address, 180371928e68SAkira Hatanaka const void *Decoder) { 1804d37bab61SAlexey Samsonov int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4; 1805e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 180671928e68SAkira Hatanaka return MCDisassembler::Success; 180771928e68SAkira Hatanaka } 180871928e68SAkira Hatanaka 180971928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 181071928e68SAkira Hatanaka unsigned Insn, 181171928e68SAkira Hatanaka uint64_t Address, 181271928e68SAkira Hatanaka const void *Decoder) { 181371928e68SAkira Hatanaka 1814ecaef49fSJim Grosbach unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 1815e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(JumpOffset)); 181671928e68SAkira Hatanaka return MCDisassembler::Success; 181771928e68SAkira Hatanaka } 181871928e68SAkira Hatanaka 18193c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst, 18203c8869dcSZoran Jovanovic unsigned Offset, 18213c8869dcSZoran Jovanovic uint64_t Address, 18223c8869dcSZoran Jovanovic const void *Decoder) { 1823d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<21>(Offset) * 4; 18243c8869dcSZoran Jovanovic 1825e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 18263c8869dcSZoran Jovanovic return MCDisassembler::Success; 18273c8869dcSZoran Jovanovic } 18283c8869dcSZoran Jovanovic 18293c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst, 18303c8869dcSZoran Jovanovic unsigned Offset, 18313c8869dcSZoran Jovanovic uint64_t Address, 18323c8869dcSZoran Jovanovic const void *Decoder) { 1833d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<26>(Offset) * 4; 18343c8869dcSZoran Jovanovic 1835e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 18363c8869dcSZoran Jovanovic return MCDisassembler::Success; 18373c8869dcSZoran Jovanovic } 18383c8869dcSZoran Jovanovic 18399761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, 18409761e96bSJozef Kolek unsigned Offset, 18419761e96bSJozef Kolek uint64_t Address, 18429761e96bSJozef Kolek const void *Decoder) { 18439761e96bSJozef Kolek int32_t BranchOffset = SignExtend32<7>(Offset) << 1; 1844e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 18459761e96bSJozef Kolek return MCDisassembler::Success; 18469761e96bSJozef Kolek } 18479761e96bSJozef Kolek 18485cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, 18495cfebddeSJozef Kolek unsigned Offset, 18505cfebddeSJozef Kolek uint64_t Address, 18515cfebddeSJozef Kolek const void *Decoder) { 18525cfebddeSJozef Kolek int32_t BranchOffset = SignExtend32<10>(Offset) << 1; 1853e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 18545cfebddeSJozef Kolek return MCDisassembler::Success; 18555cfebddeSJozef Kolek } 18565cfebddeSJozef Kolek 18578a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 18588a80aa76SZoran Jovanovic unsigned Offset, 18598a80aa76SZoran Jovanovic uint64_t Address, 18608a80aa76SZoran Jovanovic const void *Decoder) { 1861d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<16>(Offset) * 2; 1862e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 18638a80aa76SZoran Jovanovic return MCDisassembler::Success; 18648a80aa76SZoran Jovanovic } 18658a80aa76SZoran Jovanovic 1866507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 1867507e084aSZoran Jovanovic unsigned Insn, 1868507e084aSZoran Jovanovic uint64_t Address, 1869507e084aSZoran Jovanovic const void *Decoder) { 1870507e084aSZoran Jovanovic unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1; 1871e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(JumpOffset)); 1872507e084aSZoran Jovanovic return MCDisassembler::Success; 1873507e084aSZoran Jovanovic } 187471928e68SAkira Hatanaka 1875aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 1876aa2b9278SJozef Kolek unsigned Value, 1877aa2b9278SJozef Kolek uint64_t Address, 1878aa2b9278SJozef Kolek const void *Decoder) { 1879aa2b9278SJozef Kolek if (Value == 0) 1880e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(1)); 1881aa2b9278SJozef Kolek else if (Value == 0x7) 1882e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(-1)); 1883aa2b9278SJozef Kolek else 1884e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Value << 2)); 1885aa2b9278SJozef Kolek return MCDisassembler::Success; 1886aa2b9278SJozef Kolek } 1887aa2b9278SJozef Kolek 1888aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, 1889aa2b9278SJozef Kolek unsigned Value, 1890aa2b9278SJozef Kolek uint64_t Address, 1891aa2b9278SJozef Kolek const void *Decoder) { 1892e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Value << 2)); 1893aa2b9278SJozef Kolek return MCDisassembler::Success; 1894aa2b9278SJozef Kolek } 1895aa2b9278SJozef Kolek 1896aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst, 1897aa2b9278SJozef Kolek unsigned Value, 1898aa2b9278SJozef Kolek uint64_t Address, 1899aa2b9278SJozef Kolek const void *Decoder) { 1900aa2b9278SJozef Kolek if (Value == 0x7F) 1901e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(-1)); 1902aa2b9278SJozef Kolek else 1903e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Value)); 1904aa2b9278SJozef Kolek return MCDisassembler::Success; 1905aa2b9278SJozef Kolek } 1906aa2b9278SJozef Kolek 19076b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, 19086b28f09dSZoran Jovanovic unsigned Value, 19096b28f09dSZoran Jovanovic uint64_t Address, 19106b28f09dSZoran Jovanovic const void *Decoder) { 19116b28f09dSZoran Jovanovic Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value)); 19126b28f09dSZoran Jovanovic return MCDisassembler::Success; 19136b28f09dSZoran Jovanovic } 19146b28f09dSZoran Jovanovic 1915aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst, 1916aa2b9278SJozef Kolek unsigned Value, 1917aa2b9278SJozef Kolek uint64_t Address, 1918aa2b9278SJozef Kolek const void *Decoder) { 1919e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<4>(Value))); 1920aa2b9278SJozef Kolek return MCDisassembler::Success; 1921aa2b9278SJozef Kolek } 1922aa2b9278SJozef Kolek 192371928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 192471928e68SAkira Hatanaka unsigned Insn, 192571928e68SAkira Hatanaka uint64_t Address, 192671928e68SAkira Hatanaka const void *Decoder) { 1927e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Insn))); 192871928e68SAkira Hatanaka return MCDisassembler::Success; 192971928e68SAkira Hatanaka } 193071928e68SAkira Hatanaka 1931ea4f653dSDaniel Sanders template <unsigned Bits, int Offset> 1932ea4f653dSDaniel Sanders static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value, 1933779c5937SMatheus Almeida uint64_t Address, 1934779c5937SMatheus Almeida const void *Decoder) { 1935ea4f653dSDaniel Sanders Value &= ((1 << Bits) - 1); 1936ea4f653dSDaniel Sanders Inst.addOperand(MCOperand::createImm(Value + Offset)); 1937779c5937SMatheus Almeida return MCDisassembler::Success; 1938779c5937SMatheus Almeida } 1939779c5937SMatheus Almeida 194071928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 194171928e68SAkira Hatanaka unsigned Insn, 194271928e68SAkira Hatanaka uint64_t Address, 194371928e68SAkira Hatanaka const void *Decoder) { 194471928e68SAkira Hatanaka // First we need to grab the pos(lsb) from MCInst. 194571928e68SAkira Hatanaka int Pos = Inst.getOperand(2).getImm(); 194671928e68SAkira Hatanaka int Size = (int) Insn - Pos + 1; 1947e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size))); 194871928e68SAkira Hatanaka return MCDisassembler::Success; 194971928e68SAkira Hatanaka } 195071928e68SAkira Hatanaka 195171928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 195271928e68SAkira Hatanaka unsigned Insn, 195371928e68SAkira Hatanaka uint64_t Address, 195471928e68SAkira Hatanaka const void *Decoder) { 195571928e68SAkira Hatanaka int Size = (int) Insn + 1; 1956e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size))); 195771928e68SAkira Hatanaka return MCDisassembler::Success; 195871928e68SAkira Hatanaka } 1959b59e1a41SDaniel Sanders 1960b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 1961b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder) { 1962e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4)); 1963b59e1a41SDaniel Sanders return MCDisassembler::Success; 1964b59e1a41SDaniel Sanders } 19652855142aSZoran Jovanovic 19662855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 19672855142aSZoran Jovanovic uint64_t Address, const void *Decoder) { 1968e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8)); 19692855142aSZoran Jovanovic return MCDisassembler::Success; 19702855142aSZoran Jovanovic } 1971a4c4b5fcSZoran Jovanovic 1972b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 1973b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1974b682ddf3SVladimir Medic int32_t DecodedValue; 1975b682ddf3SVladimir Medic switch (Insn) { 1976b682ddf3SVladimir Medic case 0: DecodedValue = 256; break; 1977b682ddf3SVladimir Medic case 1: DecodedValue = 257; break; 1978b682ddf3SVladimir Medic case 510: DecodedValue = -258; break; 1979b682ddf3SVladimir Medic case 511: DecodedValue = -257; break; 1980b682ddf3SVladimir Medic default: DecodedValue = SignExtend32<9>(Insn); break; 1981b682ddf3SVladimir Medic } 1982e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(DecodedValue * 4)); 1983b682ddf3SVladimir Medic return MCDisassembler::Success; 1984b682ddf3SVladimir Medic } 1985b682ddf3SVladimir Medic 1986b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 1987b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1988b682ddf3SVladimir Medic // Insn must be >= 0, since it is unsigned that condition is always true. 1989b682ddf3SVladimir Medic assert(Insn < 16); 1990b682ddf3SVladimir Medic int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 1991b682ddf3SVladimir Medic 255, 32768, 65535}; 1992e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(DecodedValues[Insn])); 1993b682ddf3SVladimir Medic return MCDisassembler::Success; 1994b682ddf3SVladimir Medic } 1995b682ddf3SVladimir Medic 1996b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, 1997b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1998e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Insn << 2)); 1999b682ddf3SVladimir Medic return MCDisassembler::Success; 2000b682ddf3SVladimir Medic } 2001b682ddf3SVladimir Medic 2002a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, 2003a4c4b5fcSZoran Jovanovic unsigned Insn, 2004a4c4b5fcSZoran Jovanovic uint64_t Address, 2005a4c4b5fcSZoran Jovanovic const void *Decoder) { 2006a4c4b5fcSZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5, 2007dc4b8c27SZoran Jovanovic Mips::S6, Mips::S7, Mips::FP}; 2008a4c4b5fcSZoran Jovanovic unsigned RegNum; 2009a4c4b5fcSZoran Jovanovic 2010a4c4b5fcSZoran Jovanovic unsigned RegLst = fieldFromInstruction(Insn, 21, 5); 2011df19a5e6SDaniel Sanders 2012a4c4b5fcSZoran Jovanovic // Empty register lists are not allowed. 2013a4c4b5fcSZoran Jovanovic if (RegLst == 0) 2014a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 2015a4c4b5fcSZoran Jovanovic 2016a4c4b5fcSZoran Jovanovic RegNum = RegLst & 0xf; 2017df19a5e6SDaniel Sanders 2018df19a5e6SDaniel Sanders // RegLst values 10-15, and 26-31 are reserved. 2019df19a5e6SDaniel Sanders if (RegNum > 9) 2020df19a5e6SDaniel Sanders return MCDisassembler::Fail; 2021df19a5e6SDaniel Sanders 2022a4c4b5fcSZoran Jovanovic for (unsigned i = 0; i < RegNum; i++) 2023e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Regs[i])); 2024a4c4b5fcSZoran Jovanovic 2025a4c4b5fcSZoran Jovanovic if (RegLst & 0x10) 2026e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::RA)); 2027a4c4b5fcSZoran Jovanovic 2028a4c4b5fcSZoran Jovanovic return MCDisassembler::Success; 2029a4c4b5fcSZoran Jovanovic } 2030f9a02500SZoran Jovanovic 2031f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 2032f9a02500SZoran Jovanovic uint64_t Address, 2033f9a02500SZoran Jovanovic const void *Decoder) { 2034f9a02500SZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3}; 2035797c2aecSZlatko Buljan unsigned RegLst; 2036797c2aecSZlatko Buljan switch(Inst.getOpcode()) { 2037797c2aecSZlatko Buljan default: 2038797c2aecSZlatko Buljan RegLst = fieldFromInstruction(Insn, 4, 2); 2039797c2aecSZlatko Buljan break; 2040797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 2041797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 2042797c2aecSZlatko Buljan RegLst = fieldFromInstruction(Insn, 8, 2); 2043797c2aecSZlatko Buljan break; 2044797c2aecSZlatko Buljan } 2045d68d424aSJozef Kolek unsigned RegNum = RegLst & 0x3; 2046f9a02500SZoran Jovanovic 2047d68d424aSJozef Kolek for (unsigned i = 0; i <= RegNum; i++) 2048e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Regs[i])); 2049f9a02500SZoran Jovanovic 2050e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::RA)); 2051f9a02500SZoran Jovanovic 2052f9a02500SZoran Jovanovic return MCDisassembler::Success; 2053f9a02500SZoran Jovanovic } 20542c6d7320SJozef Kolek 205541688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn, 205641688679SZoran Jovanovic uint64_t Address, const void *Decoder) { 205741688679SZoran Jovanovic 205841688679SZoran Jovanovic unsigned RegPair = fieldFromInstruction(Insn, 7, 3); 205941688679SZoran Jovanovic 206041688679SZoran Jovanovic switch (RegPair) { 206141688679SZoran Jovanovic default: 206241688679SZoran Jovanovic return MCDisassembler::Fail; 206341688679SZoran Jovanovic case 0: 2064e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A1)); 2065e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A2)); 206641688679SZoran Jovanovic break; 206741688679SZoran Jovanovic case 1: 2068e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A1)); 2069e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A3)); 207041688679SZoran Jovanovic break; 207141688679SZoran Jovanovic case 2: 2072e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A2)); 2073e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A3)); 207441688679SZoran Jovanovic break; 207541688679SZoran Jovanovic case 3: 2076e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2077e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::S5)); 207841688679SZoran Jovanovic break; 207941688679SZoran Jovanovic case 4: 2080e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2081e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::S6)); 208241688679SZoran Jovanovic break; 208341688679SZoran Jovanovic case 5: 2084e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2085e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A1)); 208641688679SZoran Jovanovic break; 208741688679SZoran Jovanovic case 6: 2088e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2089e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A2)); 209041688679SZoran Jovanovic break; 209141688679SZoran Jovanovic case 7: 2092e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2093e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A3)); 209441688679SZoran Jovanovic break; 209541688679SZoran Jovanovic } 209641688679SZoran Jovanovic 209741688679SZoran Jovanovic return MCDisassembler::Success; 209841688679SZoran Jovanovic } 209941688679SZoran Jovanovic 21002c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, 21012c6d7320SJozef Kolek uint64_t Address, const void *Decoder) { 21026499b5f0SJustin Bogner Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2))); 21032c6d7320SJozef Kolek return MCDisassembler::Success; 21042c6d7320SJozef Kolek } 2105