171928e68SAkira Hatanaka //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===// 271928e68SAkira Hatanaka // 371928e68SAkira Hatanaka // The LLVM Compiler Infrastructure 471928e68SAkira Hatanaka // 571928e68SAkira Hatanaka // This file is distributed under the University of Illinois Open Source 671928e68SAkira Hatanaka // License. See LICENSE.TXT for details. 771928e68SAkira Hatanaka // 871928e68SAkira Hatanaka //===----------------------------------------------------------------------===// 971928e68SAkira Hatanaka // 1071928e68SAkira Hatanaka // This file is part of the Mips Disassembler. 1171928e68SAkira Hatanaka // 1271928e68SAkira Hatanaka //===----------------------------------------------------------------------===// 1371928e68SAkira Hatanaka 1471928e68SAkira Hatanaka #include "Mips.h" 159bf2b567SAkira Hatanaka #include "MipsRegisterInfo.h" 16ed0881b2SChandler Carruth #include "MipsSubtarget.h" 17a1bc0f56SLang Hames #include "llvm/MC/MCContext.h" 1871928e68SAkira Hatanaka #include "llvm/MC/MCDisassembler.h" 19ecaef49fSJim Grosbach #include "llvm/MC/MCFixedLenDisassembler.h" 20ed0881b2SChandler Carruth #include "llvm/MC/MCInst.h" 21ed0881b2SChandler Carruth #include "llvm/MC/MCSubtargetInfo.h" 22ed0881b2SChandler Carruth #include "llvm/Support/MathExtras.h" 2371928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h" 2471928e68SAkira Hatanaka 2571928e68SAkira Hatanaka using namespace llvm; 2671928e68SAkira Hatanaka 27e96dd897SChandler Carruth #define DEBUG_TYPE "mips-disassembler" 28e96dd897SChandler Carruth 2971928e68SAkira Hatanaka typedef MCDisassembler::DecodeStatus DecodeStatus; 3071928e68SAkira Hatanaka 31cb3e98cfSBenjamin Kramer namespace { 32cb3e98cfSBenjamin Kramer 334aa6bea7SRafael Espindola /// A disasembler class for Mips. 349bf2b567SAkira Hatanaka class MipsDisassemblerBase : public MCDisassembler { 3571928e68SAkira Hatanaka public: 36a1bc0f56SLang Hames MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx, 374aa6bea7SRafael Espindola bool IsBigEndian) 384aa6bea7SRafael Espindola : MCDisassembler(STI, Ctx), 39e8860938SVladimir Medic IsGP64Bit(STI.getFeatureBits() & Mips::FeatureGP64Bit), 404aa6bea7SRafael Espindola IsBigEndian(IsBigEndian) {} 4171928e68SAkira Hatanaka 429bf2b567SAkira Hatanaka virtual ~MipsDisassemblerBase() {} 439bf2b567SAkira Hatanaka 44e8860938SVladimir Medic bool isGP64Bit() const { return IsGP64Bit; } 459bfa2e2eSAkira Hatanaka 469bf2b567SAkira Hatanaka private: 47e8860938SVladimir Medic bool IsGP64Bit; 489bf2b567SAkira Hatanaka protected: 494aa6bea7SRafael Espindola bool IsBigEndian; 509bf2b567SAkira Hatanaka }; 519bf2b567SAkira Hatanaka 524aa6bea7SRafael Espindola /// A disasembler class for Mips32. 539bf2b567SAkira Hatanaka class MipsDisassembler : public MipsDisassemblerBase { 54dde3d582SVladimir Medic bool IsMicroMips; 559bf2b567SAkira Hatanaka public: 56c171f65aSDaniel Sanders MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool bigEndian) 57c171f65aSDaniel Sanders : MipsDisassemblerBase(STI, Ctx, bigEndian) { 58dde3d582SVladimir Medic IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips; 59dde3d582SVladimir Medic } 6071928e68SAkira Hatanaka 61c171f65aSDaniel Sanders bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; } 62c171f65aSDaniel Sanders bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; } 63c171f65aSDaniel Sanders bool hasMips32r6() const { 645c582b2fSDaniel Sanders return STI.getFeatureBits() & Mips::FeatureMips32r6; 655c582b2fSDaniel Sanders } 665c582b2fSDaniel Sanders 670fa60416SDaniel Sanders bool isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; } 680fa60416SDaniel Sanders 69c171f65aSDaniel Sanders bool hasCOP3() const { 70c171f65aSDaniel Sanders // Only present in MIPS-I and MIPS-II 71c171f65aSDaniel Sanders return !hasMips32() && !hasMips3(); 72c171f65aSDaniel Sanders } 73c171f65aSDaniel Sanders 744aa6bea7SRafael Espindola DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 757fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address, 764aa6bea7SRafael Espindola raw_ostream &VStream, 774aa6bea7SRafael Espindola raw_ostream &CStream) const override; 7871928e68SAkira Hatanaka }; 7971928e68SAkira Hatanaka 804aa6bea7SRafael Espindola /// A disasembler class for Mips64. 819bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase { 8271928e68SAkira Hatanaka public: 83a1bc0f56SLang Hames Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 849bf2b567SAkira Hatanaka bool bigEndian) : 85a1bc0f56SLang Hames MipsDisassemblerBase(STI, Ctx, bigEndian) {} 8671928e68SAkira Hatanaka 874aa6bea7SRafael Espindola DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 887fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address, 894aa6bea7SRafael Espindola raw_ostream &VStream, 904aa6bea7SRafael Espindola raw_ostream &CStream) const override; 9171928e68SAkira Hatanaka }; 9271928e68SAkira Hatanaka 93cb3e98cfSBenjamin Kramer } // end anonymous namespace 94cb3e98cfSBenjamin Kramer 9571928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them. 9671928e68SAkira Hatanaka // Definitions are further down. 9713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 9871928e68SAkira Hatanaka unsigned RegNo, 9971928e68SAkira Hatanaka uint64_t Address, 10071928e68SAkira Hatanaka const void *Decoder); 10171928e68SAkira Hatanaka 102ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 103ec8a5490SReed Kotler unsigned RegNo, 104ec8a5490SReed Kotler uint64_t Address, 105ec8a5490SReed Kotler const void *Decoder); 106ec8a5490SReed Kotler 107b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, 108b0852e54SZoran Jovanovic unsigned RegNo, 109b0852e54SZoran Jovanovic uint64_t Address, 110b0852e54SZoran Jovanovic const void *Decoder); 111b0852e54SZoran Jovanovic 1121904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, 1131904fa21SJozef Kolek unsigned RegNo, 1141904fa21SJozef Kolek uint64_t Address, 1151904fa21SJozef Kolek const void *Decoder); 1161904fa21SJozef Kolek 11713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 11871928e68SAkira Hatanaka unsigned RegNo, 11971928e68SAkira Hatanaka uint64_t Address, 12071928e68SAkira Hatanaka const void *Decoder); 12171928e68SAkira Hatanaka 1229bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 1239bfa2e2eSAkira Hatanaka unsigned Insn, 1249bfa2e2eSAkira Hatanaka uint64_t Address, 1259bfa2e2eSAkira Hatanaka const void *Decoder); 1269bfa2e2eSAkira Hatanaka 127654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 128ecabd1a5SAkira Hatanaka unsigned RegNo, 129ecabd1a5SAkira Hatanaka uint64_t Address, 130ecabd1a5SAkira Hatanaka const void *Decoder); 131ecabd1a5SAkira Hatanaka 13271928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 13371928e68SAkira Hatanaka unsigned RegNo, 13471928e68SAkira Hatanaka uint64_t Address, 13571928e68SAkira Hatanaka const void *Decoder); 13671928e68SAkira Hatanaka 13771928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 13871928e68SAkira Hatanaka unsigned RegNo, 13971928e68SAkira Hatanaka uint64_t Address, 14071928e68SAkira Hatanaka const void *Decoder); 14171928e68SAkira Hatanaka 14271928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 14371928e68SAkira Hatanaka unsigned RegNo, 14471928e68SAkira Hatanaka uint64_t Address, 14571928e68SAkira Hatanaka const void *Decoder); 14671928e68SAkira Hatanaka 1471fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 1481fb1b8b8SAkira Hatanaka unsigned RegNo, 1491fb1b8b8SAkira Hatanaka uint64_t Address, 1501fb1b8b8SAkira Hatanaka const void *Decoder); 1511fb1b8b8SAkira Hatanaka 1520fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, 1530fa60416SDaniel Sanders uint64_t Address, 1540fa60416SDaniel Sanders const void *Decoder); 1550fa60416SDaniel Sanders 15671928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 15771928e68SAkira Hatanaka unsigned Insn, 15871928e68SAkira Hatanaka uint64_t Address, 15971928e68SAkira Hatanaka const void *Decoder); 16071928e68SAkira Hatanaka 16171928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 16271928e68SAkira Hatanaka unsigned RegNo, 16371928e68SAkira Hatanaka uint64_t Address, 16471928e68SAkira Hatanaka const void *Decoder); 16571928e68SAkira Hatanaka 16600fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 167ecabd1a5SAkira Hatanaka unsigned RegNo, 168ecabd1a5SAkira Hatanaka uint64_t Address, 169ecabd1a5SAkira Hatanaka const void *Decoder); 170ecabd1a5SAkira Hatanaka 1718002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 17259bfaf77SAkira Hatanaka unsigned RegNo, 17359bfaf77SAkira Hatanaka uint64_t Address, 17459bfaf77SAkira Hatanaka const void *Decoder); 17559bfaf77SAkira Hatanaka 1768002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 17759bfaf77SAkira Hatanaka unsigned RegNo, 17859bfaf77SAkira Hatanaka uint64_t Address, 17959bfaf77SAkira Hatanaka const void *Decoder); 18059bfaf77SAkira Hatanaka 1813eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, 1823eb663b0SJack Carter unsigned RegNo, 1833eb663b0SJack Carter uint64_t Address, 1843eb663b0SJack Carter const void *Decoder); 1853eb663b0SJack Carter 1865dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, 1875dc8ac92SJack Carter unsigned RegNo, 1885dc8ac92SJack Carter uint64_t Address, 1895dc8ac92SJack Carter const void *Decoder); 1905dc8ac92SJack Carter 1915dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, 1925dc8ac92SJack Carter unsigned RegNo, 1935dc8ac92SJack Carter uint64_t Address, 1945dc8ac92SJack Carter const void *Decoder); 1955dc8ac92SJack Carter 1965dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, 1975dc8ac92SJack Carter unsigned RegNo, 1985dc8ac92SJack Carter uint64_t Address, 1995dc8ac92SJack Carter const void *Decoder); 2005dc8ac92SJack Carter 201a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, 202a591fdc6SMatheus Almeida unsigned RegNo, 203a591fdc6SMatheus Almeida uint64_t Address, 204a591fdc6SMatheus Almeida const void *Decoder); 205a591fdc6SMatheus Almeida 2062a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, 2072a83d680SDaniel Sanders unsigned RegNo, 2082a83d680SDaniel Sanders uint64_t Address, 2092a83d680SDaniel Sanders const void *Decoder); 2102a83d680SDaniel Sanders 21171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 21271928e68SAkira Hatanaka unsigned Offset, 21371928e68SAkira Hatanaka uint64_t Address, 21471928e68SAkira Hatanaka const void *Decoder); 21571928e68SAkira Hatanaka 21671928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 21771928e68SAkira Hatanaka unsigned Insn, 21871928e68SAkira Hatanaka uint64_t Address, 21971928e68SAkira Hatanaka const void *Decoder); 22071928e68SAkira Hatanaka 2213c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst, 2223c8869dcSZoran Jovanovic unsigned Offset, 2233c8869dcSZoran Jovanovic uint64_t Address, 2243c8869dcSZoran Jovanovic const void *Decoder); 2253c8869dcSZoran Jovanovic 2263c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst, 2273c8869dcSZoran Jovanovic unsigned Offset, 2283c8869dcSZoran Jovanovic uint64_t Address, 2293c8869dcSZoran Jovanovic const void *Decoder); 2303c8869dcSZoran Jovanovic 2319761e96bSJozef Kolek // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is 2329761e96bSJozef Kolek // shifted left by 1 bit. 2339761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, 2349761e96bSJozef Kolek unsigned Offset, 2359761e96bSJozef Kolek uint64_t Address, 2369761e96bSJozef Kolek const void *Decoder); 2379761e96bSJozef Kolek 2388a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is 2398a80aa76SZoran Jovanovic // shifted left by 1 bit. 2408a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 2418a80aa76SZoran Jovanovic unsigned Offset, 2428a80aa76SZoran Jovanovic uint64_t Address, 2438a80aa76SZoran Jovanovic const void *Decoder); 2448a80aa76SZoran Jovanovic 245507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is 246507e084aSZoran Jovanovic // shifted left by 1 bit. 247507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 248507e084aSZoran Jovanovic unsigned Insn, 249507e084aSZoran Jovanovic uint64_t Address, 250507e084aSZoran Jovanovic const void *Decoder); 251507e084aSZoran Jovanovic 25271928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 25371928e68SAkira Hatanaka unsigned Insn, 25471928e68SAkira Hatanaka uint64_t Address, 25571928e68SAkira Hatanaka const void *Decoder); 25671928e68SAkira Hatanaka 25792db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 25892db6b78SDaniel Sanders unsigned Insn, 25992db6b78SDaniel Sanders uint64_t Address, 26092db6b78SDaniel Sanders const void *Decoder); 26192db6b78SDaniel Sanders 262ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst, 263ab6d1cceSJozef Kolek unsigned Insn, 264ab6d1cceSJozef Kolek uint64_t Address, 265ab6d1cceSJozef Kolek const void *Decoder); 266ab6d1cceSJozef Kolek 267b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 268b4484d62SDaniel Sanders unsigned Insn, 269b4484d62SDaniel Sanders uint64_t Address, 270b4484d62SDaniel Sanders const void *Decoder); 271b4484d62SDaniel Sanders 272fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 273fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder); 274fe0bf9f6SMatheus Almeida 275315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 276315e7ecaSJozef Kolek unsigned Insn, 277315e7ecaSJozef Kolek uint64_t Address, 278315e7ecaSJozef Kolek const void *Decoder); 279315e7ecaSJozef Kolek 28012c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, 28112c6982bSJozef Kolek unsigned Insn, 28212c6982bSJozef Kolek uint64_t Address, 28312c6982bSJozef Kolek const void *Decoder); 28412c6982bSJozef Kolek 285dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 286dde3d582SVladimir Medic unsigned Insn, 287dde3d582SVladimir Medic uint64_t Address, 288dde3d582SVladimir Medic const void *Decoder); 289dde3d582SVladimir Medic 290dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 291dde3d582SVladimir Medic unsigned Insn, 292dde3d582SVladimir Medic uint64_t Address, 293dde3d582SVladimir Medic const void *Decoder); 294dde3d582SVladimir Medic 29571928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 29671928e68SAkira Hatanaka uint64_t Address, 29771928e68SAkira Hatanaka const void *Decoder); 29871928e68SAkira Hatanaka 29992db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, 30092db6b78SDaniel Sanders uint64_t Address, 30192db6b78SDaniel Sanders const void *Decoder); 30292db6b78SDaniel Sanders 30392db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, 30492db6b78SDaniel Sanders uint64_t Address, 30592db6b78SDaniel Sanders const void *Decoder); 30692db6b78SDaniel Sanders 307*435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn, 308*435cf8a4SVladimir Medic uint64_t Address, 309*435cf8a4SVladimir Medic const void *Decoder); 310*435cf8a4SVladimir Medic 3116a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 3126a803f61SDaniel Sanders unsigned Insn, 3136a803f61SDaniel Sanders uint64_t Address, 3146a803f61SDaniel Sanders const void *Decoder); 3156a803f61SDaniel Sanders 316aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 317aa2b9278SJozef Kolek unsigned Value, 318aa2b9278SJozef Kolek uint64_t Address, 319aa2b9278SJozef Kolek const void *Decoder); 320aa2b9278SJozef Kolek 321aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, 322aa2b9278SJozef Kolek unsigned Value, 323aa2b9278SJozef Kolek uint64_t Address, 324aa2b9278SJozef Kolek const void *Decoder); 325aa2b9278SJozef Kolek 326aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst, 327aa2b9278SJozef Kolek unsigned Value, 328aa2b9278SJozef Kolek uint64_t Address, 329aa2b9278SJozef Kolek const void *Decoder); 330aa2b9278SJozef Kolek 331aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst, 332aa2b9278SJozef Kolek unsigned Value, 333aa2b9278SJozef Kolek uint64_t Address, 334aa2b9278SJozef Kolek const void *Decoder); 335aa2b9278SJozef Kolek 33671928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 33771928e68SAkira Hatanaka unsigned Insn, 33871928e68SAkira Hatanaka uint64_t Address, 33971928e68SAkira Hatanaka const void *Decoder); 34071928e68SAkira Hatanaka 341779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which 342779c5937SMatheus Almeida // is off by one. 343779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst, 344779c5937SMatheus Almeida unsigned Insn, 345779c5937SMatheus Almeida uint64_t Address, 346779c5937SMatheus Almeida const void *Decoder); 347779c5937SMatheus Almeida 34871928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 34971928e68SAkira Hatanaka unsigned Insn, 35071928e68SAkira Hatanaka uint64_t Address, 35171928e68SAkira Hatanaka const void *Decoder); 35271928e68SAkira Hatanaka 35371928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 35471928e68SAkira Hatanaka unsigned Insn, 35571928e68SAkira Hatanaka uint64_t Address, 35671928e68SAkira Hatanaka const void *Decoder); 35771928e68SAkira Hatanaka 358b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 359b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder); 360b59e1a41SDaniel Sanders 3612855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 3622855142aSZoran Jovanovic uint64_t Address, const void *Decoder); 3632855142aSZoran Jovanovic 364b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 365b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 366b682ddf3SVladimir Medic 367b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 368b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 369b682ddf3SVladimir Medic 370b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, 371b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 372b682ddf3SVladimir Medic 373b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't 374b50ccf8eSDaniel Sanders /// handle. 375b50ccf8eSDaniel Sanders template <typename InsnType> 376b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 377b50ccf8eSDaniel Sanders const void *Decoder); 3785c582b2fSDaniel Sanders 3795c582b2fSDaniel Sanders template <typename InsnType> 3805c582b2fSDaniel Sanders static DecodeStatus 3815c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3825c582b2fSDaniel Sanders const void *Decoder); 3835c582b2fSDaniel Sanders 3845c582b2fSDaniel Sanders template <typename InsnType> 3855c582b2fSDaniel Sanders static DecodeStatus 3865c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3875c582b2fSDaniel Sanders const void *Decoder); 3885c582b2fSDaniel Sanders 3895c582b2fSDaniel Sanders template <typename InsnType> 3905c582b2fSDaniel Sanders static DecodeStatus 3915c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3925c582b2fSDaniel Sanders const void *Decoder); 3935c582b2fSDaniel Sanders 3945c582b2fSDaniel Sanders template <typename InsnType> 3955c582b2fSDaniel Sanders static DecodeStatus 3965c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(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 DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4025c582b2fSDaniel Sanders const void *Decoder); 4035c582b2fSDaniel Sanders 40428a0ca07SZoran Jovanovic template <typename InsnType> 40528a0ca07SZoran Jovanovic static DecodeStatus 40628a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 40728a0ca07SZoran Jovanovic const void *Decoder); 40828a0ca07SZoran Jovanovic 409a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn, 410a4c4b5fcSZoran Jovanovic uint64_t Address, 411a4c4b5fcSZoran Jovanovic const void *Decoder); 412a4c4b5fcSZoran Jovanovic 413f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 414f9a02500SZoran Jovanovic uint64_t Address, 415f9a02500SZoran Jovanovic const void *Decoder); 416f9a02500SZoran Jovanovic 41771928e68SAkira Hatanaka namespace llvm { 41871928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 41971928e68SAkira Hatanaka TheMips64elTarget; 42071928e68SAkira Hatanaka } 42171928e68SAkira Hatanaka 42271928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler( 42371928e68SAkira Hatanaka const Target &T, 424a1bc0f56SLang Hames const MCSubtargetInfo &STI, 425a1bc0f56SLang Hames MCContext &Ctx) { 426a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, true); 42771928e68SAkira Hatanaka } 42871928e68SAkira Hatanaka 42971928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler( 43071928e68SAkira Hatanaka const Target &T, 431a1bc0f56SLang Hames const MCSubtargetInfo &STI, 432a1bc0f56SLang Hames MCContext &Ctx) { 433a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, false); 43471928e68SAkira Hatanaka } 43571928e68SAkira Hatanaka 43671928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler( 43771928e68SAkira Hatanaka const Target &T, 438a1bc0f56SLang Hames const MCSubtargetInfo &STI, 439a1bc0f56SLang Hames MCContext &Ctx) { 440a1bc0f56SLang Hames return new Mips64Disassembler(STI, Ctx, true); 44171928e68SAkira Hatanaka } 44271928e68SAkira Hatanaka 44371928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler( 44471928e68SAkira Hatanaka const Target &T, 445a1bc0f56SLang Hames const MCSubtargetInfo &STI, 446a1bc0f56SLang Hames MCContext &Ctx) { 447a1bc0f56SLang Hames return new Mips64Disassembler(STI, Ctx, false); 44871928e68SAkira Hatanaka } 44971928e68SAkira Hatanaka 45071928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() { 45171928e68SAkira Hatanaka // Register the disassembler. 45271928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 45371928e68SAkira Hatanaka createMipsDisassembler); 45471928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 45571928e68SAkira Hatanaka createMipselDisassembler); 45671928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64Target, 45771928e68SAkira Hatanaka createMips64Disassembler); 45871928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 45971928e68SAkira Hatanaka createMips64elDisassembler); 46071928e68SAkira Hatanaka } 46171928e68SAkira Hatanaka 46271928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc" 46371928e68SAkira Hatanaka 4645c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 4655c582b2fSDaniel Sanders const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D); 4665c582b2fSDaniel Sanders const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo(); 4675c582b2fSDaniel Sanders return *(RegInfo->getRegClass(RC).begin() + RegNo); 4685c582b2fSDaniel Sanders } 4695c582b2fSDaniel Sanders 470b50ccf8eSDaniel Sanders template <typename InsnType> 471b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 472b50ccf8eSDaniel Sanders const void *Decoder) { 473b50ccf8eSDaniel Sanders typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *); 474b50ccf8eSDaniel Sanders // The size of the n field depends on the element size 475b50ccf8eSDaniel Sanders // The register class also depends on this. 476b50ccf8eSDaniel Sanders InsnType tmp = fieldFromInstruction(insn, 17, 5); 477b50ccf8eSDaniel Sanders unsigned NSize = 0; 478b50ccf8eSDaniel Sanders DecodeFN RegDecoder = nullptr; 479b50ccf8eSDaniel Sanders if ((tmp & 0x18) == 0x00) { // INSVE_B 480b50ccf8eSDaniel Sanders NSize = 4; 481b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128BRegisterClass; 482b50ccf8eSDaniel Sanders } else if ((tmp & 0x1c) == 0x10) { // INSVE_H 483b50ccf8eSDaniel Sanders NSize = 3; 484b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128HRegisterClass; 485b50ccf8eSDaniel Sanders } else if ((tmp & 0x1e) == 0x18) { // INSVE_W 486b50ccf8eSDaniel Sanders NSize = 2; 487b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128WRegisterClass; 488b50ccf8eSDaniel Sanders } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D 489b50ccf8eSDaniel Sanders NSize = 1; 490b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128DRegisterClass; 491b50ccf8eSDaniel Sanders } else 492b50ccf8eSDaniel Sanders llvm_unreachable("Invalid encoding"); 493b50ccf8eSDaniel Sanders 494b50ccf8eSDaniel Sanders assert(NSize != 0 && RegDecoder != nullptr); 495b50ccf8eSDaniel Sanders 496b50ccf8eSDaniel Sanders // $wd 497b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 6, 5); 498b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 499b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 500b50ccf8eSDaniel Sanders // $wd_in 501b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 502b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 503b50ccf8eSDaniel Sanders // $n 504b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 16, NSize); 505b50ccf8eSDaniel Sanders MI.addOperand(MCOperand::CreateImm(tmp)); 506b50ccf8eSDaniel Sanders // $ws 507b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 11, 5); 508b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 509b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 510b50ccf8eSDaniel Sanders // $n2 511b50ccf8eSDaniel Sanders MI.addOperand(MCOperand::CreateImm(0)); 512b50ccf8eSDaniel Sanders 513b50ccf8eSDaniel Sanders return MCDisassembler::Success; 514b50ccf8eSDaniel Sanders } 515b50ccf8eSDaniel Sanders 5165c582b2fSDaniel Sanders template <typename InsnType> 5175c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, 5185c582b2fSDaniel Sanders uint64_t Address, 5195c582b2fSDaniel Sanders const void *Decoder) { 5205c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5215c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 5225c582b2fSDaniel Sanders // ISA's instead). 5235c582b2fSDaniel Sanders // 5245c582b2fSDaniel Sanders // We have: 5255c582b2fSDaniel Sanders // 0b001000 sssss ttttt iiiiiiiiiiiiiiii 5265c582b2fSDaniel Sanders // BOVC if rs >= rt 5275c582b2fSDaniel Sanders // BEQZALC if rs == 0 && rt != 0 5285c582b2fSDaniel Sanders // BEQC if rs < rt && rs != 0 5295c582b2fSDaniel Sanders 5305c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 5315c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 532d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 5335c582b2fSDaniel Sanders bool HasRs = false; 5345c582b2fSDaniel Sanders 5355c582b2fSDaniel Sanders if (Rs >= Rt) { 5365c582b2fSDaniel Sanders MI.setOpcode(Mips::BOVC); 5375c582b2fSDaniel Sanders HasRs = true; 5385c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 5395c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQC); 5405c582b2fSDaniel Sanders HasRs = true; 5415c582b2fSDaniel Sanders } else 5425c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQZALC); 5435c582b2fSDaniel Sanders 5445c582b2fSDaniel Sanders if (HasRs) 5455c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5465c582b2fSDaniel Sanders Rs))); 5475c582b2fSDaniel Sanders 5485c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5495c582b2fSDaniel Sanders Rt))); 5505c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 5515c582b2fSDaniel Sanders 5525c582b2fSDaniel Sanders return MCDisassembler::Success; 5535c582b2fSDaniel Sanders } 5545c582b2fSDaniel Sanders 5555c582b2fSDaniel Sanders template <typename InsnType> 5565c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, 5575c582b2fSDaniel Sanders uint64_t Address, 5585c582b2fSDaniel Sanders const void *Decoder) { 5595c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5605c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 5615c582b2fSDaniel Sanders // ISA's instead). 5625c582b2fSDaniel Sanders // 5635c582b2fSDaniel Sanders // We have: 5645c582b2fSDaniel Sanders // 0b011000 sssss ttttt iiiiiiiiiiiiiiii 5655c582b2fSDaniel Sanders // BNVC if rs >= rt 5665c582b2fSDaniel Sanders // BNEZALC if rs == 0 && rt != 0 5675c582b2fSDaniel Sanders // BNEC if rs < rt && rs != 0 5685c582b2fSDaniel Sanders 5695c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 5705c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 571d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 5725c582b2fSDaniel Sanders bool HasRs = false; 5735c582b2fSDaniel Sanders 5745c582b2fSDaniel Sanders if (Rs >= Rt) { 5755c582b2fSDaniel Sanders MI.setOpcode(Mips::BNVC); 5765c582b2fSDaniel Sanders HasRs = true; 5775c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 5785c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEC); 5795c582b2fSDaniel Sanders HasRs = true; 5805c582b2fSDaniel Sanders } else 5815c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEZALC); 5825c582b2fSDaniel Sanders 5835c582b2fSDaniel Sanders if (HasRs) 5845c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5855c582b2fSDaniel Sanders Rs))); 5865c582b2fSDaniel Sanders 5875c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5885c582b2fSDaniel Sanders Rt))); 5895c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 5905c582b2fSDaniel Sanders 5915c582b2fSDaniel Sanders return MCDisassembler::Success; 5925c582b2fSDaniel Sanders } 5935c582b2fSDaniel Sanders 5945c582b2fSDaniel Sanders template <typename InsnType> 5955c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, 5965c582b2fSDaniel Sanders uint64_t Address, 5975c582b2fSDaniel Sanders const void *Decoder) { 5985c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5995c582b2fSDaniel Sanders // (otherwise we would have matched the BLEZL instruction from the earlier 6005c582b2fSDaniel Sanders // ISA's instead). 6015c582b2fSDaniel Sanders // 6025c582b2fSDaniel Sanders // We have: 6035c582b2fSDaniel Sanders // 0b010110 sssss ttttt iiiiiiiiiiiiiiii 6045c582b2fSDaniel Sanders // Invalid if rs == 0 6055c582b2fSDaniel Sanders // BLEZC if rs == 0 && rt != 0 6065c582b2fSDaniel Sanders // BGEZC if rs == rt && rt != 0 6075c582b2fSDaniel Sanders // BGEC if rs != rt && rs != 0 && rt != 0 6085c582b2fSDaniel Sanders 6095c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6105c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 611d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 61228a0ca07SZoran Jovanovic bool HasRs = false; 6135c582b2fSDaniel Sanders 6145c582b2fSDaniel Sanders if (Rt == 0) 6155c582b2fSDaniel Sanders return MCDisassembler::Fail; 6165c582b2fSDaniel Sanders else if (Rs == 0) 6175c582b2fSDaniel Sanders MI.setOpcode(Mips::BLEZC); 6185c582b2fSDaniel Sanders else if (Rs == Rt) 6195c582b2fSDaniel Sanders MI.setOpcode(Mips::BGEZC); 62028a0ca07SZoran Jovanovic else { 62128a0ca07SZoran Jovanovic HasRs = true; 62228a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEC); 62328a0ca07SZoran Jovanovic } 62428a0ca07SZoran Jovanovic 62528a0ca07SZoran Jovanovic if (HasRs) 62628a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 62728a0ca07SZoran Jovanovic Rs))); 6285c582b2fSDaniel Sanders 6295c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6305c582b2fSDaniel Sanders Rt))); 6315c582b2fSDaniel Sanders 6325c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 6335c582b2fSDaniel Sanders 6345c582b2fSDaniel Sanders return MCDisassembler::Success; 6355c582b2fSDaniel Sanders } 6365c582b2fSDaniel Sanders 6375c582b2fSDaniel Sanders template <typename InsnType> 6385c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, 6395c582b2fSDaniel Sanders uint64_t Address, 6405c582b2fSDaniel Sanders const void *Decoder) { 6415c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6425c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZL instruction from the earlier 6435c582b2fSDaniel Sanders // ISA's instead). 6445c582b2fSDaniel Sanders // 6455c582b2fSDaniel Sanders // We have: 6465c582b2fSDaniel Sanders // 0b010111 sssss ttttt iiiiiiiiiiiiiiii 6475c582b2fSDaniel Sanders // Invalid if rs == 0 6485c582b2fSDaniel Sanders // BGTZC if rs == 0 && rt != 0 6495c582b2fSDaniel Sanders // BLTZC if rs == rt && rt != 0 6505c582b2fSDaniel Sanders // BLTC if rs != rt && rs != 0 && rt != 0 6515c582b2fSDaniel Sanders 6525c14b069SZoran Jovanovic bool HasRs = false; 6535c14b069SZoran Jovanovic 6545c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6555c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 656d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 6575c582b2fSDaniel Sanders 6585c582b2fSDaniel Sanders if (Rt == 0) 6595c582b2fSDaniel Sanders return MCDisassembler::Fail; 6605c582b2fSDaniel Sanders else if (Rs == 0) 6615c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZC); 6625c582b2fSDaniel Sanders else if (Rs == Rt) 6635c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZC); 6645c14b069SZoran Jovanovic else { 6655c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTC); 6665c14b069SZoran Jovanovic HasRs = true; 6675c14b069SZoran Jovanovic } 6685c14b069SZoran Jovanovic 6695c14b069SZoran Jovanovic if (HasRs) 6705c14b069SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6715c14b069SZoran Jovanovic Rs))); 6725c582b2fSDaniel Sanders 6735c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6745c582b2fSDaniel Sanders Rt))); 6755c582b2fSDaniel Sanders 6765c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 6775c582b2fSDaniel Sanders 6785c582b2fSDaniel Sanders return MCDisassembler::Success; 6795c582b2fSDaniel Sanders } 6805c582b2fSDaniel Sanders 6815c582b2fSDaniel Sanders template <typename InsnType> 6825c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, 6835c582b2fSDaniel Sanders uint64_t Address, 6845c582b2fSDaniel Sanders const void *Decoder) { 6855c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6865c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZ instruction from the earlier 6875c582b2fSDaniel Sanders // ISA's instead). 6885c582b2fSDaniel Sanders // 6895c582b2fSDaniel Sanders // We have: 6905c582b2fSDaniel Sanders // 0b000111 sssss ttttt iiiiiiiiiiiiiiii 6915c582b2fSDaniel Sanders // BGTZ if rt == 0 6925c582b2fSDaniel Sanders // BGTZALC if rs == 0 && rt != 0 6935c582b2fSDaniel Sanders // BLTZALC if rs != 0 && rs == rt 6945c582b2fSDaniel Sanders // BLTUC if rs != 0 && rs != rt 6955c582b2fSDaniel Sanders 6965c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6975c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 698d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 6995c582b2fSDaniel Sanders bool HasRs = false; 7005c582b2fSDaniel Sanders bool HasRt = false; 7015c582b2fSDaniel Sanders 7025c582b2fSDaniel Sanders if (Rt == 0) { 7035c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZ); 7045c582b2fSDaniel Sanders HasRs = true; 7055c582b2fSDaniel Sanders } else if (Rs == 0) { 7065c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZALC); 7075c582b2fSDaniel Sanders HasRt = true; 7085c582b2fSDaniel Sanders } else if (Rs == Rt) { 7095c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZALC); 7105c582b2fSDaniel Sanders HasRs = true; 7115c14b069SZoran Jovanovic } else { 7125c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTUC); 7135c14b069SZoran Jovanovic HasRs = true; 7145c14b069SZoran Jovanovic HasRt = true; 7155c14b069SZoran Jovanovic } 7165c582b2fSDaniel Sanders 7175c582b2fSDaniel Sanders if (HasRs) 7185c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 7195c582b2fSDaniel Sanders Rs))); 7205c582b2fSDaniel Sanders 7215c582b2fSDaniel Sanders if (HasRt) 7225c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 7235c582b2fSDaniel Sanders Rt))); 7245c582b2fSDaniel Sanders 7255c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 7265c582b2fSDaniel Sanders 7275c582b2fSDaniel Sanders return MCDisassembler::Success; 7285c582b2fSDaniel Sanders } 7295c582b2fSDaniel Sanders 73028a0ca07SZoran Jovanovic template <typename InsnType> 73128a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn, 73228a0ca07SZoran Jovanovic uint64_t Address, 73328a0ca07SZoran Jovanovic const void *Decoder) { 73428a0ca07SZoran Jovanovic // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 73528a0ca07SZoran Jovanovic // (otherwise we would have matched the BLEZL instruction from the earlier 73628a0ca07SZoran Jovanovic // ISA's instead). 73728a0ca07SZoran Jovanovic // 73828a0ca07SZoran Jovanovic // We have: 73928a0ca07SZoran Jovanovic // 0b000110 sssss ttttt iiiiiiiiiiiiiiii 74028a0ca07SZoran Jovanovic // Invalid if rs == 0 74128a0ca07SZoran Jovanovic // BLEZALC if rs == 0 && rt != 0 74228a0ca07SZoran Jovanovic // BGEZALC if rs == rt && rt != 0 74328a0ca07SZoran Jovanovic // BGEUC if rs != rt && rs != 0 && rt != 0 74428a0ca07SZoran Jovanovic 74528a0ca07SZoran Jovanovic InsnType Rs = fieldFromInstruction(insn, 21, 5); 74628a0ca07SZoran Jovanovic InsnType Rt = fieldFromInstruction(insn, 16, 5); 747d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 74828a0ca07SZoran Jovanovic bool HasRs = false; 74928a0ca07SZoran Jovanovic 75028a0ca07SZoran Jovanovic if (Rt == 0) 75128a0ca07SZoran Jovanovic return MCDisassembler::Fail; 75228a0ca07SZoran Jovanovic else if (Rs == 0) 75328a0ca07SZoran Jovanovic MI.setOpcode(Mips::BLEZALC); 75428a0ca07SZoran Jovanovic else if (Rs == Rt) 75528a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEZALC); 75628a0ca07SZoran Jovanovic else { 75728a0ca07SZoran Jovanovic HasRs = true; 75828a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEUC); 75928a0ca07SZoran Jovanovic } 76028a0ca07SZoran Jovanovic 76128a0ca07SZoran Jovanovic if (HasRs) 76228a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 76328a0ca07SZoran Jovanovic Rs))); 76428a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 76528a0ca07SZoran Jovanovic Rt))); 76628a0ca07SZoran Jovanovic 76728a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateImm(Imm)); 76828a0ca07SZoran Jovanovic 76928a0ca07SZoran Jovanovic return MCDisassembler::Success; 77028a0ca07SZoran Jovanovic } 77128a0ca07SZoran Jovanovic 772ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted 773ea22c4cfSJozef Kolek /// according to the given endianess. 774ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 775ea22c4cfSJozef Kolek uint64_t &Size, uint32_t &Insn, 776ea22c4cfSJozef Kolek bool IsBigEndian) { 777ea22c4cfSJozef Kolek // We want to read exactly 2 Bytes of data. 778ea22c4cfSJozef Kolek if (Bytes.size() < 2) { 779ea22c4cfSJozef Kolek Size = 0; 780ea22c4cfSJozef Kolek return MCDisassembler::Fail; 781ea22c4cfSJozef Kolek } 782ea22c4cfSJozef Kolek 783ea22c4cfSJozef Kolek if (IsBigEndian) { 784ea22c4cfSJozef Kolek Insn = (Bytes[0] << 8) | Bytes[1]; 785ea22c4cfSJozef Kolek } else { 786ea22c4cfSJozef Kolek Insn = (Bytes[1] << 8) | Bytes[0]; 787ea22c4cfSJozef Kolek } 788ea22c4cfSJozef Kolek 789ea22c4cfSJozef Kolek return MCDisassembler::Success; 790ea22c4cfSJozef Kolek } 791ea22c4cfSJozef Kolek 7927fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted 7934aa6bea7SRafael Espindola /// according to the given endianess 7947fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 7957fc5b874SRafael Espindola uint64_t &Size, uint32_t &Insn, 7967fc5b874SRafael Espindola bool IsBigEndian, bool IsMicroMips) { 79771928e68SAkira Hatanaka // We want to read exactly 4 Bytes of data. 7987fc5b874SRafael Espindola if (Bytes.size() < 4) { 7994aa6bea7SRafael Espindola Size = 0; 80071928e68SAkira Hatanaka return MCDisassembler::Fail; 80171928e68SAkira Hatanaka } 80271928e68SAkira Hatanaka 803ea22c4cfSJozef Kolek // High 16 bits of a 32-bit microMIPS instruction (where the opcode is) 804ea22c4cfSJozef Kolek // always precede the low 16 bits in the instruction stream (that is, they 805ea22c4cfSJozef Kolek // are placed at lower addresses in the instruction stream). 806ea22c4cfSJozef Kolek // 807ea22c4cfSJozef Kolek // microMIPS byte ordering: 808ea22c4cfSJozef Kolek // Big-endian: 0 | 1 | 2 | 3 809ea22c4cfSJozef Kolek // Little-endian: 1 | 0 | 3 | 2 810ea22c4cfSJozef Kolek 8114aa6bea7SRafael Espindola if (IsBigEndian) { 81271928e68SAkira Hatanaka // Encoded as a big-endian 32-bit word in the stream. 8134aa6bea7SRafael Espindola Insn = 8144aa6bea7SRafael Espindola (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24); 8154aa6bea7SRafael Espindola } else { 816dde3d582SVladimir Medic if (IsMicroMips) { 8174aa6bea7SRafael Espindola Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) | 818dde3d582SVladimir Medic (Bytes[1] << 24); 819dde3d582SVladimir Medic } else { 8204aa6bea7SRafael Espindola Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | 82171928e68SAkira Hatanaka (Bytes[3] << 24); 82271928e68SAkira Hatanaka } 823dde3d582SVladimir Medic } 82471928e68SAkira Hatanaka 82571928e68SAkira Hatanaka return MCDisassembler::Success; 82671928e68SAkira Hatanaka } 82771928e68SAkira Hatanaka 8284aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 8297fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 83071928e68SAkira Hatanaka uint64_t Address, 8314aa6bea7SRafael Espindola raw_ostream &VStream, 8324aa6bea7SRafael Espindola raw_ostream &CStream) const { 83371928e68SAkira Hatanaka uint32_t Insn; 834ea22c4cfSJozef Kolek DecodeStatus Result; 83571928e68SAkira Hatanaka 836ea22c4cfSJozef Kolek if (IsMicroMips) { 837ea22c4cfSJozef Kolek Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); 838ea22c4cfSJozef Kolek 839ea22c4cfSJozef Kolek DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n"); 840ea22c4cfSJozef Kolek // Calling the auto-generated decoder function. 841ea22c4cfSJozef Kolek Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address, 842ea22c4cfSJozef Kolek this, STI); 843ea22c4cfSJozef Kolek if (Result != MCDisassembler::Fail) { 844ea22c4cfSJozef Kolek Size = 2; 845ea22c4cfSJozef Kolek return Result; 846ea22c4cfSJozef Kolek } 847ea22c4cfSJozef Kolek 848ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true); 84971928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 85071928e68SAkira Hatanaka return MCDisassembler::Fail; 85171928e68SAkira Hatanaka 852ea22c4cfSJozef Kolek DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); 853dde3d582SVladimir Medic // Calling the auto-generated decoder function. 8544aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, 855dde3d582SVladimir Medic this, STI); 856dde3d582SVladimir Medic if (Result != MCDisassembler::Fail) { 857dde3d582SVladimir Medic Size = 4; 858dde3d582SVladimir Medic return Result; 859dde3d582SVladimir Medic } 860dde3d582SVladimir Medic return MCDisassembler::Fail; 861dde3d582SVladimir Medic } 862dde3d582SVladimir Medic 863ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); 864ea22c4cfSJozef Kolek if (Result == MCDisassembler::Fail) 865ea22c4cfSJozef Kolek return MCDisassembler::Fail; 866ea22c4cfSJozef Kolek 867c171f65aSDaniel Sanders if (hasCOP3()) { 868c171f65aSDaniel Sanders DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n"); 869c171f65aSDaniel Sanders Result = 8704aa6bea7SRafael Espindola decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI); 871c171f65aSDaniel Sanders if (Result != MCDisassembler::Fail) { 872c171f65aSDaniel Sanders Size = 4; 873c171f65aSDaniel Sanders return Result; 874c171f65aSDaniel Sanders } 875c171f65aSDaniel Sanders } 876c171f65aSDaniel Sanders 877c171f65aSDaniel Sanders if (hasMips32r6() && isGP64()) { 8780fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n"); 8794aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn, 8800fa60416SDaniel Sanders Address, this, STI); 8810fa60416SDaniel Sanders if (Result != MCDisassembler::Fail) { 8820fa60416SDaniel Sanders Size = 4; 8830fa60416SDaniel Sanders return Result; 8840fa60416SDaniel Sanders } 8850fa60416SDaniel Sanders } 8860fa60416SDaniel Sanders 887c171f65aSDaniel Sanders if (hasMips32r6()) { 8880fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n"); 8894aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn, 8905c582b2fSDaniel Sanders Address, this, STI); 8915c582b2fSDaniel Sanders if (Result != MCDisassembler::Fail) { 8925c582b2fSDaniel Sanders Size = 4; 8935c582b2fSDaniel Sanders return Result; 8945c582b2fSDaniel Sanders } 8955c582b2fSDaniel Sanders } 8965c582b2fSDaniel Sanders 8970fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n"); 89871928e68SAkira Hatanaka // Calling the auto-generated decoder function. 8994aa6bea7SRafael Espindola Result = 9004aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI); 90171928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 90271928e68SAkira Hatanaka Size = 4; 90371928e68SAkira Hatanaka return Result; 90471928e68SAkira Hatanaka } 90571928e68SAkira Hatanaka 90671928e68SAkira Hatanaka return MCDisassembler::Fail; 90771928e68SAkira Hatanaka } 90871928e68SAkira Hatanaka 9094aa6bea7SRafael Espindola DecodeStatus Mips64Disassembler::getInstruction(MCInst &Instr, uint64_t &Size, 9107fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 91171928e68SAkira Hatanaka uint64_t Address, 9124aa6bea7SRafael Espindola raw_ostream &VStream, 9134aa6bea7SRafael Espindola raw_ostream &CStream) const { 91471928e68SAkira Hatanaka uint32_t Insn; 91571928e68SAkira Hatanaka 9164aa6bea7SRafael Espindola DecodeStatus Result = 9177fc5b874SRafael Espindola readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); 91871928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 91971928e68SAkira Hatanaka return MCDisassembler::Fail; 92071928e68SAkira Hatanaka 92171928e68SAkira Hatanaka // Calling the auto-generated decoder function. 9224aa6bea7SRafael Espindola Result = 9234aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips6432, Instr, Insn, Address, this, STI); 92471928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 92571928e68SAkira Hatanaka Size = 4; 92671928e68SAkira Hatanaka return Result; 92771928e68SAkira Hatanaka } 92871928e68SAkira Hatanaka // If we fail to decode in Mips64 decoder space we can try in Mips32 9294aa6bea7SRafael Espindola Result = 9304aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI); 93171928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 93271928e68SAkira Hatanaka Size = 4; 93371928e68SAkira Hatanaka return Result; 93471928e68SAkira Hatanaka } 93571928e68SAkira Hatanaka 93671928e68SAkira Hatanaka return MCDisassembler::Fail; 93771928e68SAkira Hatanaka } 93871928e68SAkira Hatanaka 939ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 940ec8a5490SReed Kotler unsigned RegNo, 941ec8a5490SReed Kotler uint64_t Address, 942ec8a5490SReed Kotler const void *Decoder) { 943ec8a5490SReed Kotler 944ec8a5490SReed Kotler return MCDisassembler::Fail; 945ec8a5490SReed Kotler 946ec8a5490SReed Kotler } 947ec8a5490SReed Kotler 94813e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 94971928e68SAkira Hatanaka unsigned RegNo, 95071928e68SAkira Hatanaka uint64_t Address, 95171928e68SAkira Hatanaka const void *Decoder) { 95271928e68SAkira Hatanaka 95371928e68SAkira Hatanaka if (RegNo > 31) 95471928e68SAkira Hatanaka return MCDisassembler::Fail; 95571928e68SAkira Hatanaka 95613e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); 9579bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 95871928e68SAkira Hatanaka return MCDisassembler::Success; 95971928e68SAkira Hatanaka } 96071928e68SAkira Hatanaka 961b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, 962b0852e54SZoran Jovanovic unsigned RegNo, 963b0852e54SZoran Jovanovic uint64_t Address, 964b0852e54SZoran Jovanovic const void *Decoder) { 965ea22c4cfSJozef Kolek if (RegNo > 7) 966b0852e54SZoran Jovanovic return MCDisassembler::Fail; 967ea22c4cfSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo); 968ea22c4cfSJozef Kolek Inst.addOperand(MCOperand::CreateReg(Reg)); 969ea22c4cfSJozef Kolek return MCDisassembler::Success; 970b0852e54SZoran Jovanovic } 971b0852e54SZoran Jovanovic 9721904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, 9731904fa21SJozef Kolek unsigned RegNo, 9741904fa21SJozef Kolek uint64_t Address, 9751904fa21SJozef Kolek const void *Decoder) { 976315e7ecaSJozef Kolek if (RegNo > 7) 9771904fa21SJozef Kolek return MCDisassembler::Fail; 978315e7ecaSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo); 979315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateReg(Reg)); 980315e7ecaSJozef Kolek return MCDisassembler::Success; 9811904fa21SJozef Kolek } 9821904fa21SJozef Kolek 98313e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 98471928e68SAkira Hatanaka unsigned RegNo, 98571928e68SAkira Hatanaka uint64_t Address, 98671928e68SAkira Hatanaka const void *Decoder) { 98771928e68SAkira Hatanaka if (RegNo > 31) 98871928e68SAkira Hatanaka return MCDisassembler::Fail; 98913e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); 9909bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 99171928e68SAkira Hatanaka return MCDisassembler::Success; 99271928e68SAkira Hatanaka } 99371928e68SAkira Hatanaka 9949bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 9959bfa2e2eSAkira Hatanaka unsigned RegNo, 9969bfa2e2eSAkira Hatanaka uint64_t Address, 9979bfa2e2eSAkira Hatanaka const void *Decoder) { 998e8860938SVladimir Medic if (static_cast<const MipsDisassembler *>(Decoder)->isGP64Bit()) 9999bfa2e2eSAkira Hatanaka return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); 10009bfa2e2eSAkira Hatanaka 10019bfa2e2eSAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 10029bfa2e2eSAkira Hatanaka } 10039bfa2e2eSAkira Hatanaka 1004654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 1005ecabd1a5SAkira Hatanaka unsigned RegNo, 1006ecabd1a5SAkira Hatanaka uint64_t Address, 1007ecabd1a5SAkira Hatanaka const void *Decoder) { 100813e6ccf3SAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 1009ecabd1a5SAkira Hatanaka } 1010ecabd1a5SAkira Hatanaka 101171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 101271928e68SAkira Hatanaka unsigned RegNo, 101371928e68SAkira Hatanaka uint64_t Address, 101471928e68SAkira Hatanaka const void *Decoder) { 101571928e68SAkira Hatanaka if (RegNo > 31) 101671928e68SAkira Hatanaka return MCDisassembler::Fail; 101771928e68SAkira Hatanaka 10189bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 10199bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 102071928e68SAkira Hatanaka return MCDisassembler::Success; 102171928e68SAkira Hatanaka } 102271928e68SAkira Hatanaka 102371928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 102471928e68SAkira Hatanaka unsigned RegNo, 102571928e68SAkira Hatanaka uint64_t Address, 102671928e68SAkira Hatanaka const void *Decoder) { 102771928e68SAkira Hatanaka if (RegNo > 31) 102871928e68SAkira Hatanaka return MCDisassembler::Fail; 102971928e68SAkira Hatanaka 10309bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 10319bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 103271928e68SAkira Hatanaka return MCDisassembler::Success; 103371928e68SAkira Hatanaka } 103471928e68SAkira Hatanaka 103571928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 103671928e68SAkira Hatanaka unsigned RegNo, 103771928e68SAkira Hatanaka uint64_t Address, 103871928e68SAkira Hatanaka const void *Decoder) { 1039253777fdSChad Rosier if (RegNo > 31) 1040253777fdSChad Rosier return MCDisassembler::Fail; 1041253777fdSChad Rosier unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); 1042253777fdSChad Rosier Inst.addOperand(MCOperand::CreateReg(Reg)); 104371928e68SAkira Hatanaka return MCDisassembler::Success; 104471928e68SAkira Hatanaka } 104571928e68SAkira Hatanaka 10461fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 10471fb1b8b8SAkira Hatanaka unsigned RegNo, 10481fb1b8b8SAkira Hatanaka uint64_t Address, 10491fb1b8b8SAkira Hatanaka const void *Decoder) { 10501fb1b8b8SAkira Hatanaka if (RegNo > 7) 10511fb1b8b8SAkira Hatanaka return MCDisassembler::Fail; 10521fb1b8b8SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); 10531fb1b8b8SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 10541fb1b8b8SAkira Hatanaka return MCDisassembler::Success; 10551fb1b8b8SAkira Hatanaka } 10561fb1b8b8SAkira Hatanaka 10570fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, 10580fa60416SDaniel Sanders uint64_t Address, 10590fa60416SDaniel Sanders const void *Decoder) { 10600fa60416SDaniel Sanders if (RegNo > 31) 10610fa60416SDaniel Sanders return MCDisassembler::Fail; 10620fa60416SDaniel Sanders 10630fa60416SDaniel Sanders unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo); 10640fa60416SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 10650fa60416SDaniel Sanders return MCDisassembler::Success; 10660fa60416SDaniel Sanders } 10670fa60416SDaniel Sanders 106871928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 106971928e68SAkira Hatanaka unsigned Insn, 107071928e68SAkira Hatanaka uint64_t Address, 107171928e68SAkira Hatanaka const void *Decoder) { 107271928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1073ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1074ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 10759bf2b567SAkira Hatanaka 107613e6ccf3SAkira Hatanaka Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 107713e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 107871928e68SAkira Hatanaka 1079d7ecf49eSVladimir Medic if(Inst.getOpcode() == Mips::SC || 1080d7ecf49eSVladimir Medic Inst.getOpcode() == Mips::SCD){ 10819bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 108271928e68SAkira Hatanaka } 108371928e68SAkira Hatanaka 10849bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 10859bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 108671928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 108771928e68SAkira Hatanaka 108871928e68SAkira Hatanaka return MCDisassembler::Success; 108971928e68SAkira Hatanaka } 109071928e68SAkira Hatanaka 109192db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 109292db6b78SDaniel Sanders unsigned Insn, 109392db6b78SDaniel Sanders uint64_t Address, 109492db6b78SDaniel Sanders const void *Decoder) { 109592db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 109692db6b78SDaniel Sanders unsigned Hint = fieldFromInstruction(Insn, 16, 5); 109792db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 109892db6b78SDaniel Sanders 109992db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 110092db6b78SDaniel Sanders 110192db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 110292db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 110392db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Hint)); 110492db6b78SDaniel Sanders 110592db6b78SDaniel Sanders return MCDisassembler::Success; 110692db6b78SDaniel Sanders } 110792db6b78SDaniel Sanders 1108ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst, 1109ab6d1cceSJozef Kolek unsigned Insn, 1110ab6d1cceSJozef Kolek uint64_t Address, 1111ab6d1cceSJozef Kolek const void *Decoder) { 1112ab6d1cceSJozef Kolek int Offset = SignExtend32<12>(Insn & 0xfff); 1113ab6d1cceSJozef Kolek unsigned Base = fieldFromInstruction(Insn, 16, 5); 1114ab6d1cceSJozef Kolek unsigned Hint = fieldFromInstruction(Insn, 21, 5); 1115ab6d1cceSJozef Kolek 1116ab6d1cceSJozef Kolek Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1117ab6d1cceSJozef Kolek 1118ab6d1cceSJozef Kolek Inst.addOperand(MCOperand::CreateReg(Base)); 1119ab6d1cceSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset)); 1120ab6d1cceSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Hint)); 1121ab6d1cceSJozef Kolek 1122ab6d1cceSJozef Kolek return MCDisassembler::Success; 1123ab6d1cceSJozef Kolek } 1124ab6d1cceSJozef Kolek 1125b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 1126b4484d62SDaniel Sanders unsigned Insn, 1127b4484d62SDaniel Sanders uint64_t Address, 1128b4484d62SDaniel Sanders const void *Decoder) { 1129b4484d62SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 1130b4484d62SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 1131b4484d62SDaniel Sanders 1132b4484d62SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1133b4484d62SDaniel Sanders 1134b4484d62SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 1135b4484d62SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 1136b4484d62SDaniel Sanders 1137b4484d62SDaniel Sanders return MCDisassembler::Success; 1138b4484d62SDaniel Sanders } 1139b4484d62SDaniel Sanders 1140fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 1141fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder) { 1142fe0bf9f6SMatheus Almeida int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10)); 1143fe0bf9f6SMatheus Almeida unsigned Reg = fieldFromInstruction(Insn, 6, 5); 1144fe0bf9f6SMatheus Almeida unsigned Base = fieldFromInstruction(Insn, 11, 5); 1145fe0bf9f6SMatheus Almeida 1146fe0bf9f6SMatheus Almeida Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg); 1147fe0bf9f6SMatheus Almeida Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1148fe0bf9f6SMatheus Almeida 1149fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Reg)); 1150fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Base)); 11516b59c449SMatheus Almeida 11526b59c449SMatheus Almeida // The immediate field of an LD/ST instruction is scaled which means it must 11536b59c449SMatheus Almeida // be multiplied (when decoding) by the size (in bytes) of the instructions' 11546b59c449SMatheus Almeida // data format. 11556b59c449SMatheus Almeida // .b - 1 byte 11566b59c449SMatheus Almeida // .h - 2 bytes 11576b59c449SMatheus Almeida // .w - 4 bytes 11586b59c449SMatheus Almeida // .d - 8 bytes 11596b59c449SMatheus Almeida switch(Inst.getOpcode()) 11606b59c449SMatheus Almeida { 11616b59c449SMatheus Almeida default: 11626b59c449SMatheus Almeida assert (0 && "Unexpected instruction"); 11636b59c449SMatheus Almeida return MCDisassembler::Fail; 11646b59c449SMatheus Almeida break; 11656b59c449SMatheus Almeida case Mips::LD_B: 11666b59c449SMatheus Almeida case Mips::ST_B: 1167fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateImm(Offset)); 11686b59c449SMatheus Almeida break; 11696b59c449SMatheus Almeida case Mips::LD_H: 11706b59c449SMatheus Almeida case Mips::ST_H: 1171d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(Offset * 2)); 11726b59c449SMatheus Almeida break; 11736b59c449SMatheus Almeida case Mips::LD_W: 11746b59c449SMatheus Almeida case Mips::ST_W: 1175d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(Offset * 4)); 11766b59c449SMatheus Almeida break; 11776b59c449SMatheus Almeida case Mips::LD_D: 11786b59c449SMatheus Almeida case Mips::ST_D: 1179d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(Offset * 8)); 11806b59c449SMatheus Almeida break; 11816b59c449SMatheus Almeida } 1182fe0bf9f6SMatheus Almeida 1183fe0bf9f6SMatheus Almeida return MCDisassembler::Success; 1184fe0bf9f6SMatheus Almeida } 1185fe0bf9f6SMatheus Almeida 1186315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 1187315e7ecaSJozef Kolek unsigned Insn, 1188315e7ecaSJozef Kolek uint64_t Address, 1189315e7ecaSJozef Kolek const void *Decoder) { 1190315e7ecaSJozef Kolek unsigned Offset = Insn & 0xf; 1191315e7ecaSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 7, 3); 1192315e7ecaSJozef Kolek unsigned Base = fieldFromInstruction(Insn, 4, 3); 1193315e7ecaSJozef Kolek 1194315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1195315e7ecaSJozef Kolek case Mips::LBU16_MM: 1196315e7ecaSJozef Kolek case Mips::LHU16_MM: 1197315e7ecaSJozef Kolek case Mips::LW16_MM: 1198315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder) 1199315e7ecaSJozef Kolek == MCDisassembler::Fail) 1200315e7ecaSJozef Kolek return MCDisassembler::Fail; 1201315e7ecaSJozef Kolek break; 1202315e7ecaSJozef Kolek case Mips::SB16_MM: 1203315e7ecaSJozef Kolek case Mips::SH16_MM: 1204315e7ecaSJozef Kolek case Mips::SW16_MM: 1205315e7ecaSJozef Kolek if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder) 1206315e7ecaSJozef Kolek == MCDisassembler::Fail) 1207315e7ecaSJozef Kolek return MCDisassembler::Fail; 1208315e7ecaSJozef Kolek break; 1209315e7ecaSJozef Kolek } 1210315e7ecaSJozef Kolek 1211315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder) 1212315e7ecaSJozef Kolek == MCDisassembler::Fail) 1213315e7ecaSJozef Kolek return MCDisassembler::Fail; 1214315e7ecaSJozef Kolek 1215315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1216315e7ecaSJozef Kolek case Mips::LBU16_MM: 1217315e7ecaSJozef Kolek if (Offset == 0xf) 1218315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(-1)); 1219315e7ecaSJozef Kolek else 1220315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset)); 1221315e7ecaSJozef Kolek break; 1222315e7ecaSJozef Kolek case Mips::SB16_MM: 1223315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset)); 1224315e7ecaSJozef Kolek break; 1225315e7ecaSJozef Kolek case Mips::LHU16_MM: 1226315e7ecaSJozef Kolek case Mips::SH16_MM: 1227315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset << 1)); 1228315e7ecaSJozef Kolek break; 1229315e7ecaSJozef Kolek case Mips::LW16_MM: 1230315e7ecaSJozef Kolek case Mips::SW16_MM: 1231315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset << 2)); 1232315e7ecaSJozef Kolek break; 1233315e7ecaSJozef Kolek } 1234315e7ecaSJozef Kolek 1235315e7ecaSJozef Kolek return MCDisassembler::Success; 1236315e7ecaSJozef Kolek } 1237315e7ecaSJozef Kolek 123812c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, 123912c6982bSJozef Kolek unsigned Insn, 124012c6982bSJozef Kolek uint64_t Address, 124112c6982bSJozef Kolek const void *Decoder) { 124212c6982bSJozef Kolek unsigned Offset = Insn & 0x1F; 124312c6982bSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 5, 5); 124412c6982bSJozef Kolek 124512c6982bSJozef Kolek Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 124612c6982bSJozef Kolek 124712c6982bSJozef Kolek Inst.addOperand(MCOperand::CreateReg(Reg)); 124812c6982bSJozef Kolek Inst.addOperand(MCOperand::CreateReg(Mips::SP)); 124912c6982bSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset << 2)); 125012c6982bSJozef Kolek 125112c6982bSJozef Kolek return MCDisassembler::Success; 125212c6982bSJozef Kolek } 125312c6982bSJozef Kolek 1254dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 1255dde3d582SVladimir Medic unsigned Insn, 1256dde3d582SVladimir Medic uint64_t Address, 1257dde3d582SVladimir Medic const void *Decoder) { 1258dde3d582SVladimir Medic int Offset = SignExtend32<12>(Insn & 0x0fff); 1259dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1260dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1261dde3d582SVladimir Medic 1262dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1263dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1264dde3d582SVladimir Medic 1265a4c4b5fcSZoran Jovanovic switch (Inst.getOpcode()) { 1266a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 1267a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 1268a4c4b5fcSZoran Jovanovic if (DecodeRegListOperand(Inst, Insn, Address, Decoder) 1269a4c4b5fcSZoran Jovanovic == MCDisassembler::Fail) 1270a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 1271a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Base)); 1272a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(Offset)); 1273a4c4b5fcSZoran Jovanovic break; 1274a4c4b5fcSZoran Jovanovic case Mips::SC_MM: 1275285cc289SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Reg)); 1276a4c4b5fcSZoran Jovanovic // fallthrough 1277a4c4b5fcSZoran Jovanovic default: 1278dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Reg)); 12792deca348SZoran Jovanovic if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) 12802deca348SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Reg+1)); 12812deca348SZoran Jovanovic 1282dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Base)); 1283dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Offset)); 1284a4c4b5fcSZoran Jovanovic } 1285dde3d582SVladimir Medic 1286dde3d582SVladimir Medic return MCDisassembler::Success; 1287dde3d582SVladimir Medic } 1288dde3d582SVladimir Medic 1289dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 1290dde3d582SVladimir Medic unsigned Insn, 1291dde3d582SVladimir Medic uint64_t Address, 1292dde3d582SVladimir Medic const void *Decoder) { 1293dde3d582SVladimir Medic int Offset = SignExtend32<16>(Insn & 0xffff); 1294dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1295dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1296dde3d582SVladimir Medic 1297dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1298dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1299dde3d582SVladimir Medic 1300dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Reg)); 1301dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Base)); 1302dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Offset)); 1303dde3d582SVladimir Medic 1304dde3d582SVladimir Medic return MCDisassembler::Success; 1305dde3d582SVladimir Medic } 1306dde3d582SVladimir Medic 130771928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, 130871928e68SAkira Hatanaka unsigned Insn, 130971928e68SAkira Hatanaka uint64_t Address, 131071928e68SAkira Hatanaka const void *Decoder) { 131171928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1312ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1313ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 131471928e68SAkira Hatanaka 13159bf2b567SAkira Hatanaka Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 131613e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 13179bf2b567SAkira Hatanaka 13189bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 13199bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 132071928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 132171928e68SAkira Hatanaka 132271928e68SAkira Hatanaka return MCDisassembler::Success; 132371928e68SAkira Hatanaka } 132471928e68SAkira Hatanaka 132592db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, 132692db6b78SDaniel Sanders unsigned Insn, 132792db6b78SDaniel Sanders uint64_t Address, 132892db6b78SDaniel Sanders const void *Decoder) { 132992db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 133092db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 133192db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 133292db6b78SDaniel Sanders 133392db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); 133492db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 133592db6b78SDaniel Sanders 133692db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 133792db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 133892db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 133992db6b78SDaniel Sanders 134092db6b78SDaniel Sanders return MCDisassembler::Success; 134192db6b78SDaniel Sanders } 134292db6b78SDaniel Sanders 134392db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, 134492db6b78SDaniel Sanders unsigned Insn, 134592db6b78SDaniel Sanders uint64_t Address, 134692db6b78SDaniel Sanders const void *Decoder) { 134792db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 134892db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 134992db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 135092db6b78SDaniel Sanders 135192db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP3RegClassID, Reg); 135292db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 135392db6b78SDaniel Sanders 135492db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 135592db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 135692db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 135792db6b78SDaniel Sanders 135892db6b78SDaniel Sanders return MCDisassembler::Success; 135992db6b78SDaniel Sanders } 136092db6b78SDaniel Sanders 1361*435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, 1362*435cf8a4SVladimir Medic unsigned Insn, 1363*435cf8a4SVladimir Medic uint64_t Address, 1364*435cf8a4SVladimir Medic const void *Decoder) { 1365*435cf8a4SVladimir Medic int Offset = SignExtend32<11>(Insn & 0x07ff); 1366*435cf8a4SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1367*435cf8a4SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 11, 5); 1368*435cf8a4SVladimir Medic 1369*435cf8a4SVladimir Medic Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); 1370*435cf8a4SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1371*435cf8a4SVladimir Medic 1372*435cf8a4SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Reg)); 1373*435cf8a4SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Base)); 1374*435cf8a4SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Offset)); 1375*435cf8a4SVladimir Medic 1376*435cf8a4SVladimir Medic return MCDisassembler::Success; 1377*435cf8a4SVladimir Medic } 13786a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 13796a803f61SDaniel Sanders unsigned Insn, 13806a803f61SDaniel Sanders uint64_t Address, 13816a803f61SDaniel Sanders const void *Decoder) { 13826a803f61SDaniel Sanders int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff); 13836a803f61SDaniel Sanders unsigned Rt = fieldFromInstruction(Insn, 16, 5); 13846a803f61SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 13856a803f61SDaniel Sanders 13866a803f61SDaniel Sanders Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt); 13876a803f61SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 13886a803f61SDaniel Sanders 13896a803f61SDaniel Sanders if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){ 13906a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Rt)); 13916a803f61SDaniel Sanders } 13926a803f61SDaniel Sanders 13936a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Rt)); 13946a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 13956a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 13966a803f61SDaniel Sanders 13976a803f61SDaniel Sanders return MCDisassembler::Success; 13986a803f61SDaniel Sanders } 139971928e68SAkira Hatanaka 140071928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 140171928e68SAkira Hatanaka unsigned RegNo, 140271928e68SAkira Hatanaka uint64_t Address, 140371928e68SAkira Hatanaka const void *Decoder) { 140471928e68SAkira Hatanaka // Currently only hardware register 29 is supported. 140571928e68SAkira Hatanaka if (RegNo != 29) 140671928e68SAkira Hatanaka return MCDisassembler::Fail; 140771928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); 140871928e68SAkira Hatanaka return MCDisassembler::Success; 140971928e68SAkira Hatanaka } 141071928e68SAkira Hatanaka 141171928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 141271928e68SAkira Hatanaka unsigned RegNo, 141371928e68SAkira Hatanaka uint64_t Address, 141471928e68SAkira Hatanaka const void *Decoder) { 14159bf2b567SAkira Hatanaka if (RegNo > 30 || RegNo %2) 141671928e68SAkira Hatanaka return MCDisassembler::Fail; 141771928e68SAkira Hatanaka 14189bf2b567SAkira Hatanaka ; 14199bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 14209bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 142171928e68SAkira Hatanaka return MCDisassembler::Success; 142271928e68SAkira Hatanaka } 142371928e68SAkira Hatanaka 142400fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 1425ecabd1a5SAkira Hatanaka unsigned RegNo, 1426ecabd1a5SAkira Hatanaka uint64_t Address, 1427ecabd1a5SAkira Hatanaka const void *Decoder) { 1428ecabd1a5SAkira Hatanaka if (RegNo >= 4) 1429ecabd1a5SAkira Hatanaka return MCDisassembler::Fail; 1430ecabd1a5SAkira Hatanaka 143100fcf2e1SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo); 1432ecabd1a5SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 1433ecabd1a5SAkira Hatanaka return MCDisassembler::Success; 1434ecabd1a5SAkira Hatanaka } 1435ecabd1a5SAkira Hatanaka 14368002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 143759bfaf77SAkira Hatanaka unsigned RegNo, 143859bfaf77SAkira Hatanaka uint64_t Address, 143959bfaf77SAkira Hatanaka const void *Decoder) { 144059bfaf77SAkira Hatanaka if (RegNo >= 4) 144159bfaf77SAkira Hatanaka return MCDisassembler::Fail; 144259bfaf77SAkira Hatanaka 14438002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo); 144459bfaf77SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 144559bfaf77SAkira Hatanaka return MCDisassembler::Success; 144659bfaf77SAkira Hatanaka } 144759bfaf77SAkira Hatanaka 14488002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 144959bfaf77SAkira Hatanaka unsigned RegNo, 145059bfaf77SAkira Hatanaka uint64_t Address, 145159bfaf77SAkira Hatanaka const void *Decoder) { 145259bfaf77SAkira Hatanaka if (RegNo >= 4) 145359bfaf77SAkira Hatanaka return MCDisassembler::Fail; 145459bfaf77SAkira Hatanaka 14558002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo); 145659bfaf77SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 145759bfaf77SAkira Hatanaka return MCDisassembler::Success; 145859bfaf77SAkira Hatanaka } 145959bfaf77SAkira Hatanaka 14603eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, 14613eb663b0SJack Carter unsigned RegNo, 14623eb663b0SJack Carter uint64_t Address, 14633eb663b0SJack Carter const void *Decoder) { 14643eb663b0SJack Carter if (RegNo > 31) 14653eb663b0SJack Carter return MCDisassembler::Fail; 14663eb663b0SJack Carter 14673eb663b0SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo); 14683eb663b0SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 14693eb663b0SJack Carter return MCDisassembler::Success; 14703eb663b0SJack Carter } 14713eb663b0SJack Carter 14725dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, 14735dc8ac92SJack Carter unsigned RegNo, 14745dc8ac92SJack Carter uint64_t Address, 14755dc8ac92SJack Carter const void *Decoder) { 14765dc8ac92SJack Carter if (RegNo > 31) 14775dc8ac92SJack Carter return MCDisassembler::Fail; 14785dc8ac92SJack Carter 14795dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo); 14805dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 14815dc8ac92SJack Carter return MCDisassembler::Success; 14825dc8ac92SJack Carter } 14835dc8ac92SJack Carter 14845dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, 14855dc8ac92SJack Carter unsigned RegNo, 14865dc8ac92SJack Carter uint64_t Address, 14875dc8ac92SJack Carter const void *Decoder) { 14885dc8ac92SJack Carter if (RegNo > 31) 14895dc8ac92SJack Carter return MCDisassembler::Fail; 14905dc8ac92SJack Carter 14915dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo); 14925dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 14935dc8ac92SJack Carter return MCDisassembler::Success; 14945dc8ac92SJack Carter } 14955dc8ac92SJack Carter 14965dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, 14975dc8ac92SJack Carter unsigned RegNo, 14985dc8ac92SJack Carter uint64_t Address, 14995dc8ac92SJack Carter const void *Decoder) { 15005dc8ac92SJack Carter if (RegNo > 31) 15015dc8ac92SJack Carter return MCDisassembler::Fail; 15025dc8ac92SJack Carter 15035dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo); 15045dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 15055dc8ac92SJack Carter return MCDisassembler::Success; 15065dc8ac92SJack Carter } 15075dc8ac92SJack Carter 1508a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, 1509a591fdc6SMatheus Almeida unsigned RegNo, 1510a591fdc6SMatheus Almeida uint64_t Address, 1511a591fdc6SMatheus Almeida const void *Decoder) { 1512a591fdc6SMatheus Almeida if (RegNo > 7) 1513a591fdc6SMatheus Almeida return MCDisassembler::Fail; 1514a591fdc6SMatheus Almeida 1515a591fdc6SMatheus Almeida unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo); 1516a591fdc6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Reg)); 1517a591fdc6SMatheus Almeida return MCDisassembler::Success; 1518a591fdc6SMatheus Almeida } 1519a591fdc6SMatheus Almeida 15202a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, 15212a83d680SDaniel Sanders unsigned RegNo, 15222a83d680SDaniel Sanders uint64_t Address, 15232a83d680SDaniel Sanders const void *Decoder) { 15242a83d680SDaniel Sanders if (RegNo > 31) 15252a83d680SDaniel Sanders return MCDisassembler::Fail; 15262a83d680SDaniel Sanders 15272a83d680SDaniel Sanders unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo); 15282a83d680SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 15292a83d680SDaniel Sanders return MCDisassembler::Success; 15302a83d680SDaniel Sanders } 15312a83d680SDaniel Sanders 153271928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 153371928e68SAkira Hatanaka unsigned Offset, 153471928e68SAkira Hatanaka uint64_t Address, 153571928e68SAkira Hatanaka const void *Decoder) { 1536d37bab61SAlexey Samsonov int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4; 153771928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 153871928e68SAkira Hatanaka return MCDisassembler::Success; 153971928e68SAkira Hatanaka } 154071928e68SAkira Hatanaka 154171928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 154271928e68SAkira Hatanaka unsigned Insn, 154371928e68SAkira Hatanaka uint64_t Address, 154471928e68SAkira Hatanaka const void *Decoder) { 154571928e68SAkira Hatanaka 1546ecaef49fSJim Grosbach unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 154771928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 154871928e68SAkira Hatanaka return MCDisassembler::Success; 154971928e68SAkira Hatanaka } 155071928e68SAkira Hatanaka 15513c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst, 15523c8869dcSZoran Jovanovic unsigned Offset, 15533c8869dcSZoran Jovanovic uint64_t Address, 15543c8869dcSZoran Jovanovic const void *Decoder) { 1555d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<21>(Offset) * 4; 15563c8869dcSZoran Jovanovic 15573c8869dcSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 15583c8869dcSZoran Jovanovic return MCDisassembler::Success; 15593c8869dcSZoran Jovanovic } 15603c8869dcSZoran Jovanovic 15613c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst, 15623c8869dcSZoran Jovanovic unsigned Offset, 15633c8869dcSZoran Jovanovic uint64_t Address, 15643c8869dcSZoran Jovanovic const void *Decoder) { 1565d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<26>(Offset) * 4; 15663c8869dcSZoran Jovanovic 15673c8869dcSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 15683c8869dcSZoran Jovanovic return MCDisassembler::Success; 15693c8869dcSZoran Jovanovic } 15703c8869dcSZoran Jovanovic 15719761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, 15729761e96bSJozef Kolek unsigned Offset, 15739761e96bSJozef Kolek uint64_t Address, 15749761e96bSJozef Kolek const void *Decoder) { 15759761e96bSJozef Kolek int32_t BranchOffset = SignExtend32<7>(Offset) << 1; 15769761e96bSJozef Kolek Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 15779761e96bSJozef Kolek return MCDisassembler::Success; 15789761e96bSJozef Kolek } 15799761e96bSJozef Kolek 15808a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 15818a80aa76SZoran Jovanovic unsigned Offset, 15828a80aa76SZoran Jovanovic uint64_t Address, 15838a80aa76SZoran Jovanovic const void *Decoder) { 1584d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<16>(Offset) * 2; 15858a80aa76SZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 15868a80aa76SZoran Jovanovic return MCDisassembler::Success; 15878a80aa76SZoran Jovanovic } 15888a80aa76SZoran Jovanovic 1589507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 1590507e084aSZoran Jovanovic unsigned Insn, 1591507e084aSZoran Jovanovic uint64_t Address, 1592507e084aSZoran Jovanovic const void *Decoder) { 1593507e084aSZoran Jovanovic unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1; 1594507e084aSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 1595507e084aSZoran Jovanovic return MCDisassembler::Success; 1596507e084aSZoran Jovanovic } 159771928e68SAkira Hatanaka 1598aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 1599aa2b9278SJozef Kolek unsigned Value, 1600aa2b9278SJozef Kolek uint64_t Address, 1601aa2b9278SJozef Kolek const void *Decoder) { 1602aa2b9278SJozef Kolek if (Value == 0) 1603aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(1)); 1604aa2b9278SJozef Kolek else if (Value == 0x7) 1605aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(-1)); 1606aa2b9278SJozef Kolek else 1607aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(Value << 2)); 1608aa2b9278SJozef Kolek return MCDisassembler::Success; 1609aa2b9278SJozef Kolek } 1610aa2b9278SJozef Kolek 1611aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, 1612aa2b9278SJozef Kolek unsigned Value, 1613aa2b9278SJozef Kolek uint64_t Address, 1614aa2b9278SJozef Kolek const void *Decoder) { 1615aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(Value << 2)); 1616aa2b9278SJozef Kolek return MCDisassembler::Success; 1617aa2b9278SJozef Kolek } 1618aa2b9278SJozef Kolek 1619aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst, 1620aa2b9278SJozef Kolek unsigned Value, 1621aa2b9278SJozef Kolek uint64_t Address, 1622aa2b9278SJozef Kolek const void *Decoder) { 1623aa2b9278SJozef Kolek if (Value == 0x7F) 1624aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(-1)); 1625aa2b9278SJozef Kolek else 1626aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(Value)); 1627aa2b9278SJozef Kolek return MCDisassembler::Success; 1628aa2b9278SJozef Kolek } 1629aa2b9278SJozef Kolek 1630aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst, 1631aa2b9278SJozef Kolek unsigned Value, 1632aa2b9278SJozef Kolek uint64_t Address, 1633aa2b9278SJozef Kolek const void *Decoder) { 1634aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(SignExtend32<4>(Value))); 1635aa2b9278SJozef Kolek return MCDisassembler::Success; 1636aa2b9278SJozef Kolek } 1637aa2b9278SJozef Kolek 163871928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 163971928e68SAkira Hatanaka unsigned Insn, 164071928e68SAkira Hatanaka uint64_t Address, 164171928e68SAkira Hatanaka const void *Decoder) { 164271928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); 164371928e68SAkira Hatanaka return MCDisassembler::Success; 164471928e68SAkira Hatanaka } 164571928e68SAkira Hatanaka 1646779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst, 1647779c5937SMatheus Almeida unsigned Insn, 1648779c5937SMatheus Almeida uint64_t Address, 1649779c5937SMatheus Almeida const void *Decoder) { 1650779c5937SMatheus Almeida // We add one to the immediate field as it was encoded as 'imm - 1'. 1651779c5937SMatheus Almeida Inst.addOperand(MCOperand::CreateImm(Insn + 1)); 1652779c5937SMatheus Almeida return MCDisassembler::Success; 1653779c5937SMatheus Almeida } 1654779c5937SMatheus Almeida 165571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 165671928e68SAkira Hatanaka unsigned Insn, 165771928e68SAkira Hatanaka uint64_t Address, 165871928e68SAkira Hatanaka const void *Decoder) { 165971928e68SAkira Hatanaka // First we need to grab the pos(lsb) from MCInst. 166071928e68SAkira Hatanaka int Pos = Inst.getOperand(2).getImm(); 166171928e68SAkira Hatanaka int Size = (int) Insn - Pos + 1; 166271928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 166371928e68SAkira Hatanaka return MCDisassembler::Success; 166471928e68SAkira Hatanaka } 166571928e68SAkira Hatanaka 166671928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 166771928e68SAkira Hatanaka unsigned Insn, 166871928e68SAkira Hatanaka uint64_t Address, 166971928e68SAkira Hatanaka const void *Decoder) { 167071928e68SAkira Hatanaka int Size = (int) Insn + 1; 167171928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 167271928e68SAkira Hatanaka return MCDisassembler::Success; 167371928e68SAkira Hatanaka } 1674b59e1a41SDaniel Sanders 1675b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 1676b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder) { 1677d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) * 4)); 1678b59e1a41SDaniel Sanders return MCDisassembler::Success; 1679b59e1a41SDaniel Sanders } 16802855142aSZoran Jovanovic 16812855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 16822855142aSZoran Jovanovic uint64_t Address, const void *Decoder) { 1683d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) * 8)); 16842855142aSZoran Jovanovic return MCDisassembler::Success; 16852855142aSZoran Jovanovic } 1686a4c4b5fcSZoran Jovanovic 1687b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 1688b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1689b682ddf3SVladimir Medic int32_t DecodedValue; 1690b682ddf3SVladimir Medic switch (Insn) { 1691b682ddf3SVladimir Medic case 0: DecodedValue = 256; break; 1692b682ddf3SVladimir Medic case 1: DecodedValue = 257; break; 1693b682ddf3SVladimir Medic case 510: DecodedValue = -258; break; 1694b682ddf3SVladimir Medic case 511: DecodedValue = -257; break; 1695b682ddf3SVladimir Medic default: DecodedValue = SignExtend32<9>(Insn); break; 1696b682ddf3SVladimir Medic } 16972c55974dSAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(DecodedValue * 4)); 1698b682ddf3SVladimir Medic return MCDisassembler::Success; 1699b682ddf3SVladimir Medic } 1700b682ddf3SVladimir Medic 1701b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 1702b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1703b682ddf3SVladimir Medic // Insn must be >= 0, since it is unsigned that condition is always true. 1704b682ddf3SVladimir Medic assert(Insn < 16); 1705b682ddf3SVladimir Medic int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 1706b682ddf3SVladimir Medic 255, 32768, 65535}; 1707b682ddf3SVladimir Medic Inst.addOperand(MCOperand::CreateImm(DecodedValues[Insn])); 1708b682ddf3SVladimir Medic return MCDisassembler::Success; 1709b682ddf3SVladimir Medic } 1710b682ddf3SVladimir Medic 1711b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, 1712b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1713b682ddf3SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Insn << 2)); 1714b682ddf3SVladimir Medic return MCDisassembler::Success; 1715b682ddf3SVladimir Medic } 1716b682ddf3SVladimir Medic 1717a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, 1718a4c4b5fcSZoran Jovanovic unsigned Insn, 1719a4c4b5fcSZoran Jovanovic uint64_t Address, 1720a4c4b5fcSZoran Jovanovic const void *Decoder) { 1721a4c4b5fcSZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5, 1722a4c4b5fcSZoran Jovanovic Mips::S6, Mips::FP}; 1723a4c4b5fcSZoran Jovanovic unsigned RegNum; 1724a4c4b5fcSZoran Jovanovic 1725a4c4b5fcSZoran Jovanovic unsigned RegLst = fieldFromInstruction(Insn, 21, 5); 1726a4c4b5fcSZoran Jovanovic // Empty register lists are not allowed. 1727a4c4b5fcSZoran Jovanovic if (RegLst == 0) 1728a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 1729a4c4b5fcSZoran Jovanovic 1730a4c4b5fcSZoran Jovanovic RegNum = RegLst & 0xf; 1731a4c4b5fcSZoran Jovanovic for (unsigned i = 0; i < RegNum; i++) 1732a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Regs[i])); 1733a4c4b5fcSZoran Jovanovic 1734a4c4b5fcSZoran Jovanovic if (RegLst & 0x10) 1735a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Mips::RA)); 1736a4c4b5fcSZoran Jovanovic 1737a4c4b5fcSZoran Jovanovic return MCDisassembler::Success; 1738a4c4b5fcSZoran Jovanovic } 1739f9a02500SZoran Jovanovic 1740f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 1741f9a02500SZoran Jovanovic uint64_t Address, 1742f9a02500SZoran Jovanovic const void *Decoder) { 1743f9a02500SZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3}; 1744f9a02500SZoran Jovanovic unsigned RegNum; 1745f9a02500SZoran Jovanovic 1746f9a02500SZoran Jovanovic unsigned RegLst = fieldFromInstruction(Insn, 4, 2); 1747f9a02500SZoran Jovanovic // Empty register lists are not allowed. 1748f9a02500SZoran Jovanovic if (RegLst == 0) 1749f9a02500SZoran Jovanovic return MCDisassembler::Fail; 1750f9a02500SZoran Jovanovic 1751f9a02500SZoran Jovanovic RegNum = RegLst & 0x3; 1752f9a02500SZoran Jovanovic for (unsigned i = 0; i < RegNum - 1; i++) 1753f9a02500SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Regs[i])); 1754f9a02500SZoran Jovanovic 1755f9a02500SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Mips::RA)); 1756f9a02500SZoran Jovanovic 1757f9a02500SZoran Jovanovic return MCDisassembler::Success; 1758f9a02500SZoran Jovanovic } 1759