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 24492db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 24592db6b78SDaniel Sanders unsigned Insn, 24692db6b78SDaniel Sanders uint64_t Address, 24792db6b78SDaniel Sanders const void *Decoder); 24892db6b78SDaniel Sanders 249df464ae2SVladimir Medic static DecodeStatus DecodeCacheOpR6(MCInst &Inst, 250df464ae2SVladimir Medic unsigned Insn, 251df464ae2SVladimir Medic uint64_t Address, 252df464ae2SVladimir Medic const void *Decoder); 253df464ae2SVladimir Medic 254ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst, 255ab6d1cceSJozef Kolek unsigned Insn, 256ab6d1cceSJozef Kolek uint64_t Address, 257ab6d1cceSJozef Kolek const void *Decoder); 258ab6d1cceSJozef Kolek 259*9eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst, 260*9eaa30d2SZoran Jovanovic unsigned Insn, 261*9eaa30d2SZoran Jovanovic uint64_t Address, 262*9eaa30d2SZoran Jovanovic const void *Decoder); 263*9eaa30d2SZoran Jovanovic 264b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 265b4484d62SDaniel Sanders unsigned Insn, 266b4484d62SDaniel Sanders uint64_t Address, 267b4484d62SDaniel Sanders const void *Decoder); 268b4484d62SDaniel Sanders 269fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 270fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder); 271fe0bf9f6SMatheus Almeida 272315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 273315e7ecaSJozef Kolek unsigned Insn, 274315e7ecaSJozef Kolek uint64_t Address, 275315e7ecaSJozef Kolek const void *Decoder); 276315e7ecaSJozef Kolek 27712c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, 27812c6982bSJozef Kolek unsigned Insn, 27912c6982bSJozef Kolek uint64_t Address, 28012c6982bSJozef Kolek const void *Decoder); 28112c6982bSJozef Kolek 282e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, 283e10a02ecSJozef Kolek unsigned Insn, 284e10a02ecSJozef Kolek uint64_t Address, 285e10a02ecSJozef Kolek const void *Decoder); 286e10a02ecSJozef Kolek 287d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, 288d68d424aSJozef Kolek unsigned Insn, 289d68d424aSJozef Kolek uint64_t Address, 290d68d424aSJozef Kolek const void *Decoder); 291d68d424aSJozef Kolek 292a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst, 293a6593ff6SZoran Jovanovic unsigned Insn, 294a6593ff6SZoran Jovanovic uint64_t Address, 295a6593ff6SZoran Jovanovic const void *Decoder); 296a6593ff6SZoran Jovanovic 297dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 298dde3d582SVladimir Medic unsigned Insn, 299dde3d582SVladimir Medic uint64_t Address, 300dde3d582SVladimir Medic const void *Decoder); 301dde3d582SVladimir Medic 302dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 303dde3d582SVladimir Medic unsigned Insn, 304dde3d582SVladimir Medic uint64_t Address, 305dde3d582SVladimir Medic const void *Decoder); 306dde3d582SVladimir Medic 30771928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 30871928e68SAkira Hatanaka uint64_t Address, 30971928e68SAkira Hatanaka const void *Decoder); 31071928e68SAkira Hatanaka 31192db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, 31292db6b78SDaniel Sanders uint64_t Address, 31392db6b78SDaniel Sanders const void *Decoder); 31492db6b78SDaniel Sanders 31592db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, 31692db6b78SDaniel Sanders uint64_t Address, 31792db6b78SDaniel Sanders const void *Decoder); 31892db6b78SDaniel Sanders 319435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn, 320435cf8a4SVladimir Medic uint64_t Address, 321435cf8a4SVladimir Medic const void *Decoder); 322435cf8a4SVladimir Medic 3236a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 3246a803f61SDaniel Sanders unsigned Insn, 3256a803f61SDaniel Sanders uint64_t Address, 3266a803f61SDaniel Sanders const void *Decoder); 3276a803f61SDaniel Sanders 328aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 329aa2b9278SJozef Kolek unsigned Value, 330aa2b9278SJozef Kolek uint64_t Address, 331aa2b9278SJozef Kolek const void *Decoder); 332aa2b9278SJozef Kolek 333aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, 334aa2b9278SJozef Kolek unsigned Value, 335aa2b9278SJozef Kolek uint64_t Address, 336aa2b9278SJozef Kolek const void *Decoder); 337aa2b9278SJozef Kolek 338aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst, 339aa2b9278SJozef Kolek unsigned Value, 340aa2b9278SJozef Kolek uint64_t Address, 341aa2b9278SJozef Kolek const void *Decoder); 342aa2b9278SJozef Kolek 343aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst, 344aa2b9278SJozef Kolek unsigned Value, 345aa2b9278SJozef Kolek uint64_t Address, 346aa2b9278SJozef Kolek const void *Decoder); 347aa2b9278SJozef Kolek 34871928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 34971928e68SAkira Hatanaka unsigned Insn, 35071928e68SAkira Hatanaka uint64_t Address, 35171928e68SAkira Hatanaka const void *Decoder); 35271928e68SAkira Hatanaka 353779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which 354779c5937SMatheus Almeida // is off by one. 355779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst, 356779c5937SMatheus Almeida unsigned Insn, 357779c5937SMatheus Almeida uint64_t Address, 358779c5937SMatheus Almeida const void *Decoder); 359779c5937SMatheus Almeida 36071928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 36171928e68SAkira Hatanaka unsigned Insn, 36271928e68SAkira Hatanaka uint64_t Address, 36371928e68SAkira Hatanaka const void *Decoder); 36471928e68SAkira Hatanaka 36571928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 36671928e68SAkira Hatanaka unsigned Insn, 36771928e68SAkira Hatanaka uint64_t Address, 36871928e68SAkira Hatanaka const void *Decoder); 36971928e68SAkira Hatanaka 370b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 371b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder); 372b59e1a41SDaniel Sanders 3732855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 3742855142aSZoran Jovanovic uint64_t Address, const void *Decoder); 3752855142aSZoran Jovanovic 376b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 377b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 378b682ddf3SVladimir Medic 379b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 380b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 381b682ddf3SVladimir Medic 382b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, 383b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 384b682ddf3SVladimir Medic 3852c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, 3862c6d7320SJozef Kolek uint64_t Address, const void *Decoder); 3872c6d7320SJozef Kolek 388b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't 389b50ccf8eSDaniel Sanders /// handle. 390b50ccf8eSDaniel Sanders template <typename InsnType> 391b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 392b50ccf8eSDaniel Sanders const void *Decoder); 3935c582b2fSDaniel Sanders 3945c582b2fSDaniel Sanders template <typename InsnType> 3955c582b2fSDaniel Sanders static DecodeStatus 3965c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3975c582b2fSDaniel Sanders const void *Decoder); 3985c582b2fSDaniel Sanders 3995c582b2fSDaniel Sanders template <typename InsnType> 4005c582b2fSDaniel Sanders static DecodeStatus 4015c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4025c582b2fSDaniel Sanders const void *Decoder); 4035c582b2fSDaniel Sanders 4045c582b2fSDaniel Sanders template <typename InsnType> 4055c582b2fSDaniel Sanders static DecodeStatus 4065c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4075c582b2fSDaniel Sanders const void *Decoder); 4085c582b2fSDaniel Sanders 4095c582b2fSDaniel Sanders template <typename InsnType> 4105c582b2fSDaniel Sanders static DecodeStatus 4115c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4125c582b2fSDaniel Sanders const void *Decoder); 4135c582b2fSDaniel Sanders 4145c582b2fSDaniel Sanders template <typename InsnType> 4155c582b2fSDaniel Sanders static DecodeStatus 4165c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4175c582b2fSDaniel Sanders const void *Decoder); 4185c582b2fSDaniel Sanders 41928a0ca07SZoran Jovanovic template <typename InsnType> 42028a0ca07SZoran Jovanovic static DecodeStatus 42128a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 42228a0ca07SZoran Jovanovic const void *Decoder); 42328a0ca07SZoran Jovanovic 424a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn, 425a4c4b5fcSZoran Jovanovic uint64_t Address, 426a4c4b5fcSZoran Jovanovic const void *Decoder); 427a4c4b5fcSZoran Jovanovic 428f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 429f9a02500SZoran Jovanovic uint64_t Address, 430f9a02500SZoran Jovanovic const void *Decoder); 431f9a02500SZoran Jovanovic 43241688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn, 43341688679SZoran Jovanovic uint64_t Address, 43441688679SZoran Jovanovic const void *Decoder); 43541688679SZoran Jovanovic 43671928e68SAkira Hatanaka namespace llvm { 43771928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 43871928e68SAkira Hatanaka TheMips64elTarget; 43971928e68SAkira Hatanaka } 44071928e68SAkira Hatanaka 44171928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler( 44271928e68SAkira Hatanaka const Target &T, 443a1bc0f56SLang Hames const MCSubtargetInfo &STI, 444a1bc0f56SLang Hames MCContext &Ctx) { 445a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, true); 44671928e68SAkira Hatanaka } 44771928e68SAkira Hatanaka 44871928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler( 44971928e68SAkira Hatanaka const Target &T, 450a1bc0f56SLang Hames const MCSubtargetInfo &STI, 451a1bc0f56SLang Hames MCContext &Ctx) { 452a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, false); 45371928e68SAkira Hatanaka } 45471928e68SAkira Hatanaka 45571928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() { 45671928e68SAkira Hatanaka // Register the disassembler. 45771928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 45871928e68SAkira Hatanaka createMipsDisassembler); 45971928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 46071928e68SAkira Hatanaka createMipselDisassembler); 46171928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64Target, 462a19216c8SDaniel Sanders createMipsDisassembler); 46371928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 464a19216c8SDaniel Sanders createMipselDisassembler); 46571928e68SAkira Hatanaka } 46671928e68SAkira Hatanaka 46771928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc" 46871928e68SAkira Hatanaka 4695c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 470a19216c8SDaniel Sanders const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D); 4715c582b2fSDaniel Sanders const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo(); 4725c582b2fSDaniel Sanders return *(RegInfo->getRegClass(RC).begin() + RegNo); 4735c582b2fSDaniel Sanders } 4745c582b2fSDaniel Sanders 475b50ccf8eSDaniel Sanders template <typename InsnType> 476b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 477b50ccf8eSDaniel Sanders const void *Decoder) { 478b50ccf8eSDaniel Sanders typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *); 479b50ccf8eSDaniel Sanders // The size of the n field depends on the element size 480b50ccf8eSDaniel Sanders // The register class also depends on this. 481b50ccf8eSDaniel Sanders InsnType tmp = fieldFromInstruction(insn, 17, 5); 482b50ccf8eSDaniel Sanders unsigned NSize = 0; 483b50ccf8eSDaniel Sanders DecodeFN RegDecoder = nullptr; 484b50ccf8eSDaniel Sanders if ((tmp & 0x18) == 0x00) { // INSVE_B 485b50ccf8eSDaniel Sanders NSize = 4; 486b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128BRegisterClass; 487b50ccf8eSDaniel Sanders } else if ((tmp & 0x1c) == 0x10) { // INSVE_H 488b50ccf8eSDaniel Sanders NSize = 3; 489b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128HRegisterClass; 490b50ccf8eSDaniel Sanders } else if ((tmp & 0x1e) == 0x18) { // INSVE_W 491b50ccf8eSDaniel Sanders NSize = 2; 492b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128WRegisterClass; 493b50ccf8eSDaniel Sanders } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D 494b50ccf8eSDaniel Sanders NSize = 1; 495b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128DRegisterClass; 496b50ccf8eSDaniel Sanders } else 497b50ccf8eSDaniel Sanders llvm_unreachable("Invalid encoding"); 498b50ccf8eSDaniel Sanders 499b50ccf8eSDaniel Sanders assert(NSize != 0 && RegDecoder != nullptr); 500b50ccf8eSDaniel Sanders 501b50ccf8eSDaniel Sanders // $wd 502b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 6, 5); 503b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 504b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 505b50ccf8eSDaniel Sanders // $wd_in 506b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 507b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 508b50ccf8eSDaniel Sanders // $n 509b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 16, NSize); 510e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(tmp)); 511b50ccf8eSDaniel Sanders // $ws 512b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 11, 5); 513b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 514b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 515b50ccf8eSDaniel Sanders // $n2 516e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(0)); 517b50ccf8eSDaniel Sanders 518b50ccf8eSDaniel Sanders return MCDisassembler::Success; 519b50ccf8eSDaniel Sanders } 520b50ccf8eSDaniel Sanders 5215c582b2fSDaniel Sanders template <typename InsnType> 5225c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, 5235c582b2fSDaniel Sanders uint64_t Address, 5245c582b2fSDaniel Sanders const void *Decoder) { 5255c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5265c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 5275c582b2fSDaniel Sanders // ISA's instead). 5285c582b2fSDaniel Sanders // 5295c582b2fSDaniel Sanders // We have: 5305c582b2fSDaniel Sanders // 0b001000 sssss ttttt iiiiiiiiiiiiiiii 5315c582b2fSDaniel Sanders // BOVC if rs >= rt 5325c582b2fSDaniel Sanders // BEQZALC if rs == 0 && rt != 0 5335c582b2fSDaniel Sanders // BEQC if rs < rt && rs != 0 5345c582b2fSDaniel Sanders 5355c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 5365c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 537d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 5385c582b2fSDaniel Sanders bool HasRs = false; 5395c582b2fSDaniel Sanders 5405c582b2fSDaniel Sanders if (Rs >= Rt) { 5415c582b2fSDaniel Sanders MI.setOpcode(Mips::BOVC); 5425c582b2fSDaniel Sanders HasRs = true; 5435c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 5445c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQC); 5455c582b2fSDaniel Sanders HasRs = true; 5465c582b2fSDaniel Sanders } else 5475c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQZALC); 5485c582b2fSDaniel Sanders 5495c582b2fSDaniel Sanders if (HasRs) 550e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 5515c582b2fSDaniel Sanders Rs))); 5525c582b2fSDaniel Sanders 553e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 5545c582b2fSDaniel Sanders Rt))); 555e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 5565c582b2fSDaniel Sanders 5575c582b2fSDaniel Sanders return MCDisassembler::Success; 5585c582b2fSDaniel Sanders } 5595c582b2fSDaniel Sanders 5605c582b2fSDaniel Sanders template <typename InsnType> 5615c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, 5625c582b2fSDaniel Sanders uint64_t Address, 5635c582b2fSDaniel Sanders const void *Decoder) { 5645c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5655c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 5665c582b2fSDaniel Sanders // ISA's instead). 5675c582b2fSDaniel Sanders // 5685c582b2fSDaniel Sanders // We have: 5695c582b2fSDaniel Sanders // 0b011000 sssss ttttt iiiiiiiiiiiiiiii 5705c582b2fSDaniel Sanders // BNVC if rs >= rt 5715c582b2fSDaniel Sanders // BNEZALC if rs == 0 && rt != 0 5725c582b2fSDaniel Sanders // BNEC if rs < rt && rs != 0 5735c582b2fSDaniel Sanders 5745c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 5755c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 576d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 5775c582b2fSDaniel Sanders bool HasRs = false; 5785c582b2fSDaniel Sanders 5795c582b2fSDaniel Sanders if (Rs >= Rt) { 5805c582b2fSDaniel Sanders MI.setOpcode(Mips::BNVC); 5815c582b2fSDaniel Sanders HasRs = true; 5825c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 5835c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEC); 5845c582b2fSDaniel Sanders HasRs = true; 5855c582b2fSDaniel Sanders } else 5865c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEZALC); 5875c582b2fSDaniel Sanders 5885c582b2fSDaniel Sanders if (HasRs) 589e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 5905c582b2fSDaniel Sanders Rs))); 5915c582b2fSDaniel Sanders 592e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 5935c582b2fSDaniel Sanders Rt))); 594e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 5955c582b2fSDaniel Sanders 5965c582b2fSDaniel Sanders return MCDisassembler::Success; 5975c582b2fSDaniel Sanders } 5985c582b2fSDaniel Sanders 5995c582b2fSDaniel Sanders template <typename InsnType> 6005c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, 6015c582b2fSDaniel Sanders uint64_t Address, 6025c582b2fSDaniel Sanders const void *Decoder) { 6035c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6045c582b2fSDaniel Sanders // (otherwise we would have matched the BLEZL instruction from the earlier 6055c582b2fSDaniel Sanders // ISA's instead). 6065c582b2fSDaniel Sanders // 6075c582b2fSDaniel Sanders // We have: 6085c582b2fSDaniel Sanders // 0b010110 sssss ttttt iiiiiiiiiiiiiiii 6095c582b2fSDaniel Sanders // Invalid if rs == 0 6105c582b2fSDaniel Sanders // BLEZC if rs == 0 && rt != 0 6115c582b2fSDaniel Sanders // BGEZC if rs == rt && rt != 0 6125c582b2fSDaniel Sanders // BGEC if rs != rt && rs != 0 && rt != 0 6135c582b2fSDaniel Sanders 6145c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6155c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 616d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 61728a0ca07SZoran Jovanovic bool HasRs = false; 6185c582b2fSDaniel Sanders 6195c582b2fSDaniel Sanders if (Rt == 0) 6205c582b2fSDaniel Sanders return MCDisassembler::Fail; 6215c582b2fSDaniel Sanders else if (Rs == 0) 6225c582b2fSDaniel Sanders MI.setOpcode(Mips::BLEZC); 6235c582b2fSDaniel Sanders else if (Rs == Rt) 6245c582b2fSDaniel Sanders MI.setOpcode(Mips::BGEZC); 62528a0ca07SZoran Jovanovic else { 62628a0ca07SZoran Jovanovic HasRs = true; 62728a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEC); 62828a0ca07SZoran Jovanovic } 62928a0ca07SZoran Jovanovic 63028a0ca07SZoran Jovanovic if (HasRs) 631e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 63228a0ca07SZoran Jovanovic Rs))); 6335c582b2fSDaniel Sanders 634e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 6355c582b2fSDaniel Sanders Rt))); 6365c582b2fSDaniel Sanders 637e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 6385c582b2fSDaniel Sanders 6395c582b2fSDaniel Sanders return MCDisassembler::Success; 6405c582b2fSDaniel Sanders } 6415c582b2fSDaniel Sanders 6425c582b2fSDaniel Sanders template <typename InsnType> 6435c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, 6445c582b2fSDaniel Sanders uint64_t Address, 6455c582b2fSDaniel Sanders const void *Decoder) { 6465c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6475c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZL instruction from the earlier 6485c582b2fSDaniel Sanders // ISA's instead). 6495c582b2fSDaniel Sanders // 6505c582b2fSDaniel Sanders // We have: 6515c582b2fSDaniel Sanders // 0b010111 sssss ttttt iiiiiiiiiiiiiiii 6525c582b2fSDaniel Sanders // Invalid if rs == 0 6535c582b2fSDaniel Sanders // BGTZC if rs == 0 && rt != 0 6545c582b2fSDaniel Sanders // BLTZC if rs == rt && rt != 0 6555c582b2fSDaniel Sanders // BLTC if rs != rt && rs != 0 && rt != 0 6565c582b2fSDaniel Sanders 6575c14b069SZoran Jovanovic bool HasRs = false; 6585c14b069SZoran Jovanovic 6595c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6605c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 661d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 6625c582b2fSDaniel Sanders 6635c582b2fSDaniel Sanders if (Rt == 0) 6645c582b2fSDaniel Sanders return MCDisassembler::Fail; 6655c582b2fSDaniel Sanders else if (Rs == 0) 6665c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZC); 6675c582b2fSDaniel Sanders else if (Rs == Rt) 6685c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZC); 6695c14b069SZoran Jovanovic else { 6705c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTC); 6715c14b069SZoran Jovanovic HasRs = true; 6725c14b069SZoran Jovanovic } 6735c14b069SZoran Jovanovic 6745c14b069SZoran Jovanovic if (HasRs) 675e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 6765c14b069SZoran Jovanovic Rs))); 6775c582b2fSDaniel Sanders 678e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 6795c582b2fSDaniel Sanders Rt))); 6805c582b2fSDaniel Sanders 681e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 6825c582b2fSDaniel Sanders 6835c582b2fSDaniel Sanders return MCDisassembler::Success; 6845c582b2fSDaniel Sanders } 6855c582b2fSDaniel Sanders 6865c582b2fSDaniel Sanders template <typename InsnType> 6875c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, 6885c582b2fSDaniel Sanders uint64_t Address, 6895c582b2fSDaniel Sanders const void *Decoder) { 6905c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6915c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZ instruction from the earlier 6925c582b2fSDaniel Sanders // ISA's instead). 6935c582b2fSDaniel Sanders // 6945c582b2fSDaniel Sanders // We have: 6955c582b2fSDaniel Sanders // 0b000111 sssss ttttt iiiiiiiiiiiiiiii 6965c582b2fSDaniel Sanders // BGTZ if rt == 0 6975c582b2fSDaniel Sanders // BGTZALC if rs == 0 && rt != 0 6985c582b2fSDaniel Sanders // BLTZALC if rs != 0 && rs == rt 6995c582b2fSDaniel Sanders // BLTUC if rs != 0 && rs != rt 7005c582b2fSDaniel Sanders 7015c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 7025c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 703d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 7045c582b2fSDaniel Sanders bool HasRs = false; 7055c582b2fSDaniel Sanders bool HasRt = false; 7065c582b2fSDaniel Sanders 7075c582b2fSDaniel Sanders if (Rt == 0) { 7085c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZ); 7095c582b2fSDaniel Sanders HasRs = true; 7105c582b2fSDaniel Sanders } else if (Rs == 0) { 7115c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZALC); 7125c582b2fSDaniel Sanders HasRt = true; 7135c582b2fSDaniel Sanders } else if (Rs == Rt) { 7145c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZALC); 7155c582b2fSDaniel Sanders HasRs = true; 7165c14b069SZoran Jovanovic } else { 7175c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTUC); 7185c14b069SZoran Jovanovic HasRs = true; 7195c14b069SZoran Jovanovic HasRt = true; 7205c14b069SZoran Jovanovic } 7215c582b2fSDaniel Sanders 7225c582b2fSDaniel Sanders if (HasRs) 723e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 7245c582b2fSDaniel Sanders Rs))); 7255c582b2fSDaniel Sanders 7265c582b2fSDaniel Sanders if (HasRt) 727e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 7285c582b2fSDaniel Sanders Rt))); 7295c582b2fSDaniel Sanders 730e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 7315c582b2fSDaniel Sanders 7325c582b2fSDaniel Sanders return MCDisassembler::Success; 7335c582b2fSDaniel Sanders } 7345c582b2fSDaniel Sanders 73528a0ca07SZoran Jovanovic template <typename InsnType> 73628a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn, 73728a0ca07SZoran Jovanovic uint64_t Address, 73828a0ca07SZoran Jovanovic const void *Decoder) { 73928a0ca07SZoran Jovanovic // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 74028a0ca07SZoran Jovanovic // (otherwise we would have matched the BLEZL instruction from the earlier 74128a0ca07SZoran Jovanovic // ISA's instead). 74228a0ca07SZoran Jovanovic // 74328a0ca07SZoran Jovanovic // We have: 74428a0ca07SZoran Jovanovic // 0b000110 sssss ttttt iiiiiiiiiiiiiiii 74528a0ca07SZoran Jovanovic // Invalid if rs == 0 74628a0ca07SZoran Jovanovic // BLEZALC if rs == 0 && rt != 0 74728a0ca07SZoran Jovanovic // BGEZALC if rs == rt && rt != 0 74828a0ca07SZoran Jovanovic // BGEUC if rs != rt && rs != 0 && rt != 0 74928a0ca07SZoran Jovanovic 75028a0ca07SZoran Jovanovic InsnType Rs = fieldFromInstruction(insn, 21, 5); 75128a0ca07SZoran Jovanovic InsnType Rt = fieldFromInstruction(insn, 16, 5); 752d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 75328a0ca07SZoran Jovanovic bool HasRs = false; 75428a0ca07SZoran Jovanovic 75528a0ca07SZoran Jovanovic if (Rt == 0) 75628a0ca07SZoran Jovanovic return MCDisassembler::Fail; 75728a0ca07SZoran Jovanovic else if (Rs == 0) 75828a0ca07SZoran Jovanovic MI.setOpcode(Mips::BLEZALC); 75928a0ca07SZoran Jovanovic else if (Rs == Rt) 76028a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEZALC); 76128a0ca07SZoran Jovanovic else { 76228a0ca07SZoran Jovanovic HasRs = true; 76328a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEUC); 76428a0ca07SZoran Jovanovic } 76528a0ca07SZoran Jovanovic 76628a0ca07SZoran Jovanovic if (HasRs) 767e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 76828a0ca07SZoran Jovanovic Rs))); 769e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 77028a0ca07SZoran Jovanovic Rt))); 77128a0ca07SZoran Jovanovic 772e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 77328a0ca07SZoran Jovanovic 77428a0ca07SZoran Jovanovic return MCDisassembler::Success; 77528a0ca07SZoran Jovanovic } 77628a0ca07SZoran Jovanovic 777ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted 778ea22c4cfSJozef Kolek /// according to the given endianess. 779ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 780ea22c4cfSJozef Kolek uint64_t &Size, uint32_t &Insn, 781ea22c4cfSJozef Kolek bool IsBigEndian) { 782ea22c4cfSJozef Kolek // We want to read exactly 2 Bytes of data. 783ea22c4cfSJozef Kolek if (Bytes.size() < 2) { 784ea22c4cfSJozef Kolek Size = 0; 785ea22c4cfSJozef Kolek return MCDisassembler::Fail; 786ea22c4cfSJozef Kolek } 787ea22c4cfSJozef Kolek 788ea22c4cfSJozef Kolek if (IsBigEndian) { 789ea22c4cfSJozef Kolek Insn = (Bytes[0] << 8) | Bytes[1]; 790ea22c4cfSJozef Kolek } else { 791ea22c4cfSJozef Kolek Insn = (Bytes[1] << 8) | Bytes[0]; 792ea22c4cfSJozef Kolek } 793ea22c4cfSJozef Kolek 794ea22c4cfSJozef Kolek return MCDisassembler::Success; 795ea22c4cfSJozef Kolek } 796ea22c4cfSJozef Kolek 7977fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted 7984aa6bea7SRafael Espindola /// according to the given endianess 7997fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 8007fc5b874SRafael Espindola uint64_t &Size, uint32_t &Insn, 8017fc5b874SRafael Espindola bool IsBigEndian, bool IsMicroMips) { 80271928e68SAkira Hatanaka // We want to read exactly 4 Bytes of data. 8037fc5b874SRafael Espindola if (Bytes.size() < 4) { 8044aa6bea7SRafael Espindola Size = 0; 80571928e68SAkira Hatanaka return MCDisassembler::Fail; 80671928e68SAkira Hatanaka } 80771928e68SAkira Hatanaka 808ea22c4cfSJozef Kolek // High 16 bits of a 32-bit microMIPS instruction (where the opcode is) 809ea22c4cfSJozef Kolek // always precede the low 16 bits in the instruction stream (that is, they 810ea22c4cfSJozef Kolek // are placed at lower addresses in the instruction stream). 811ea22c4cfSJozef Kolek // 812ea22c4cfSJozef Kolek // microMIPS byte ordering: 813ea22c4cfSJozef Kolek // Big-endian: 0 | 1 | 2 | 3 814ea22c4cfSJozef Kolek // Little-endian: 1 | 0 | 3 | 2 815ea22c4cfSJozef Kolek 8164aa6bea7SRafael Espindola if (IsBigEndian) { 81771928e68SAkira Hatanaka // Encoded as a big-endian 32-bit word in the stream. 8184aa6bea7SRafael Espindola Insn = 8194aa6bea7SRafael Espindola (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24); 8204aa6bea7SRafael Espindola } else { 821dde3d582SVladimir Medic if (IsMicroMips) { 8224aa6bea7SRafael Espindola Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) | 823dde3d582SVladimir Medic (Bytes[1] << 24); 824dde3d582SVladimir Medic } else { 8254aa6bea7SRafael Espindola Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | 82671928e68SAkira Hatanaka (Bytes[3] << 24); 82771928e68SAkira Hatanaka } 828dde3d582SVladimir Medic } 82971928e68SAkira Hatanaka 83071928e68SAkira Hatanaka return MCDisassembler::Success; 83171928e68SAkira Hatanaka } 83271928e68SAkira Hatanaka 8334aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 8347fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 83571928e68SAkira Hatanaka uint64_t Address, 8364aa6bea7SRafael Espindola raw_ostream &VStream, 8374aa6bea7SRafael Espindola raw_ostream &CStream) const { 83871928e68SAkira Hatanaka uint32_t Insn; 839ea22c4cfSJozef Kolek DecodeStatus Result; 84071928e68SAkira Hatanaka 841ea22c4cfSJozef Kolek if (IsMicroMips) { 842ea22c4cfSJozef Kolek Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); 843ea22c4cfSJozef Kolek 844ada70918SZoran Jovanovic if (hasMips32r6()) { 845ada70918SZoran Jovanovic DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n"); 846ada70918SZoran Jovanovic // Calling the auto-generated decoder function for microMIPS32R6 847ada70918SZoran Jovanovic // (and microMIPS64R6) 16-bit instructions. 848ada70918SZoran Jovanovic Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn, 849ada70918SZoran Jovanovic Address, this, STI); 850ada70918SZoran Jovanovic if (Result != MCDisassembler::Fail) { 851ada70918SZoran Jovanovic Size = 2; 852ada70918SZoran Jovanovic return Result; 853ada70918SZoran Jovanovic } 854ada70918SZoran Jovanovic } 855ada70918SZoran Jovanovic 856ea22c4cfSJozef Kolek DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n"); 857ada70918SZoran Jovanovic // Calling the auto-generated decoder function for microMIPS 16-bit 858ada70918SZoran Jovanovic // instructions. 859ea22c4cfSJozef Kolek Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address, 860ea22c4cfSJozef Kolek this, STI); 861ea22c4cfSJozef Kolek if (Result != MCDisassembler::Fail) { 862ea22c4cfSJozef Kolek Size = 2; 863ea22c4cfSJozef Kolek return Result; 864ea22c4cfSJozef Kolek } 865ea22c4cfSJozef Kolek 866ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true); 86771928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 86871928e68SAkira Hatanaka return MCDisassembler::Fail; 86971928e68SAkira Hatanaka 870676d6012SJozef Kolek if (hasMips32r6()) { 871676d6012SJozef Kolek DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n"); 872676d6012SJozef Kolek // Calling the auto-generated decoder function. 873366783e1SZoran Jovanovic Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address, 874676d6012SJozef Kolek this, STI); 875ada70918SZoran Jovanovic if (Result != MCDisassembler::Fail) { 876ada70918SZoran Jovanovic Size = 4; 877ada70918SZoran Jovanovic return Result; 878ada70918SZoran Jovanovic } 879ada70918SZoran Jovanovic } 880ada70918SZoran Jovanovic 881ea22c4cfSJozef Kolek DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); 882dde3d582SVladimir Medic // Calling the auto-generated decoder function. 8834aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, 884dde3d582SVladimir Medic this, STI); 885dde3d582SVladimir Medic if (Result != MCDisassembler::Fail) { 886dde3d582SVladimir Medic Size = 4; 887dde3d582SVladimir Medic return Result; 888dde3d582SVladimir Medic } 889dde3d582SVladimir Medic return MCDisassembler::Fail; 890dde3d582SVladimir Medic } 891dde3d582SVladimir Medic 892ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); 893ea22c4cfSJozef Kolek if (Result == MCDisassembler::Fail) 894ea22c4cfSJozef Kolek return MCDisassembler::Fail; 895ea22c4cfSJozef Kolek 896c171f65aSDaniel Sanders if (hasCOP3()) { 897c171f65aSDaniel Sanders DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n"); 898c171f65aSDaniel Sanders Result = 8994aa6bea7SRafael Espindola decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI); 900c171f65aSDaniel Sanders if (Result != MCDisassembler::Fail) { 901c171f65aSDaniel Sanders Size = 4; 902c171f65aSDaniel Sanders return Result; 903c171f65aSDaniel Sanders } 904c171f65aSDaniel Sanders } 905c171f65aSDaniel Sanders 906c171f65aSDaniel Sanders if (hasMips32r6() && isGP64()) { 9070fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n"); 9084aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn, 9090fa60416SDaniel Sanders Address, this, STI); 9100fa60416SDaniel Sanders if (Result != MCDisassembler::Fail) { 9110fa60416SDaniel Sanders Size = 4; 9120fa60416SDaniel Sanders return Result; 9130fa60416SDaniel Sanders } 9140fa60416SDaniel Sanders } 9150fa60416SDaniel Sanders 916c171f65aSDaniel Sanders if (hasMips32r6()) { 9170fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n"); 9184aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn, 9195c582b2fSDaniel Sanders Address, this, STI); 9205c582b2fSDaniel Sanders if (Result != MCDisassembler::Fail) { 9215c582b2fSDaniel Sanders Size = 4; 9225c582b2fSDaniel Sanders return Result; 9235c582b2fSDaniel Sanders } 9245c582b2fSDaniel Sanders } 9255c582b2fSDaniel Sanders 9263adf9b8dSKai Nacke if (hasCnMips()) { 9273adf9b8dSKai Nacke DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n"); 9283adf9b8dSKai Nacke Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn, 9293adf9b8dSKai Nacke Address, this, STI); 9303adf9b8dSKai Nacke if (Result != MCDisassembler::Fail) { 9313adf9b8dSKai Nacke Size = 4; 9323adf9b8dSKai Nacke return Result; 9333adf9b8dSKai Nacke } 9343adf9b8dSKai Nacke } 9353adf9b8dSKai Nacke 936a19216c8SDaniel Sanders if (isGP64()) { 937a19216c8SDaniel Sanders DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n"); 938a19216c8SDaniel Sanders Result = decodeInstruction(DecoderTableMips6432, Instr, Insn, 939a19216c8SDaniel Sanders Address, this, STI); 940a19216c8SDaniel Sanders if (Result != MCDisassembler::Fail) { 941a19216c8SDaniel Sanders Size = 4; 942a19216c8SDaniel Sanders return Result; 943a19216c8SDaniel Sanders } 944a19216c8SDaniel Sanders } 945a19216c8SDaniel Sanders 9460fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n"); 94771928e68SAkira Hatanaka // Calling the auto-generated decoder function. 9484aa6bea7SRafael Espindola Result = 9494aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI); 95071928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 95171928e68SAkira Hatanaka Size = 4; 95271928e68SAkira Hatanaka return Result; 95371928e68SAkira Hatanaka } 95471928e68SAkira Hatanaka 95571928e68SAkira Hatanaka return MCDisassembler::Fail; 95671928e68SAkira Hatanaka } 95771928e68SAkira Hatanaka 958ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 959ec8a5490SReed Kotler unsigned RegNo, 960ec8a5490SReed Kotler uint64_t Address, 961ec8a5490SReed Kotler const void *Decoder) { 962ec8a5490SReed Kotler 963ec8a5490SReed Kotler return MCDisassembler::Fail; 964ec8a5490SReed Kotler 965ec8a5490SReed Kotler } 966ec8a5490SReed Kotler 96713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 96871928e68SAkira Hatanaka unsigned RegNo, 96971928e68SAkira Hatanaka uint64_t Address, 97071928e68SAkira Hatanaka const void *Decoder) { 97171928e68SAkira Hatanaka 97271928e68SAkira Hatanaka if (RegNo > 31) 97371928e68SAkira Hatanaka return MCDisassembler::Fail; 97471928e68SAkira Hatanaka 97513e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); 976e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 97771928e68SAkira Hatanaka return MCDisassembler::Success; 97871928e68SAkira Hatanaka } 97971928e68SAkira Hatanaka 980b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, 981b0852e54SZoran Jovanovic unsigned RegNo, 982b0852e54SZoran Jovanovic uint64_t Address, 983b0852e54SZoran Jovanovic const void *Decoder) { 984ea22c4cfSJozef Kolek if (RegNo > 7) 985b0852e54SZoran Jovanovic return MCDisassembler::Fail; 986ea22c4cfSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo); 987e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 988ea22c4cfSJozef Kolek return MCDisassembler::Success; 989b0852e54SZoran Jovanovic } 990b0852e54SZoran Jovanovic 9911904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, 9921904fa21SJozef Kolek unsigned RegNo, 9931904fa21SJozef Kolek uint64_t Address, 9941904fa21SJozef Kolek const void *Decoder) { 995315e7ecaSJozef Kolek if (RegNo > 7) 9961904fa21SJozef Kolek return MCDisassembler::Fail; 997315e7ecaSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo); 998e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 999315e7ecaSJozef Kolek return MCDisassembler::Success; 10001904fa21SJozef Kolek } 10011904fa21SJozef Kolek 100241688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst, 100341688679SZoran Jovanovic unsigned RegNo, 100441688679SZoran Jovanovic uint64_t Address, 100541688679SZoran Jovanovic const void *Decoder) { 100641688679SZoran Jovanovic if (RegNo > 7) 100741688679SZoran Jovanovic return MCDisassembler::Fail; 100841688679SZoran Jovanovic unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo); 1009e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 101041688679SZoran Jovanovic return MCDisassembler::Success; 101141688679SZoran Jovanovic } 101241688679SZoran Jovanovic 101313e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 101471928e68SAkira Hatanaka unsigned RegNo, 101571928e68SAkira Hatanaka uint64_t Address, 101671928e68SAkira Hatanaka const void *Decoder) { 101771928e68SAkira Hatanaka if (RegNo > 31) 101871928e68SAkira Hatanaka return MCDisassembler::Fail; 101913e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); 1020e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 102171928e68SAkira Hatanaka return MCDisassembler::Success; 102271928e68SAkira Hatanaka } 102371928e68SAkira Hatanaka 10249bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 10259bfa2e2eSAkira Hatanaka unsigned RegNo, 10269bfa2e2eSAkira Hatanaka uint64_t Address, 10279bfa2e2eSAkira Hatanaka const void *Decoder) { 1028a19216c8SDaniel Sanders if (static_cast<const MipsDisassembler *>(Decoder)->isGP64()) 10299bfa2e2eSAkira Hatanaka return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); 10309bfa2e2eSAkira Hatanaka 10319bfa2e2eSAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 10329bfa2e2eSAkira Hatanaka } 10339bfa2e2eSAkira Hatanaka 1034654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 1035ecabd1a5SAkira Hatanaka unsigned RegNo, 1036ecabd1a5SAkira Hatanaka uint64_t Address, 1037ecabd1a5SAkira Hatanaka const void *Decoder) { 103813e6ccf3SAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 1039ecabd1a5SAkira Hatanaka } 1040ecabd1a5SAkira Hatanaka 104171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 104271928e68SAkira Hatanaka unsigned RegNo, 104371928e68SAkira Hatanaka uint64_t Address, 104471928e68SAkira Hatanaka const void *Decoder) { 104571928e68SAkira Hatanaka if (RegNo > 31) 104671928e68SAkira Hatanaka return MCDisassembler::Fail; 104771928e68SAkira Hatanaka 10489bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 1049e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 105071928e68SAkira Hatanaka return MCDisassembler::Success; 105171928e68SAkira Hatanaka } 105271928e68SAkira Hatanaka 105371928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 105471928e68SAkira Hatanaka unsigned RegNo, 105571928e68SAkira Hatanaka uint64_t Address, 105671928e68SAkira Hatanaka const void *Decoder) { 105771928e68SAkira Hatanaka if (RegNo > 31) 105871928e68SAkira Hatanaka return MCDisassembler::Fail; 105971928e68SAkira Hatanaka 10609bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 1061e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 106271928e68SAkira Hatanaka return MCDisassembler::Success; 106371928e68SAkira Hatanaka } 106471928e68SAkira Hatanaka 106571928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 106671928e68SAkira Hatanaka unsigned RegNo, 106771928e68SAkira Hatanaka uint64_t Address, 106871928e68SAkira Hatanaka const void *Decoder) { 1069253777fdSChad Rosier if (RegNo > 31) 1070253777fdSChad Rosier return MCDisassembler::Fail; 1071253777fdSChad Rosier unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); 1072e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 107371928e68SAkira Hatanaka return MCDisassembler::Success; 107471928e68SAkira Hatanaka } 107571928e68SAkira Hatanaka 10761fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 10771fb1b8b8SAkira Hatanaka unsigned RegNo, 10781fb1b8b8SAkira Hatanaka uint64_t Address, 10791fb1b8b8SAkira Hatanaka const void *Decoder) { 10801fb1b8b8SAkira Hatanaka if (RegNo > 7) 10811fb1b8b8SAkira Hatanaka return MCDisassembler::Fail; 10821fb1b8b8SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); 1083e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 10841fb1b8b8SAkira Hatanaka return MCDisassembler::Success; 10851fb1b8b8SAkira Hatanaka } 10861fb1b8b8SAkira Hatanaka 10870fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, 10880fa60416SDaniel Sanders uint64_t Address, 10890fa60416SDaniel Sanders const void *Decoder) { 10900fa60416SDaniel Sanders if (RegNo > 31) 10910fa60416SDaniel Sanders return MCDisassembler::Fail; 10920fa60416SDaniel Sanders 10930fa60416SDaniel Sanders unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo); 1094e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 10950fa60416SDaniel Sanders return MCDisassembler::Success; 10960fa60416SDaniel Sanders } 10970fa60416SDaniel Sanders 109871928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 109971928e68SAkira Hatanaka unsigned Insn, 110071928e68SAkira Hatanaka uint64_t Address, 110171928e68SAkira Hatanaka const void *Decoder) { 110271928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1103ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1104ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 11059bf2b567SAkira Hatanaka 110613e6ccf3SAkira Hatanaka Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 110713e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 110871928e68SAkira Hatanaka 1109d7ecf49eSVladimir Medic if(Inst.getOpcode() == Mips::SC || 1110d7ecf49eSVladimir Medic Inst.getOpcode() == Mips::SCD){ 1111e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 111271928e68SAkira Hatanaka } 111371928e68SAkira Hatanaka 1114e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1115e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1116e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 111771928e68SAkira Hatanaka 111871928e68SAkira Hatanaka return MCDisassembler::Success; 111971928e68SAkira Hatanaka } 112071928e68SAkira Hatanaka 112192db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 112292db6b78SDaniel Sanders unsigned Insn, 112392db6b78SDaniel Sanders uint64_t Address, 112492db6b78SDaniel Sanders const void *Decoder) { 112592db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 112692db6b78SDaniel Sanders unsigned Hint = fieldFromInstruction(Insn, 16, 5); 112792db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 112892db6b78SDaniel Sanders 112992db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 113092db6b78SDaniel Sanders 1131e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1132e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1133e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Hint)); 113492db6b78SDaniel Sanders 113592db6b78SDaniel Sanders return MCDisassembler::Success; 113692db6b78SDaniel Sanders } 113792db6b78SDaniel Sanders 1138ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst, 1139ab6d1cceSJozef Kolek unsigned Insn, 1140ab6d1cceSJozef Kolek uint64_t Address, 1141ab6d1cceSJozef Kolek const void *Decoder) { 1142ab6d1cceSJozef Kolek int Offset = SignExtend32<12>(Insn & 0xfff); 1143ab6d1cceSJozef Kolek unsigned Base = fieldFromInstruction(Insn, 16, 5); 1144ab6d1cceSJozef Kolek unsigned Hint = fieldFromInstruction(Insn, 21, 5); 1145ab6d1cceSJozef Kolek 1146ab6d1cceSJozef Kolek Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1147ab6d1cceSJozef Kolek 1148e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1149e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1150e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Hint)); 1151ab6d1cceSJozef Kolek 1152ab6d1cceSJozef Kolek return MCDisassembler::Success; 1153ab6d1cceSJozef Kolek } 1154ab6d1cceSJozef Kolek 1155df464ae2SVladimir Medic static DecodeStatus DecodeCacheOpR6(MCInst &Inst, 1156df464ae2SVladimir Medic unsigned Insn, 1157df464ae2SVladimir Medic uint64_t Address, 1158df464ae2SVladimir Medic const void *Decoder) { 1159df464ae2SVladimir Medic int Offset = fieldFromInstruction(Insn, 7, 9); 1160df464ae2SVladimir Medic unsigned Hint = fieldFromInstruction(Insn, 16, 5); 1161df464ae2SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 21, 5); 1162df464ae2SVladimir Medic 1163df464ae2SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1164df464ae2SVladimir Medic 1165e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1166e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1167e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Hint)); 1168df464ae2SVladimir Medic 1169df464ae2SVladimir Medic return MCDisassembler::Success; 1170df464ae2SVladimir Medic } 1171df464ae2SVladimir Medic 1172*9eaa30d2SZoran Jovanovic static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst, 1173*9eaa30d2SZoran Jovanovic unsigned Insn, 1174*9eaa30d2SZoran Jovanovic uint64_t Address, 1175*9eaa30d2SZoran Jovanovic const void *Decoder) { 1176*9eaa30d2SZoran Jovanovic int Offset = SignExtend32<9>(Insn & 0x1ff); 1177*9eaa30d2SZoran Jovanovic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1178*9eaa30d2SZoran Jovanovic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1179*9eaa30d2SZoran Jovanovic 1180*9eaa30d2SZoran Jovanovic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1181*9eaa30d2SZoran Jovanovic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1182*9eaa30d2SZoran Jovanovic 1183*9eaa30d2SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Reg)); 1184*9eaa30d2SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Base)); 1185*9eaa30d2SZoran Jovanovic Inst.addOperand(MCOperand::createImm(Offset)); 1186*9eaa30d2SZoran Jovanovic 1187*9eaa30d2SZoran Jovanovic return MCDisassembler::Success; 1188*9eaa30d2SZoran Jovanovic } 1189*9eaa30d2SZoran Jovanovic 1190b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 1191b4484d62SDaniel Sanders unsigned Insn, 1192b4484d62SDaniel Sanders uint64_t Address, 1193b4484d62SDaniel Sanders const void *Decoder) { 1194b4484d62SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 1195b4484d62SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 1196b4484d62SDaniel Sanders 1197b4484d62SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1198b4484d62SDaniel Sanders 1199e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1200e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1201b4484d62SDaniel Sanders 1202b4484d62SDaniel Sanders return MCDisassembler::Success; 1203b4484d62SDaniel Sanders } 1204b4484d62SDaniel Sanders 1205fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 1206fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder) { 1207fe0bf9f6SMatheus Almeida int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10)); 1208fe0bf9f6SMatheus Almeida unsigned Reg = fieldFromInstruction(Insn, 6, 5); 1209fe0bf9f6SMatheus Almeida unsigned Base = fieldFromInstruction(Insn, 11, 5); 1210fe0bf9f6SMatheus Almeida 1211fe0bf9f6SMatheus Almeida Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg); 1212fe0bf9f6SMatheus Almeida Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1213fe0bf9f6SMatheus Almeida 1214e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1215e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 12166b59c449SMatheus Almeida 12176b59c449SMatheus Almeida // The immediate field of an LD/ST instruction is scaled which means it must 12186b59c449SMatheus Almeida // be multiplied (when decoding) by the size (in bytes) of the instructions' 12196b59c449SMatheus Almeida // data format. 12206b59c449SMatheus Almeida // .b - 1 byte 12216b59c449SMatheus Almeida // .h - 2 bytes 12226b59c449SMatheus Almeida // .w - 4 bytes 12236b59c449SMatheus Almeida // .d - 8 bytes 12246b59c449SMatheus Almeida switch(Inst.getOpcode()) 12256b59c449SMatheus Almeida { 12266b59c449SMatheus Almeida default: 12276b59c449SMatheus Almeida assert (0 && "Unexpected instruction"); 12286b59c449SMatheus Almeida return MCDisassembler::Fail; 12296b59c449SMatheus Almeida break; 12306b59c449SMatheus Almeida case Mips::LD_B: 12316b59c449SMatheus Almeida case Mips::ST_B: 1232e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 12336b59c449SMatheus Almeida break; 12346b59c449SMatheus Almeida case Mips::LD_H: 12356b59c449SMatheus Almeida case Mips::ST_H: 1236e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset * 2)); 12376b59c449SMatheus Almeida break; 12386b59c449SMatheus Almeida case Mips::LD_W: 12396b59c449SMatheus Almeida case Mips::ST_W: 1240e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset * 4)); 12416b59c449SMatheus Almeida break; 12426b59c449SMatheus Almeida case Mips::LD_D: 12436b59c449SMatheus Almeida case Mips::ST_D: 1244e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset * 8)); 12456b59c449SMatheus Almeida break; 12466b59c449SMatheus Almeida } 1247fe0bf9f6SMatheus Almeida 1248fe0bf9f6SMatheus Almeida return MCDisassembler::Success; 1249fe0bf9f6SMatheus Almeida } 1250fe0bf9f6SMatheus Almeida 1251315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 1252315e7ecaSJozef Kolek unsigned Insn, 1253315e7ecaSJozef Kolek uint64_t Address, 1254315e7ecaSJozef Kolek const void *Decoder) { 1255315e7ecaSJozef Kolek unsigned Offset = Insn & 0xf; 1256315e7ecaSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 7, 3); 1257315e7ecaSJozef Kolek unsigned Base = fieldFromInstruction(Insn, 4, 3); 1258315e7ecaSJozef Kolek 1259315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1260315e7ecaSJozef Kolek case Mips::LBU16_MM: 1261315e7ecaSJozef Kolek case Mips::LHU16_MM: 1262315e7ecaSJozef Kolek case Mips::LW16_MM: 1263315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder) 1264315e7ecaSJozef Kolek == MCDisassembler::Fail) 1265315e7ecaSJozef Kolek return MCDisassembler::Fail; 1266315e7ecaSJozef Kolek break; 1267315e7ecaSJozef Kolek case Mips::SB16_MM: 1268315e7ecaSJozef Kolek case Mips::SH16_MM: 1269315e7ecaSJozef Kolek case Mips::SW16_MM: 1270315e7ecaSJozef Kolek if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder) 1271315e7ecaSJozef Kolek == MCDisassembler::Fail) 1272315e7ecaSJozef Kolek return MCDisassembler::Fail; 1273315e7ecaSJozef Kolek break; 1274315e7ecaSJozef Kolek } 1275315e7ecaSJozef Kolek 1276315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder) 1277315e7ecaSJozef Kolek == MCDisassembler::Fail) 1278315e7ecaSJozef Kolek return MCDisassembler::Fail; 1279315e7ecaSJozef Kolek 1280315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1281315e7ecaSJozef Kolek case Mips::LBU16_MM: 1282315e7ecaSJozef Kolek if (Offset == 0xf) 1283e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(-1)); 1284315e7ecaSJozef Kolek else 1285e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1286315e7ecaSJozef Kolek break; 1287315e7ecaSJozef Kolek case Mips::SB16_MM: 1288e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1289315e7ecaSJozef Kolek break; 1290315e7ecaSJozef Kolek case Mips::LHU16_MM: 1291315e7ecaSJozef Kolek case Mips::SH16_MM: 1292e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 1)); 1293315e7ecaSJozef Kolek break; 1294315e7ecaSJozef Kolek case Mips::LW16_MM: 1295315e7ecaSJozef Kolek case Mips::SW16_MM: 1296e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 1297315e7ecaSJozef Kolek break; 1298315e7ecaSJozef Kolek } 1299315e7ecaSJozef Kolek 1300315e7ecaSJozef Kolek return MCDisassembler::Success; 1301315e7ecaSJozef Kolek } 1302315e7ecaSJozef Kolek 130312c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, 130412c6982bSJozef Kolek unsigned Insn, 130512c6982bSJozef Kolek uint64_t Address, 130612c6982bSJozef Kolek const void *Decoder) { 130712c6982bSJozef Kolek unsigned Offset = Insn & 0x1F; 130812c6982bSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 5, 5); 130912c6982bSJozef Kolek 131012c6982bSJozef Kolek Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 131112c6982bSJozef Kolek 1312e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1313e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::SP)); 1314e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 131512c6982bSJozef Kolek 131612c6982bSJozef Kolek return MCDisassembler::Success; 131712c6982bSJozef Kolek } 131812c6982bSJozef Kolek 1319e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, 1320e10a02ecSJozef Kolek unsigned Insn, 1321e10a02ecSJozef Kolek uint64_t Address, 1322e10a02ecSJozef Kolek const void *Decoder) { 1323e10a02ecSJozef Kolek unsigned Offset = Insn & 0x7F; 1324e10a02ecSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 7, 3); 1325e10a02ecSJozef Kolek 1326e10a02ecSJozef Kolek Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1327e10a02ecSJozef Kolek 1328e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1329e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::GP)); 1330e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 1331e10a02ecSJozef Kolek 1332e10a02ecSJozef Kolek return MCDisassembler::Success; 1333e10a02ecSJozef Kolek } 1334e10a02ecSJozef Kolek 1335d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, 1336d68d424aSJozef Kolek unsigned Insn, 1337d68d424aSJozef Kolek uint64_t Address, 1338d68d424aSJozef Kolek const void *Decoder) { 1339d68d424aSJozef Kolek int Offset = SignExtend32<4>(Insn & 0xf); 1340d68d424aSJozef Kolek 1341d68d424aSJozef Kolek if (DecodeRegListOperand16(Inst, Insn, Address, Decoder) 1342d68d424aSJozef Kolek == MCDisassembler::Fail) 1343d68d424aSJozef Kolek return MCDisassembler::Fail; 1344d68d424aSJozef Kolek 1345e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::SP)); 1346e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 1347d68d424aSJozef Kolek 1348d68d424aSJozef Kolek return MCDisassembler::Success; 1349d68d424aSJozef Kolek } 1350d68d424aSJozef Kolek 1351a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst, 1352a6593ff6SZoran Jovanovic unsigned Insn, 1353a6593ff6SZoran Jovanovic uint64_t Address, 1354a6593ff6SZoran Jovanovic const void *Decoder) { 1355a6593ff6SZoran Jovanovic int Offset = SignExtend32<9>(Insn & 0x1ff); 1356a6593ff6SZoran Jovanovic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1357a6593ff6SZoran Jovanovic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1358a6593ff6SZoran Jovanovic 1359a6593ff6SZoran Jovanovic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1360a6593ff6SZoran Jovanovic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1361a6593ff6SZoran Jovanovic 1362a6593ff6SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Reg)); 1363a6593ff6SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Base)); 1364a6593ff6SZoran Jovanovic Inst.addOperand(MCOperand::createImm(Offset)); 1365a6593ff6SZoran Jovanovic 1366a6593ff6SZoran Jovanovic return MCDisassembler::Success; 1367a6593ff6SZoran Jovanovic } 1368a6593ff6SZoran Jovanovic 1369dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 1370dde3d582SVladimir Medic unsigned Insn, 1371dde3d582SVladimir Medic uint64_t Address, 1372dde3d582SVladimir Medic const void *Decoder) { 1373dde3d582SVladimir Medic int Offset = SignExtend32<12>(Insn & 0x0fff); 1374dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1375dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1376dde3d582SVladimir Medic 1377dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1378dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1379dde3d582SVladimir Medic 1380a4c4b5fcSZoran Jovanovic switch (Inst.getOpcode()) { 1381a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 1382a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 1383a4c4b5fcSZoran Jovanovic if (DecodeRegListOperand(Inst, Insn, Address, Decoder) 1384a4c4b5fcSZoran Jovanovic == MCDisassembler::Fail) 1385a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 1386e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1387e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1388a4c4b5fcSZoran Jovanovic break; 1389a4c4b5fcSZoran Jovanovic case Mips::SC_MM: 1390e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1391a4c4b5fcSZoran Jovanovic // fallthrough 1392a4c4b5fcSZoran Jovanovic default: 1393e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 13942deca348SZoran Jovanovic if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) 1395e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg+1)); 13962deca348SZoran Jovanovic 1397e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1398e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1399a4c4b5fcSZoran Jovanovic } 1400dde3d582SVladimir Medic 1401dde3d582SVladimir Medic return MCDisassembler::Success; 1402dde3d582SVladimir Medic } 1403dde3d582SVladimir Medic 1404dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 1405dde3d582SVladimir Medic unsigned Insn, 1406dde3d582SVladimir Medic uint64_t Address, 1407dde3d582SVladimir Medic const void *Decoder) { 1408dde3d582SVladimir Medic int Offset = SignExtend32<16>(Insn & 0xffff); 1409dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1410dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1411dde3d582SVladimir Medic 1412dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1413dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1414dde3d582SVladimir Medic 1415e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1416e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1417e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1418dde3d582SVladimir Medic 1419dde3d582SVladimir Medic return MCDisassembler::Success; 1420dde3d582SVladimir Medic } 1421dde3d582SVladimir Medic 142271928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, 142371928e68SAkira Hatanaka unsigned Insn, 142471928e68SAkira Hatanaka uint64_t Address, 142571928e68SAkira Hatanaka const void *Decoder) { 142671928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1427ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1428ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 142971928e68SAkira Hatanaka 14309bf2b567SAkira Hatanaka Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 143113e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 14329bf2b567SAkira Hatanaka 1433e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1434e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1435e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 143671928e68SAkira Hatanaka 143771928e68SAkira Hatanaka return MCDisassembler::Success; 143871928e68SAkira Hatanaka } 143971928e68SAkira Hatanaka 144092db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, 144192db6b78SDaniel Sanders unsigned Insn, 144292db6b78SDaniel Sanders uint64_t Address, 144392db6b78SDaniel Sanders const void *Decoder) { 144492db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 144592db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 144692db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 144792db6b78SDaniel Sanders 144892db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); 144992db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 145092db6b78SDaniel Sanders 1451e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1452e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1453e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 145492db6b78SDaniel Sanders 145592db6b78SDaniel Sanders return MCDisassembler::Success; 145692db6b78SDaniel Sanders } 145792db6b78SDaniel Sanders 145892db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, 145992db6b78SDaniel Sanders unsigned Insn, 146092db6b78SDaniel Sanders uint64_t Address, 146192db6b78SDaniel Sanders const void *Decoder) { 146292db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 146392db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 146492db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 146592db6b78SDaniel Sanders 146692db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP3RegClassID, Reg); 146792db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 146892db6b78SDaniel Sanders 1469e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1470e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1471e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 147292db6b78SDaniel Sanders 147392db6b78SDaniel Sanders return MCDisassembler::Success; 147492db6b78SDaniel Sanders } 147592db6b78SDaniel Sanders 1476435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, 1477435cf8a4SVladimir Medic unsigned Insn, 1478435cf8a4SVladimir Medic uint64_t Address, 1479435cf8a4SVladimir Medic const void *Decoder) { 1480435cf8a4SVladimir Medic int Offset = SignExtend32<11>(Insn & 0x07ff); 1481435cf8a4SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1482435cf8a4SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 11, 5); 1483435cf8a4SVladimir Medic 1484435cf8a4SVladimir Medic Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); 1485435cf8a4SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1486435cf8a4SVladimir Medic 1487e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1488e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1489e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1490435cf8a4SVladimir Medic 1491435cf8a4SVladimir Medic return MCDisassembler::Success; 1492435cf8a4SVladimir Medic } 14936a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 14946a803f61SDaniel Sanders unsigned Insn, 14956a803f61SDaniel Sanders uint64_t Address, 14966a803f61SDaniel Sanders const void *Decoder) { 14976a803f61SDaniel Sanders int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff); 14986a803f61SDaniel Sanders unsigned Rt = fieldFromInstruction(Insn, 16, 5); 14996a803f61SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 15006a803f61SDaniel Sanders 15016a803f61SDaniel Sanders Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt); 15026a803f61SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 15036a803f61SDaniel Sanders 15046a803f61SDaniel Sanders if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){ 1505e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Rt)); 15066a803f61SDaniel Sanders } 15076a803f61SDaniel Sanders 1508e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Rt)); 1509e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1510e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 15116a803f61SDaniel Sanders 15126a803f61SDaniel Sanders return MCDisassembler::Success; 15136a803f61SDaniel Sanders } 151471928e68SAkira Hatanaka 151571928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 151671928e68SAkira Hatanaka unsigned RegNo, 151771928e68SAkira Hatanaka uint64_t Address, 151871928e68SAkira Hatanaka const void *Decoder) { 151971928e68SAkira Hatanaka // Currently only hardware register 29 is supported. 152071928e68SAkira Hatanaka if (RegNo != 29) 152171928e68SAkira Hatanaka return MCDisassembler::Fail; 1522e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::HWR29)); 152371928e68SAkira Hatanaka return MCDisassembler::Success; 152471928e68SAkira Hatanaka } 152571928e68SAkira Hatanaka 152671928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 152771928e68SAkira Hatanaka unsigned RegNo, 152871928e68SAkira Hatanaka uint64_t Address, 152971928e68SAkira Hatanaka const void *Decoder) { 15309bf2b567SAkira Hatanaka if (RegNo > 30 || RegNo %2) 153171928e68SAkira Hatanaka return MCDisassembler::Fail; 153271928e68SAkira Hatanaka 15339bf2b567SAkira Hatanaka ; 15349bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 1535e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 153671928e68SAkira Hatanaka return MCDisassembler::Success; 153771928e68SAkira Hatanaka } 153871928e68SAkira Hatanaka 153900fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 1540ecabd1a5SAkira Hatanaka unsigned RegNo, 1541ecabd1a5SAkira Hatanaka uint64_t Address, 1542ecabd1a5SAkira Hatanaka const void *Decoder) { 1543ecabd1a5SAkira Hatanaka if (RegNo >= 4) 1544ecabd1a5SAkira Hatanaka return MCDisassembler::Fail; 1545ecabd1a5SAkira Hatanaka 154600fcf2e1SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo); 1547e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1548ecabd1a5SAkira Hatanaka return MCDisassembler::Success; 1549ecabd1a5SAkira Hatanaka } 1550ecabd1a5SAkira Hatanaka 15518002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 155259bfaf77SAkira Hatanaka unsigned RegNo, 155359bfaf77SAkira Hatanaka uint64_t Address, 155459bfaf77SAkira Hatanaka const void *Decoder) { 155559bfaf77SAkira Hatanaka if (RegNo >= 4) 155659bfaf77SAkira Hatanaka return MCDisassembler::Fail; 155759bfaf77SAkira Hatanaka 15588002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo); 1559e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 156059bfaf77SAkira Hatanaka return MCDisassembler::Success; 156159bfaf77SAkira Hatanaka } 156259bfaf77SAkira Hatanaka 15638002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 156459bfaf77SAkira Hatanaka unsigned RegNo, 156559bfaf77SAkira Hatanaka uint64_t Address, 156659bfaf77SAkira Hatanaka const void *Decoder) { 156759bfaf77SAkira Hatanaka if (RegNo >= 4) 156859bfaf77SAkira Hatanaka return MCDisassembler::Fail; 156959bfaf77SAkira Hatanaka 15708002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo); 1571e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 157259bfaf77SAkira Hatanaka return MCDisassembler::Success; 157359bfaf77SAkira Hatanaka } 157459bfaf77SAkira Hatanaka 15753eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, 15763eb663b0SJack Carter unsigned RegNo, 15773eb663b0SJack Carter uint64_t Address, 15783eb663b0SJack Carter const void *Decoder) { 15793eb663b0SJack Carter if (RegNo > 31) 15803eb663b0SJack Carter return MCDisassembler::Fail; 15813eb663b0SJack Carter 15823eb663b0SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo); 1583e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 15843eb663b0SJack Carter return MCDisassembler::Success; 15853eb663b0SJack Carter } 15863eb663b0SJack Carter 15875dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, 15885dc8ac92SJack Carter unsigned RegNo, 15895dc8ac92SJack Carter uint64_t Address, 15905dc8ac92SJack Carter const void *Decoder) { 15915dc8ac92SJack Carter if (RegNo > 31) 15925dc8ac92SJack Carter return MCDisassembler::Fail; 15935dc8ac92SJack Carter 15945dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo); 1595e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 15965dc8ac92SJack Carter return MCDisassembler::Success; 15975dc8ac92SJack Carter } 15985dc8ac92SJack Carter 15995dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, 16005dc8ac92SJack Carter unsigned RegNo, 16015dc8ac92SJack Carter uint64_t Address, 16025dc8ac92SJack Carter const void *Decoder) { 16035dc8ac92SJack Carter if (RegNo > 31) 16045dc8ac92SJack Carter return MCDisassembler::Fail; 16055dc8ac92SJack Carter 16065dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo); 1607e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 16085dc8ac92SJack Carter return MCDisassembler::Success; 16095dc8ac92SJack Carter } 16105dc8ac92SJack Carter 16115dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, 16125dc8ac92SJack Carter unsigned RegNo, 16135dc8ac92SJack Carter uint64_t Address, 16145dc8ac92SJack Carter const void *Decoder) { 16155dc8ac92SJack Carter if (RegNo > 31) 16165dc8ac92SJack Carter return MCDisassembler::Fail; 16175dc8ac92SJack Carter 16185dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo); 1619e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 16205dc8ac92SJack Carter return MCDisassembler::Success; 16215dc8ac92SJack Carter } 16225dc8ac92SJack Carter 1623a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, 1624a591fdc6SMatheus Almeida unsigned RegNo, 1625a591fdc6SMatheus Almeida uint64_t Address, 1626a591fdc6SMatheus Almeida const void *Decoder) { 1627a591fdc6SMatheus Almeida if (RegNo > 7) 1628a591fdc6SMatheus Almeida return MCDisassembler::Fail; 1629a591fdc6SMatheus Almeida 1630a591fdc6SMatheus Almeida unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo); 1631e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1632a591fdc6SMatheus Almeida return MCDisassembler::Success; 1633a591fdc6SMatheus Almeida } 1634a591fdc6SMatheus Almeida 1635a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, 1636a3134faeSDaniel Sanders unsigned RegNo, 1637a3134faeSDaniel Sanders uint64_t Address, 1638a3134faeSDaniel Sanders const void *Decoder) { 1639a3134faeSDaniel Sanders if (RegNo > 31) 1640a3134faeSDaniel Sanders return MCDisassembler::Fail; 1641a3134faeSDaniel Sanders 1642a3134faeSDaniel Sanders unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo); 1643a3134faeSDaniel Sanders Inst.addOperand(MCOperand::createReg(Reg)); 1644a3134faeSDaniel Sanders return MCDisassembler::Success; 1645a3134faeSDaniel Sanders } 1646a3134faeSDaniel Sanders 16472a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, 16482a83d680SDaniel Sanders unsigned RegNo, 16492a83d680SDaniel Sanders uint64_t Address, 16502a83d680SDaniel Sanders const void *Decoder) { 16512a83d680SDaniel Sanders if (RegNo > 31) 16522a83d680SDaniel Sanders return MCDisassembler::Fail; 16532a83d680SDaniel Sanders 16542a83d680SDaniel Sanders unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo); 1655e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 16562a83d680SDaniel Sanders return MCDisassembler::Success; 16572a83d680SDaniel Sanders } 16582a83d680SDaniel Sanders 165971928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 166071928e68SAkira Hatanaka unsigned Offset, 166171928e68SAkira Hatanaka uint64_t Address, 166271928e68SAkira Hatanaka const void *Decoder) { 1663d37bab61SAlexey Samsonov int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4; 1664e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 166571928e68SAkira Hatanaka return MCDisassembler::Success; 166671928e68SAkira Hatanaka } 166771928e68SAkira Hatanaka 166871928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 166971928e68SAkira Hatanaka unsigned Insn, 167071928e68SAkira Hatanaka uint64_t Address, 167171928e68SAkira Hatanaka const void *Decoder) { 167271928e68SAkira Hatanaka 1673ecaef49fSJim Grosbach unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 1674e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(JumpOffset)); 167571928e68SAkira Hatanaka return MCDisassembler::Success; 167671928e68SAkira Hatanaka } 167771928e68SAkira Hatanaka 16783c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst, 16793c8869dcSZoran Jovanovic unsigned Offset, 16803c8869dcSZoran Jovanovic uint64_t Address, 16813c8869dcSZoran Jovanovic const void *Decoder) { 1682d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<21>(Offset) * 4; 16833c8869dcSZoran Jovanovic 1684e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 16853c8869dcSZoran Jovanovic return MCDisassembler::Success; 16863c8869dcSZoran Jovanovic } 16873c8869dcSZoran Jovanovic 16883c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst, 16893c8869dcSZoran Jovanovic unsigned Offset, 16903c8869dcSZoran Jovanovic uint64_t Address, 16913c8869dcSZoran Jovanovic const void *Decoder) { 1692d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<26>(Offset) * 4; 16933c8869dcSZoran Jovanovic 1694e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 16953c8869dcSZoran Jovanovic return MCDisassembler::Success; 16963c8869dcSZoran Jovanovic } 16973c8869dcSZoran Jovanovic 16989761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, 16999761e96bSJozef Kolek unsigned Offset, 17009761e96bSJozef Kolek uint64_t Address, 17019761e96bSJozef Kolek const void *Decoder) { 17029761e96bSJozef Kolek int32_t BranchOffset = SignExtend32<7>(Offset) << 1; 1703e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 17049761e96bSJozef Kolek return MCDisassembler::Success; 17059761e96bSJozef Kolek } 17069761e96bSJozef Kolek 17075cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, 17085cfebddeSJozef Kolek unsigned Offset, 17095cfebddeSJozef Kolek uint64_t Address, 17105cfebddeSJozef Kolek const void *Decoder) { 17115cfebddeSJozef Kolek int32_t BranchOffset = SignExtend32<10>(Offset) << 1; 1712e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 17135cfebddeSJozef Kolek return MCDisassembler::Success; 17145cfebddeSJozef Kolek } 17155cfebddeSJozef Kolek 17168a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 17178a80aa76SZoran Jovanovic unsigned Offset, 17188a80aa76SZoran Jovanovic uint64_t Address, 17198a80aa76SZoran Jovanovic const void *Decoder) { 1720d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<16>(Offset) * 2; 1721e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 17228a80aa76SZoran Jovanovic return MCDisassembler::Success; 17238a80aa76SZoran Jovanovic } 17248a80aa76SZoran Jovanovic 1725507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 1726507e084aSZoran Jovanovic unsigned Insn, 1727507e084aSZoran Jovanovic uint64_t Address, 1728507e084aSZoran Jovanovic const void *Decoder) { 1729507e084aSZoran Jovanovic unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1; 1730e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(JumpOffset)); 1731507e084aSZoran Jovanovic return MCDisassembler::Success; 1732507e084aSZoran Jovanovic } 173371928e68SAkira Hatanaka 1734aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 1735aa2b9278SJozef Kolek unsigned Value, 1736aa2b9278SJozef Kolek uint64_t Address, 1737aa2b9278SJozef Kolek const void *Decoder) { 1738aa2b9278SJozef Kolek if (Value == 0) 1739e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(1)); 1740aa2b9278SJozef Kolek else if (Value == 0x7) 1741e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(-1)); 1742aa2b9278SJozef Kolek else 1743e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Value << 2)); 1744aa2b9278SJozef Kolek return MCDisassembler::Success; 1745aa2b9278SJozef Kolek } 1746aa2b9278SJozef Kolek 1747aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, 1748aa2b9278SJozef Kolek unsigned Value, 1749aa2b9278SJozef Kolek uint64_t Address, 1750aa2b9278SJozef Kolek const void *Decoder) { 1751e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Value << 2)); 1752aa2b9278SJozef Kolek return MCDisassembler::Success; 1753aa2b9278SJozef Kolek } 1754aa2b9278SJozef Kolek 1755aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst, 1756aa2b9278SJozef Kolek unsigned Value, 1757aa2b9278SJozef Kolek uint64_t Address, 1758aa2b9278SJozef Kolek const void *Decoder) { 1759aa2b9278SJozef Kolek if (Value == 0x7F) 1760e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(-1)); 1761aa2b9278SJozef Kolek else 1762e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Value)); 1763aa2b9278SJozef Kolek return MCDisassembler::Success; 1764aa2b9278SJozef Kolek } 1765aa2b9278SJozef Kolek 1766aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst, 1767aa2b9278SJozef Kolek unsigned Value, 1768aa2b9278SJozef Kolek uint64_t Address, 1769aa2b9278SJozef Kolek const void *Decoder) { 1770e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<4>(Value))); 1771aa2b9278SJozef Kolek return MCDisassembler::Success; 1772aa2b9278SJozef Kolek } 1773aa2b9278SJozef Kolek 177471928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 177571928e68SAkira Hatanaka unsigned Insn, 177671928e68SAkira Hatanaka uint64_t Address, 177771928e68SAkira Hatanaka const void *Decoder) { 1778e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Insn))); 177971928e68SAkira Hatanaka return MCDisassembler::Success; 178071928e68SAkira Hatanaka } 178171928e68SAkira Hatanaka 1782779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst, 1783779c5937SMatheus Almeida unsigned Insn, 1784779c5937SMatheus Almeida uint64_t Address, 1785779c5937SMatheus Almeida const void *Decoder) { 1786779c5937SMatheus Almeida // We add one to the immediate field as it was encoded as 'imm - 1'. 1787e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Insn + 1)); 1788779c5937SMatheus Almeida return MCDisassembler::Success; 1789779c5937SMatheus Almeida } 1790779c5937SMatheus Almeida 179171928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 179271928e68SAkira Hatanaka unsigned Insn, 179371928e68SAkira Hatanaka uint64_t Address, 179471928e68SAkira Hatanaka const void *Decoder) { 179571928e68SAkira Hatanaka // First we need to grab the pos(lsb) from MCInst. 179671928e68SAkira Hatanaka int Pos = Inst.getOperand(2).getImm(); 179771928e68SAkira Hatanaka int Size = (int) Insn - Pos + 1; 1798e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size))); 179971928e68SAkira Hatanaka return MCDisassembler::Success; 180071928e68SAkira Hatanaka } 180171928e68SAkira Hatanaka 180271928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 180371928e68SAkira Hatanaka unsigned Insn, 180471928e68SAkira Hatanaka uint64_t Address, 180571928e68SAkira Hatanaka const void *Decoder) { 180671928e68SAkira Hatanaka int Size = (int) Insn + 1; 1807e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size))); 180871928e68SAkira Hatanaka return MCDisassembler::Success; 180971928e68SAkira Hatanaka } 1810b59e1a41SDaniel Sanders 1811b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 1812b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder) { 1813e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4)); 1814b59e1a41SDaniel Sanders return MCDisassembler::Success; 1815b59e1a41SDaniel Sanders } 18162855142aSZoran Jovanovic 18172855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 18182855142aSZoran Jovanovic uint64_t Address, const void *Decoder) { 1819e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8)); 18202855142aSZoran Jovanovic return MCDisassembler::Success; 18212855142aSZoran Jovanovic } 1822a4c4b5fcSZoran Jovanovic 1823b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 1824b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1825b682ddf3SVladimir Medic int32_t DecodedValue; 1826b682ddf3SVladimir Medic switch (Insn) { 1827b682ddf3SVladimir Medic case 0: DecodedValue = 256; break; 1828b682ddf3SVladimir Medic case 1: DecodedValue = 257; break; 1829b682ddf3SVladimir Medic case 510: DecodedValue = -258; break; 1830b682ddf3SVladimir Medic case 511: DecodedValue = -257; break; 1831b682ddf3SVladimir Medic default: DecodedValue = SignExtend32<9>(Insn); break; 1832b682ddf3SVladimir Medic } 1833e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(DecodedValue * 4)); 1834b682ddf3SVladimir Medic return MCDisassembler::Success; 1835b682ddf3SVladimir Medic } 1836b682ddf3SVladimir Medic 1837b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 1838b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1839b682ddf3SVladimir Medic // Insn must be >= 0, since it is unsigned that condition is always true. 1840b682ddf3SVladimir Medic assert(Insn < 16); 1841b682ddf3SVladimir Medic int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 1842b682ddf3SVladimir Medic 255, 32768, 65535}; 1843e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(DecodedValues[Insn])); 1844b682ddf3SVladimir Medic return MCDisassembler::Success; 1845b682ddf3SVladimir Medic } 1846b682ddf3SVladimir Medic 1847b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, 1848b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1849e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Insn << 2)); 1850b682ddf3SVladimir Medic return MCDisassembler::Success; 1851b682ddf3SVladimir Medic } 1852b682ddf3SVladimir Medic 1853a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, 1854a4c4b5fcSZoran Jovanovic unsigned Insn, 1855a4c4b5fcSZoran Jovanovic uint64_t Address, 1856a4c4b5fcSZoran Jovanovic const void *Decoder) { 1857a4c4b5fcSZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5, 1858a4c4b5fcSZoran Jovanovic Mips::S6, Mips::FP}; 1859a4c4b5fcSZoran Jovanovic unsigned RegNum; 1860a4c4b5fcSZoran Jovanovic 1861a4c4b5fcSZoran Jovanovic unsigned RegLst = fieldFromInstruction(Insn, 21, 5); 1862a4c4b5fcSZoran Jovanovic // Empty register lists are not allowed. 1863a4c4b5fcSZoran Jovanovic if (RegLst == 0) 1864a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 1865a4c4b5fcSZoran Jovanovic 1866a4c4b5fcSZoran Jovanovic RegNum = RegLst & 0xf; 1867a4c4b5fcSZoran Jovanovic for (unsigned i = 0; i < RegNum; i++) 1868e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Regs[i])); 1869a4c4b5fcSZoran Jovanovic 1870a4c4b5fcSZoran Jovanovic if (RegLst & 0x10) 1871e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::RA)); 1872a4c4b5fcSZoran Jovanovic 1873a4c4b5fcSZoran Jovanovic return MCDisassembler::Success; 1874a4c4b5fcSZoran Jovanovic } 1875f9a02500SZoran Jovanovic 1876f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 1877f9a02500SZoran Jovanovic uint64_t Address, 1878f9a02500SZoran Jovanovic const void *Decoder) { 1879f9a02500SZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3}; 1880f9a02500SZoran Jovanovic unsigned RegLst = fieldFromInstruction(Insn, 4, 2); 1881d68d424aSJozef Kolek unsigned RegNum = RegLst & 0x3; 1882f9a02500SZoran Jovanovic 1883d68d424aSJozef Kolek for (unsigned i = 0; i <= RegNum; i++) 1884e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Regs[i])); 1885f9a02500SZoran Jovanovic 1886e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::RA)); 1887f9a02500SZoran Jovanovic 1888f9a02500SZoran Jovanovic return MCDisassembler::Success; 1889f9a02500SZoran Jovanovic } 18902c6d7320SJozef Kolek 189141688679SZoran Jovanovic static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned Insn, 189241688679SZoran Jovanovic uint64_t Address, const void *Decoder) { 189341688679SZoran Jovanovic 189441688679SZoran Jovanovic unsigned RegPair = fieldFromInstruction(Insn, 7, 3); 189541688679SZoran Jovanovic 189641688679SZoran Jovanovic switch (RegPair) { 189741688679SZoran Jovanovic default: 189841688679SZoran Jovanovic return MCDisassembler::Fail; 189941688679SZoran Jovanovic case 0: 1900e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A1)); 1901e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A2)); 190241688679SZoran Jovanovic break; 190341688679SZoran Jovanovic case 1: 1904e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A1)); 1905e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A3)); 190641688679SZoran Jovanovic break; 190741688679SZoran Jovanovic case 2: 1908e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A2)); 1909e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A3)); 191041688679SZoran Jovanovic break; 191141688679SZoran Jovanovic case 3: 1912e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 1913e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::S5)); 191441688679SZoran Jovanovic break; 191541688679SZoran Jovanovic case 4: 1916e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 1917e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::S6)); 191841688679SZoran Jovanovic break; 191941688679SZoran Jovanovic case 5: 1920e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 1921e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A1)); 192241688679SZoran Jovanovic break; 192341688679SZoran Jovanovic case 6: 1924e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 1925e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A2)); 192641688679SZoran Jovanovic break; 192741688679SZoran Jovanovic case 7: 1928e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 1929e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A3)); 193041688679SZoran Jovanovic break; 193141688679SZoran Jovanovic } 193241688679SZoran Jovanovic 193341688679SZoran Jovanovic return MCDisassembler::Success; 193441688679SZoran Jovanovic } 193541688679SZoran Jovanovic 19362c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, 19372c6d7320SJozef Kolek uint64_t Address, const void *Decoder) { 19386499b5f0SJustin Bogner Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2))); 19392c6d7320SJozef Kolek return MCDisassembler::Success; 19402c6d7320SJozef Kolek } 1941