171928e68SAkira Hatanaka //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===// 271928e68SAkira Hatanaka // 371928e68SAkira Hatanaka // The LLVM Compiler Infrastructure 471928e68SAkira Hatanaka // 571928e68SAkira Hatanaka // This file is distributed under the University of Illinois Open Source 671928e68SAkira Hatanaka // License. See LICENSE.TXT for details. 771928e68SAkira Hatanaka // 871928e68SAkira Hatanaka //===----------------------------------------------------------------------===// 971928e68SAkira Hatanaka // 1071928e68SAkira Hatanaka // This file is part of the Mips Disassembler. 1171928e68SAkira Hatanaka // 1271928e68SAkira Hatanaka //===----------------------------------------------------------------------===// 1371928e68SAkira Hatanaka 1471928e68SAkira Hatanaka #include "Mips.h" 159bf2b567SAkira Hatanaka #include "MipsRegisterInfo.h" 16ed0881b2SChandler Carruth #include "MipsSubtarget.h" 17a1bc0f56SLang Hames #include "llvm/MC/MCContext.h" 1871928e68SAkira Hatanaka #include "llvm/MC/MCDisassembler.h" 19ecaef49fSJim Grosbach #include "llvm/MC/MCFixedLenDisassembler.h" 20ed0881b2SChandler Carruth #include "llvm/MC/MCInst.h" 21ed0881b2SChandler Carruth #include "llvm/MC/MCSubtargetInfo.h" 22ed0881b2SChandler Carruth #include "llvm/Support/MathExtras.h" 2371928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h" 2471928e68SAkira Hatanaka 2571928e68SAkira Hatanaka using namespace llvm; 2671928e68SAkira Hatanaka 27e96dd897SChandler Carruth #define DEBUG_TYPE "mips-disassembler" 28e96dd897SChandler Carruth 2971928e68SAkira Hatanaka typedef MCDisassembler::DecodeStatus DecodeStatus; 3071928e68SAkira Hatanaka 31cb3e98cfSBenjamin Kramer namespace { 32cb3e98cfSBenjamin Kramer 334aa6bea7SRafael Espindola /// A disasembler class for Mips. 349bf2b567SAkira Hatanaka class MipsDisassemblerBase : public MCDisassembler { 3571928e68SAkira Hatanaka public: 36a1bc0f56SLang Hames MipsDisassemblerBase(const MCSubtargetInfo &STI, MCContext &Ctx, 374aa6bea7SRafael Espindola bool IsBigEndian) 384aa6bea7SRafael Espindola : MCDisassembler(STI, Ctx), 394aa6bea7SRafael Espindola IsN64(STI.getFeatureBits() & Mips::FeatureN64), 404aa6bea7SRafael Espindola IsBigEndian(IsBigEndian) {} 4171928e68SAkira Hatanaka 429bf2b567SAkira Hatanaka virtual ~MipsDisassemblerBase() {} 439bf2b567SAkira Hatanaka 449bfa2e2eSAkira Hatanaka bool isN64() const { return IsN64; } 459bfa2e2eSAkira Hatanaka 469bf2b567SAkira Hatanaka private: 479bfa2e2eSAkira Hatanaka bool IsN64; 489bf2b567SAkira Hatanaka protected: 494aa6bea7SRafael Espindola bool IsBigEndian; 509bf2b567SAkira Hatanaka }; 519bf2b567SAkira Hatanaka 524aa6bea7SRafael Espindola /// A disasembler class for Mips32. 539bf2b567SAkira Hatanaka class MipsDisassembler : public MipsDisassemblerBase { 54dde3d582SVladimir Medic bool IsMicroMips; 559bf2b567SAkira Hatanaka public: 56c171f65aSDaniel Sanders MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool bigEndian) 57c171f65aSDaniel Sanders : MipsDisassemblerBase(STI, Ctx, bigEndian) { 58dde3d582SVladimir Medic IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips; 59dde3d582SVladimir Medic } 6071928e68SAkira Hatanaka 61c171f65aSDaniel Sanders bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; } 62c171f65aSDaniel Sanders bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; } 63c171f65aSDaniel Sanders bool hasMips32r6() const { 645c582b2fSDaniel Sanders return STI.getFeatureBits() & Mips::FeatureMips32r6; 655c582b2fSDaniel Sanders } 665c582b2fSDaniel Sanders 670fa60416SDaniel Sanders bool isGP64() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; } 680fa60416SDaniel Sanders 69c171f65aSDaniel Sanders bool hasCOP3() const { 70c171f65aSDaniel Sanders // Only present in MIPS-I and MIPS-II 71c171f65aSDaniel Sanders return !hasMips32() && !hasMips3(); 72c171f65aSDaniel Sanders } 73c171f65aSDaniel Sanders 744aa6bea7SRafael Espindola DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 757fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address, 764aa6bea7SRafael Espindola raw_ostream &VStream, 774aa6bea7SRafael Espindola raw_ostream &CStream) const override; 7871928e68SAkira Hatanaka }; 7971928e68SAkira Hatanaka 804aa6bea7SRafael Espindola /// A disasembler class for Mips64. 819bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase { 8271928e68SAkira Hatanaka public: 83a1bc0f56SLang Hames Mips64Disassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 849bf2b567SAkira Hatanaka bool bigEndian) : 85a1bc0f56SLang Hames MipsDisassemblerBase(STI, Ctx, bigEndian) {} 8671928e68SAkira Hatanaka 874aa6bea7SRafael Espindola DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 887fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address, 894aa6bea7SRafael Espindola raw_ostream &VStream, 904aa6bea7SRafael Espindola raw_ostream &CStream) const override; 9171928e68SAkira Hatanaka }; 9271928e68SAkira Hatanaka 93cb3e98cfSBenjamin Kramer } // end anonymous namespace 94cb3e98cfSBenjamin Kramer 9571928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them. 9671928e68SAkira Hatanaka // Definitions are further down. 9713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 9871928e68SAkira Hatanaka unsigned RegNo, 9971928e68SAkira Hatanaka uint64_t Address, 10071928e68SAkira Hatanaka const void *Decoder); 10171928e68SAkira Hatanaka 102ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 103ec8a5490SReed Kotler unsigned RegNo, 104ec8a5490SReed Kotler uint64_t Address, 105ec8a5490SReed Kotler const void *Decoder); 106ec8a5490SReed Kotler 107b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, 108b0852e54SZoran Jovanovic unsigned RegNo, 109b0852e54SZoran Jovanovic uint64_t Address, 110b0852e54SZoran Jovanovic const void *Decoder); 111b0852e54SZoran Jovanovic 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 2318a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is 2328a80aa76SZoran Jovanovic // shifted left by 1 bit. 2338a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 2348a80aa76SZoran Jovanovic unsigned Offset, 2358a80aa76SZoran Jovanovic uint64_t Address, 2368a80aa76SZoran Jovanovic const void *Decoder); 2378a80aa76SZoran Jovanovic 238507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is 239507e084aSZoran Jovanovic // shifted left by 1 bit. 240507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 241507e084aSZoran Jovanovic unsigned Insn, 242507e084aSZoran Jovanovic uint64_t Address, 243507e084aSZoran Jovanovic const void *Decoder); 244507e084aSZoran Jovanovic 24571928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 24671928e68SAkira Hatanaka unsigned Insn, 24771928e68SAkira Hatanaka uint64_t Address, 24871928e68SAkira Hatanaka const void *Decoder); 24971928e68SAkira Hatanaka 25092db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 25192db6b78SDaniel Sanders unsigned Insn, 25292db6b78SDaniel Sanders uint64_t Address, 25392db6b78SDaniel Sanders const void *Decoder); 25492db6b78SDaniel Sanders 255b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 256b4484d62SDaniel Sanders unsigned Insn, 257b4484d62SDaniel Sanders uint64_t Address, 258b4484d62SDaniel Sanders const void *Decoder); 259b4484d62SDaniel Sanders 260fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 261fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder); 262fe0bf9f6SMatheus Almeida 263315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 264315e7ecaSJozef Kolek unsigned Insn, 265315e7ecaSJozef Kolek uint64_t Address, 266315e7ecaSJozef Kolek const void *Decoder); 267315e7ecaSJozef Kolek 268dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 269dde3d582SVladimir Medic unsigned Insn, 270dde3d582SVladimir Medic uint64_t Address, 271dde3d582SVladimir Medic const void *Decoder); 272dde3d582SVladimir Medic 273dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 274dde3d582SVladimir Medic unsigned Insn, 275dde3d582SVladimir Medic uint64_t Address, 276dde3d582SVladimir Medic const void *Decoder); 277dde3d582SVladimir Medic 27871928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 27971928e68SAkira Hatanaka uint64_t Address, 28071928e68SAkira Hatanaka const void *Decoder); 28171928e68SAkira Hatanaka 28292db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, 28392db6b78SDaniel Sanders uint64_t Address, 28492db6b78SDaniel Sanders const void *Decoder); 28592db6b78SDaniel Sanders 28692db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, 28792db6b78SDaniel Sanders uint64_t Address, 28892db6b78SDaniel Sanders const void *Decoder); 28992db6b78SDaniel Sanders 2906a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 2916a803f61SDaniel Sanders unsigned Insn, 2926a803f61SDaniel Sanders uint64_t Address, 2936a803f61SDaniel Sanders const void *Decoder); 2946a803f61SDaniel Sanders 295aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 296aa2b9278SJozef Kolek unsigned Value, 297aa2b9278SJozef Kolek uint64_t Address, 298aa2b9278SJozef Kolek const void *Decoder); 299aa2b9278SJozef Kolek 300aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, 301aa2b9278SJozef Kolek unsigned Value, 302aa2b9278SJozef Kolek uint64_t Address, 303aa2b9278SJozef Kolek const void *Decoder); 304aa2b9278SJozef Kolek 305aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst, 306aa2b9278SJozef Kolek unsigned Value, 307aa2b9278SJozef Kolek uint64_t Address, 308aa2b9278SJozef Kolek const void *Decoder); 309aa2b9278SJozef Kolek 310aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst, 311aa2b9278SJozef Kolek unsigned Value, 312aa2b9278SJozef Kolek uint64_t Address, 313aa2b9278SJozef Kolek const void *Decoder); 314aa2b9278SJozef Kolek 31571928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 31671928e68SAkira Hatanaka unsigned Insn, 31771928e68SAkira Hatanaka uint64_t Address, 31871928e68SAkira Hatanaka const void *Decoder); 31971928e68SAkira Hatanaka 320779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which 321779c5937SMatheus Almeida // is off by one. 322779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst, 323779c5937SMatheus Almeida unsigned Insn, 324779c5937SMatheus Almeida uint64_t Address, 325779c5937SMatheus Almeida const void *Decoder); 326779c5937SMatheus Almeida 32771928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 32871928e68SAkira Hatanaka unsigned Insn, 32971928e68SAkira Hatanaka uint64_t Address, 33071928e68SAkira Hatanaka const void *Decoder); 33171928e68SAkira Hatanaka 33271928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 33371928e68SAkira Hatanaka unsigned Insn, 33471928e68SAkira Hatanaka uint64_t Address, 33571928e68SAkira Hatanaka const void *Decoder); 33671928e68SAkira Hatanaka 337b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 338b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder); 339b59e1a41SDaniel Sanders 3402855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 3412855142aSZoran Jovanovic uint64_t Address, const void *Decoder); 3422855142aSZoran Jovanovic 343b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 344b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 345b682ddf3SVladimir Medic 346b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 347b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 348b682ddf3SVladimir Medic 349b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, 350b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 351b682ddf3SVladimir Medic 352b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't 353b50ccf8eSDaniel Sanders /// handle. 354b50ccf8eSDaniel Sanders template <typename InsnType> 355b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 356b50ccf8eSDaniel Sanders const void *Decoder); 3575c582b2fSDaniel Sanders 3585c582b2fSDaniel Sanders template <typename InsnType> 3595c582b2fSDaniel Sanders static DecodeStatus 3605c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3615c582b2fSDaniel Sanders const void *Decoder); 3625c582b2fSDaniel Sanders 3635c582b2fSDaniel Sanders template <typename InsnType> 3645c582b2fSDaniel Sanders static DecodeStatus 3655c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3665c582b2fSDaniel Sanders const void *Decoder); 3675c582b2fSDaniel Sanders 3685c582b2fSDaniel Sanders template <typename InsnType> 3695c582b2fSDaniel Sanders static DecodeStatus 3705c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3715c582b2fSDaniel Sanders const void *Decoder); 3725c582b2fSDaniel Sanders 3735c582b2fSDaniel Sanders template <typename InsnType> 3745c582b2fSDaniel Sanders static DecodeStatus 3755c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3765c582b2fSDaniel Sanders const void *Decoder); 3775c582b2fSDaniel Sanders 3785c582b2fSDaniel Sanders template <typename InsnType> 3795c582b2fSDaniel Sanders static DecodeStatus 3805c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 3815c582b2fSDaniel Sanders const void *Decoder); 3825c582b2fSDaniel Sanders 38328a0ca07SZoran Jovanovic template <typename InsnType> 38428a0ca07SZoran Jovanovic static DecodeStatus 38528a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 38628a0ca07SZoran Jovanovic const void *Decoder); 38728a0ca07SZoran Jovanovic 388a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn, 389a4c4b5fcSZoran Jovanovic uint64_t Address, 390a4c4b5fcSZoran Jovanovic const void *Decoder); 391a4c4b5fcSZoran Jovanovic 392f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 393f9a02500SZoran Jovanovic uint64_t Address, 394f9a02500SZoran Jovanovic const void *Decoder); 395f9a02500SZoran Jovanovic 39671928e68SAkira Hatanaka namespace llvm { 39771928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 39871928e68SAkira Hatanaka TheMips64elTarget; 39971928e68SAkira Hatanaka } 40071928e68SAkira Hatanaka 40171928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler( 40271928e68SAkira Hatanaka const Target &T, 403a1bc0f56SLang Hames const MCSubtargetInfo &STI, 404a1bc0f56SLang Hames MCContext &Ctx) { 405a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, true); 40671928e68SAkira Hatanaka } 40771928e68SAkira Hatanaka 40871928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler( 40971928e68SAkira Hatanaka const Target &T, 410a1bc0f56SLang Hames const MCSubtargetInfo &STI, 411a1bc0f56SLang Hames MCContext &Ctx) { 412a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, false); 41371928e68SAkira Hatanaka } 41471928e68SAkira Hatanaka 41571928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler( 41671928e68SAkira Hatanaka const Target &T, 417a1bc0f56SLang Hames const MCSubtargetInfo &STI, 418a1bc0f56SLang Hames MCContext &Ctx) { 419a1bc0f56SLang Hames return new Mips64Disassembler(STI, Ctx, true); 42071928e68SAkira Hatanaka } 42171928e68SAkira Hatanaka 42271928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler( 42371928e68SAkira Hatanaka const Target &T, 424a1bc0f56SLang Hames const MCSubtargetInfo &STI, 425a1bc0f56SLang Hames MCContext &Ctx) { 426a1bc0f56SLang Hames return new Mips64Disassembler(STI, Ctx, false); 42771928e68SAkira Hatanaka } 42871928e68SAkira Hatanaka 42971928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() { 43071928e68SAkira Hatanaka // Register the disassembler. 43171928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 43271928e68SAkira Hatanaka createMipsDisassembler); 43371928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 43471928e68SAkira Hatanaka createMipselDisassembler); 43571928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64Target, 43671928e68SAkira Hatanaka createMips64Disassembler); 43771928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 43871928e68SAkira Hatanaka createMips64elDisassembler); 43971928e68SAkira Hatanaka } 44071928e68SAkira Hatanaka 44171928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc" 44271928e68SAkira Hatanaka 4435c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 4445c582b2fSDaniel Sanders const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D); 4455c582b2fSDaniel Sanders const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo(); 4465c582b2fSDaniel Sanders return *(RegInfo->getRegClass(RC).begin() + RegNo); 4475c582b2fSDaniel Sanders } 4485c582b2fSDaniel Sanders 449b50ccf8eSDaniel Sanders template <typename InsnType> 450b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 451b50ccf8eSDaniel Sanders const void *Decoder) { 452b50ccf8eSDaniel Sanders typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *); 453b50ccf8eSDaniel Sanders // The size of the n field depends on the element size 454b50ccf8eSDaniel Sanders // The register class also depends on this. 455b50ccf8eSDaniel Sanders InsnType tmp = fieldFromInstruction(insn, 17, 5); 456b50ccf8eSDaniel Sanders unsigned NSize = 0; 457b50ccf8eSDaniel Sanders DecodeFN RegDecoder = nullptr; 458b50ccf8eSDaniel Sanders if ((tmp & 0x18) == 0x00) { // INSVE_B 459b50ccf8eSDaniel Sanders NSize = 4; 460b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128BRegisterClass; 461b50ccf8eSDaniel Sanders } else if ((tmp & 0x1c) == 0x10) { // INSVE_H 462b50ccf8eSDaniel Sanders NSize = 3; 463b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128HRegisterClass; 464b50ccf8eSDaniel Sanders } else if ((tmp & 0x1e) == 0x18) { // INSVE_W 465b50ccf8eSDaniel Sanders NSize = 2; 466b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128WRegisterClass; 467b50ccf8eSDaniel Sanders } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D 468b50ccf8eSDaniel Sanders NSize = 1; 469b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128DRegisterClass; 470b50ccf8eSDaniel Sanders } else 471b50ccf8eSDaniel Sanders llvm_unreachable("Invalid encoding"); 472b50ccf8eSDaniel Sanders 473b50ccf8eSDaniel Sanders assert(NSize != 0 && RegDecoder != nullptr); 474b50ccf8eSDaniel Sanders 475b50ccf8eSDaniel Sanders // $wd 476b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 6, 5); 477b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 478b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 479b50ccf8eSDaniel Sanders // $wd_in 480b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 481b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 482b50ccf8eSDaniel Sanders // $n 483b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 16, NSize); 484b50ccf8eSDaniel Sanders MI.addOperand(MCOperand::CreateImm(tmp)); 485b50ccf8eSDaniel Sanders // $ws 486b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 11, 5); 487b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 488b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 489b50ccf8eSDaniel Sanders // $n2 490b50ccf8eSDaniel Sanders MI.addOperand(MCOperand::CreateImm(0)); 491b50ccf8eSDaniel Sanders 492b50ccf8eSDaniel Sanders return MCDisassembler::Success; 493b50ccf8eSDaniel Sanders } 494b50ccf8eSDaniel Sanders 4955c582b2fSDaniel Sanders template <typename InsnType> 4965c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, 4975c582b2fSDaniel Sanders uint64_t Address, 4985c582b2fSDaniel Sanders const void *Decoder) { 4995c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5005c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 5015c582b2fSDaniel Sanders // ISA's instead). 5025c582b2fSDaniel Sanders // 5035c582b2fSDaniel Sanders // We have: 5045c582b2fSDaniel Sanders // 0b001000 sssss ttttt iiiiiiiiiiiiiiii 5055c582b2fSDaniel Sanders // BOVC if rs >= rt 5065c582b2fSDaniel Sanders // BEQZALC if rs == 0 && rt != 0 5075c582b2fSDaniel Sanders // BEQC if rs < rt && rs != 0 5085c582b2fSDaniel Sanders 5095c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 5105c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 511d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 5125c582b2fSDaniel Sanders bool HasRs = false; 5135c582b2fSDaniel Sanders 5145c582b2fSDaniel Sanders if (Rs >= Rt) { 5155c582b2fSDaniel Sanders MI.setOpcode(Mips::BOVC); 5165c582b2fSDaniel Sanders HasRs = true; 5175c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 5185c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQC); 5195c582b2fSDaniel Sanders HasRs = true; 5205c582b2fSDaniel Sanders } else 5215c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQZALC); 5225c582b2fSDaniel Sanders 5235c582b2fSDaniel Sanders if (HasRs) 5245c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5255c582b2fSDaniel Sanders Rs))); 5265c582b2fSDaniel Sanders 5275c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5285c582b2fSDaniel Sanders Rt))); 5295c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 5305c582b2fSDaniel Sanders 5315c582b2fSDaniel Sanders return MCDisassembler::Success; 5325c582b2fSDaniel Sanders } 5335c582b2fSDaniel Sanders 5345c582b2fSDaniel Sanders template <typename InsnType> 5355c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, 5365c582b2fSDaniel Sanders uint64_t Address, 5375c582b2fSDaniel Sanders const void *Decoder) { 5385c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5395c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 5405c582b2fSDaniel Sanders // ISA's instead). 5415c582b2fSDaniel Sanders // 5425c582b2fSDaniel Sanders // We have: 5435c582b2fSDaniel Sanders // 0b011000 sssss ttttt iiiiiiiiiiiiiiii 5445c582b2fSDaniel Sanders // BNVC if rs >= rt 5455c582b2fSDaniel Sanders // BNEZALC if rs == 0 && rt != 0 5465c582b2fSDaniel Sanders // BNEC if rs < rt && rs != 0 5475c582b2fSDaniel Sanders 5485c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 5495c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 550d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 5515c582b2fSDaniel Sanders bool HasRs = false; 5525c582b2fSDaniel Sanders 5535c582b2fSDaniel Sanders if (Rs >= Rt) { 5545c582b2fSDaniel Sanders MI.setOpcode(Mips::BNVC); 5555c582b2fSDaniel Sanders HasRs = true; 5565c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 5575c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEC); 5585c582b2fSDaniel Sanders HasRs = true; 5595c582b2fSDaniel Sanders } else 5605c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEZALC); 5615c582b2fSDaniel Sanders 5625c582b2fSDaniel Sanders if (HasRs) 5635c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5645c582b2fSDaniel Sanders Rs))); 5655c582b2fSDaniel Sanders 5665c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5675c582b2fSDaniel Sanders Rt))); 5685c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 5695c582b2fSDaniel Sanders 5705c582b2fSDaniel Sanders return MCDisassembler::Success; 5715c582b2fSDaniel Sanders } 5725c582b2fSDaniel Sanders 5735c582b2fSDaniel Sanders template <typename InsnType> 5745c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, 5755c582b2fSDaniel Sanders uint64_t Address, 5765c582b2fSDaniel Sanders const void *Decoder) { 5775c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5785c582b2fSDaniel Sanders // (otherwise we would have matched the BLEZL instruction from the earlier 5795c582b2fSDaniel Sanders // ISA's instead). 5805c582b2fSDaniel Sanders // 5815c582b2fSDaniel Sanders // We have: 5825c582b2fSDaniel Sanders // 0b010110 sssss ttttt iiiiiiiiiiiiiiii 5835c582b2fSDaniel Sanders // Invalid if rs == 0 5845c582b2fSDaniel Sanders // BLEZC if rs == 0 && rt != 0 5855c582b2fSDaniel Sanders // BGEZC if rs == rt && rt != 0 5865c582b2fSDaniel Sanders // BGEC if rs != rt && rs != 0 && rt != 0 5875c582b2fSDaniel Sanders 5885c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 5895c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 590d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 59128a0ca07SZoran Jovanovic bool HasRs = false; 5925c582b2fSDaniel Sanders 5935c582b2fSDaniel Sanders if (Rt == 0) 5945c582b2fSDaniel Sanders return MCDisassembler::Fail; 5955c582b2fSDaniel Sanders else if (Rs == 0) 5965c582b2fSDaniel Sanders MI.setOpcode(Mips::BLEZC); 5975c582b2fSDaniel Sanders else if (Rs == Rt) 5985c582b2fSDaniel Sanders MI.setOpcode(Mips::BGEZC); 59928a0ca07SZoran Jovanovic else { 60028a0ca07SZoran Jovanovic HasRs = true; 60128a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEC); 60228a0ca07SZoran Jovanovic } 60328a0ca07SZoran Jovanovic 60428a0ca07SZoran Jovanovic if (HasRs) 60528a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 60628a0ca07SZoran Jovanovic Rs))); 6075c582b2fSDaniel Sanders 6085c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6095c582b2fSDaniel Sanders Rt))); 6105c582b2fSDaniel Sanders 6115c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 6125c582b2fSDaniel Sanders 6135c582b2fSDaniel Sanders return MCDisassembler::Success; 6145c582b2fSDaniel Sanders } 6155c582b2fSDaniel Sanders 6165c582b2fSDaniel Sanders template <typename InsnType> 6175c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, 6185c582b2fSDaniel Sanders uint64_t Address, 6195c582b2fSDaniel Sanders const void *Decoder) { 6205c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6215c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZL instruction from the earlier 6225c582b2fSDaniel Sanders // ISA's instead). 6235c582b2fSDaniel Sanders // 6245c582b2fSDaniel Sanders // We have: 6255c582b2fSDaniel Sanders // 0b010111 sssss ttttt iiiiiiiiiiiiiiii 6265c582b2fSDaniel Sanders // Invalid if rs == 0 6275c582b2fSDaniel Sanders // BGTZC if rs == 0 && rt != 0 6285c582b2fSDaniel Sanders // BLTZC if rs == rt && rt != 0 6295c582b2fSDaniel Sanders // BLTC if rs != rt && rs != 0 && rt != 0 6305c582b2fSDaniel Sanders 6315c14b069SZoran Jovanovic bool HasRs = false; 6325c14b069SZoran Jovanovic 6335c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6345c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 635d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 6365c582b2fSDaniel Sanders 6375c582b2fSDaniel Sanders if (Rt == 0) 6385c582b2fSDaniel Sanders return MCDisassembler::Fail; 6395c582b2fSDaniel Sanders else if (Rs == 0) 6405c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZC); 6415c582b2fSDaniel Sanders else if (Rs == Rt) 6425c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZC); 6435c14b069SZoran Jovanovic else { 6445c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTC); 6455c14b069SZoran Jovanovic HasRs = true; 6465c14b069SZoran Jovanovic } 6475c14b069SZoran Jovanovic 6485c14b069SZoran Jovanovic if (HasRs) 6495c14b069SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6505c14b069SZoran Jovanovic Rs))); 6515c582b2fSDaniel Sanders 6525c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6535c582b2fSDaniel Sanders Rt))); 6545c582b2fSDaniel Sanders 6555c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 6565c582b2fSDaniel Sanders 6575c582b2fSDaniel Sanders return MCDisassembler::Success; 6585c582b2fSDaniel Sanders } 6595c582b2fSDaniel Sanders 6605c582b2fSDaniel Sanders template <typename InsnType> 6615c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, 6625c582b2fSDaniel Sanders uint64_t Address, 6635c582b2fSDaniel Sanders const void *Decoder) { 6645c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6655c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZ instruction from the earlier 6665c582b2fSDaniel Sanders // ISA's instead). 6675c582b2fSDaniel Sanders // 6685c582b2fSDaniel Sanders // We have: 6695c582b2fSDaniel Sanders // 0b000111 sssss ttttt iiiiiiiiiiiiiiii 6705c582b2fSDaniel Sanders // BGTZ if rt == 0 6715c582b2fSDaniel Sanders // BGTZALC if rs == 0 && rt != 0 6725c582b2fSDaniel Sanders // BLTZALC if rs != 0 && rs == rt 6735c582b2fSDaniel Sanders // BLTUC if rs != 0 && rs != rt 6745c582b2fSDaniel Sanders 6755c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6765c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 677d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 6785c582b2fSDaniel Sanders bool HasRs = false; 6795c582b2fSDaniel Sanders bool HasRt = false; 6805c582b2fSDaniel Sanders 6815c582b2fSDaniel Sanders if (Rt == 0) { 6825c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZ); 6835c582b2fSDaniel Sanders HasRs = true; 6845c582b2fSDaniel Sanders } else if (Rs == 0) { 6855c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZALC); 6865c582b2fSDaniel Sanders HasRt = true; 6875c582b2fSDaniel Sanders } else if (Rs == Rt) { 6885c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZALC); 6895c582b2fSDaniel Sanders HasRs = true; 6905c14b069SZoran Jovanovic } else { 6915c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTUC); 6925c14b069SZoran Jovanovic HasRs = true; 6935c14b069SZoran Jovanovic HasRt = true; 6945c14b069SZoran Jovanovic } 6955c582b2fSDaniel Sanders 6965c582b2fSDaniel Sanders if (HasRs) 6975c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6985c582b2fSDaniel Sanders Rs))); 6995c582b2fSDaniel Sanders 7005c582b2fSDaniel Sanders if (HasRt) 7015c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 7025c582b2fSDaniel Sanders Rt))); 7035c582b2fSDaniel Sanders 7045c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 7055c582b2fSDaniel Sanders 7065c582b2fSDaniel Sanders return MCDisassembler::Success; 7075c582b2fSDaniel Sanders } 7085c582b2fSDaniel Sanders 70928a0ca07SZoran Jovanovic template <typename InsnType> 71028a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn, 71128a0ca07SZoran Jovanovic uint64_t Address, 71228a0ca07SZoran Jovanovic const void *Decoder) { 71328a0ca07SZoran Jovanovic // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 71428a0ca07SZoran Jovanovic // (otherwise we would have matched the BLEZL instruction from the earlier 71528a0ca07SZoran Jovanovic // ISA's instead). 71628a0ca07SZoran Jovanovic // 71728a0ca07SZoran Jovanovic // We have: 71828a0ca07SZoran Jovanovic // 0b000110 sssss ttttt iiiiiiiiiiiiiiii 71928a0ca07SZoran Jovanovic // Invalid if rs == 0 72028a0ca07SZoran Jovanovic // BLEZALC if rs == 0 && rt != 0 72128a0ca07SZoran Jovanovic // BGEZALC if rs == rt && rt != 0 72228a0ca07SZoran Jovanovic // BGEUC if rs != rt && rs != 0 && rt != 0 72328a0ca07SZoran Jovanovic 72428a0ca07SZoran Jovanovic InsnType Rs = fieldFromInstruction(insn, 21, 5); 72528a0ca07SZoran Jovanovic InsnType Rt = fieldFromInstruction(insn, 16, 5); 726d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 72728a0ca07SZoran Jovanovic bool HasRs = false; 72828a0ca07SZoran Jovanovic 72928a0ca07SZoran Jovanovic if (Rt == 0) 73028a0ca07SZoran Jovanovic return MCDisassembler::Fail; 73128a0ca07SZoran Jovanovic else if (Rs == 0) 73228a0ca07SZoran Jovanovic MI.setOpcode(Mips::BLEZALC); 73328a0ca07SZoran Jovanovic else if (Rs == Rt) 73428a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEZALC); 73528a0ca07SZoran Jovanovic else { 73628a0ca07SZoran Jovanovic HasRs = true; 73728a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEUC); 73828a0ca07SZoran Jovanovic } 73928a0ca07SZoran Jovanovic 74028a0ca07SZoran Jovanovic if (HasRs) 74128a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 74228a0ca07SZoran Jovanovic Rs))); 74328a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 74428a0ca07SZoran Jovanovic Rt))); 74528a0ca07SZoran Jovanovic 74628a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateImm(Imm)); 74728a0ca07SZoran Jovanovic 74828a0ca07SZoran Jovanovic return MCDisassembler::Success; 74928a0ca07SZoran Jovanovic } 75028a0ca07SZoran Jovanovic 751ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted 752ea22c4cfSJozef Kolek /// according to the given endianess. 753ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 754ea22c4cfSJozef Kolek uint64_t &Size, uint32_t &Insn, 755ea22c4cfSJozef Kolek bool IsBigEndian) { 756ea22c4cfSJozef Kolek // We want to read exactly 2 Bytes of data. 757ea22c4cfSJozef Kolek if (Bytes.size() < 2) { 758ea22c4cfSJozef Kolek Size = 0; 759ea22c4cfSJozef Kolek return MCDisassembler::Fail; 760ea22c4cfSJozef Kolek } 761ea22c4cfSJozef Kolek 762ea22c4cfSJozef Kolek if (IsBigEndian) { 763ea22c4cfSJozef Kolek Insn = (Bytes[0] << 8) | Bytes[1]; 764ea22c4cfSJozef Kolek } else { 765ea22c4cfSJozef Kolek Insn = (Bytes[1] << 8) | Bytes[0]; 766ea22c4cfSJozef Kolek } 767ea22c4cfSJozef Kolek 768ea22c4cfSJozef Kolek return MCDisassembler::Success; 769ea22c4cfSJozef Kolek } 770ea22c4cfSJozef Kolek 7717fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted 7724aa6bea7SRafael Espindola /// according to the given endianess 7737fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 7747fc5b874SRafael Espindola uint64_t &Size, uint32_t &Insn, 7757fc5b874SRafael Espindola bool IsBigEndian, bool IsMicroMips) { 77671928e68SAkira Hatanaka // We want to read exactly 4 Bytes of data. 7777fc5b874SRafael Espindola if (Bytes.size() < 4) { 7784aa6bea7SRafael Espindola Size = 0; 77971928e68SAkira Hatanaka return MCDisassembler::Fail; 78071928e68SAkira Hatanaka } 78171928e68SAkira Hatanaka 782ea22c4cfSJozef Kolek // High 16 bits of a 32-bit microMIPS instruction (where the opcode is) 783ea22c4cfSJozef Kolek // always precede the low 16 bits in the instruction stream (that is, they 784ea22c4cfSJozef Kolek // are placed at lower addresses in the instruction stream). 785ea22c4cfSJozef Kolek // 786ea22c4cfSJozef Kolek // microMIPS byte ordering: 787ea22c4cfSJozef Kolek // Big-endian: 0 | 1 | 2 | 3 788ea22c4cfSJozef Kolek // Little-endian: 1 | 0 | 3 | 2 789ea22c4cfSJozef Kolek 7904aa6bea7SRafael Espindola if (IsBigEndian) { 79171928e68SAkira Hatanaka // Encoded as a big-endian 32-bit word in the stream. 7924aa6bea7SRafael Espindola Insn = 7934aa6bea7SRafael Espindola (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24); 7944aa6bea7SRafael Espindola } else { 795dde3d582SVladimir Medic if (IsMicroMips) { 7964aa6bea7SRafael Espindola Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) | 797dde3d582SVladimir Medic (Bytes[1] << 24); 798dde3d582SVladimir Medic } else { 7994aa6bea7SRafael Espindola Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | 80071928e68SAkira Hatanaka (Bytes[3] << 24); 80171928e68SAkira Hatanaka } 802dde3d582SVladimir Medic } 80371928e68SAkira Hatanaka 80471928e68SAkira Hatanaka return MCDisassembler::Success; 80571928e68SAkira Hatanaka } 80671928e68SAkira Hatanaka 8074aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 8087fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 80971928e68SAkira Hatanaka uint64_t Address, 8104aa6bea7SRafael Espindola raw_ostream &VStream, 8114aa6bea7SRafael Espindola raw_ostream &CStream) const { 81271928e68SAkira Hatanaka uint32_t Insn; 813ea22c4cfSJozef Kolek DecodeStatus Result; 81471928e68SAkira Hatanaka 815ea22c4cfSJozef Kolek if (IsMicroMips) { 816ea22c4cfSJozef Kolek Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); 817ea22c4cfSJozef Kolek 818ea22c4cfSJozef Kolek DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n"); 819ea22c4cfSJozef Kolek // Calling the auto-generated decoder function. 820ea22c4cfSJozef Kolek Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address, 821ea22c4cfSJozef Kolek this, STI); 822ea22c4cfSJozef Kolek if (Result != MCDisassembler::Fail) { 823ea22c4cfSJozef Kolek Size = 2; 824ea22c4cfSJozef Kolek return Result; 825ea22c4cfSJozef Kolek } 826ea22c4cfSJozef Kolek 827ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true); 82871928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 82971928e68SAkira Hatanaka return MCDisassembler::Fail; 83071928e68SAkira Hatanaka 831ea22c4cfSJozef Kolek DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); 832dde3d582SVladimir Medic // Calling the auto-generated decoder function. 8334aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, 834dde3d582SVladimir Medic this, STI); 835dde3d582SVladimir Medic if (Result != MCDisassembler::Fail) { 836dde3d582SVladimir Medic Size = 4; 837dde3d582SVladimir Medic return Result; 838dde3d582SVladimir Medic } 839dde3d582SVladimir Medic return MCDisassembler::Fail; 840dde3d582SVladimir Medic } 841dde3d582SVladimir Medic 842ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); 843ea22c4cfSJozef Kolek if (Result == MCDisassembler::Fail) 844ea22c4cfSJozef Kolek return MCDisassembler::Fail; 845ea22c4cfSJozef Kolek 846c171f65aSDaniel Sanders if (hasCOP3()) { 847c171f65aSDaniel Sanders DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n"); 848c171f65aSDaniel Sanders Result = 8494aa6bea7SRafael Espindola decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI); 850c171f65aSDaniel Sanders if (Result != MCDisassembler::Fail) { 851c171f65aSDaniel Sanders Size = 4; 852c171f65aSDaniel Sanders return Result; 853c171f65aSDaniel Sanders } 854c171f65aSDaniel Sanders } 855c171f65aSDaniel Sanders 856c171f65aSDaniel Sanders if (hasMips32r6() && isGP64()) { 8570fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n"); 8584aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn, 8590fa60416SDaniel Sanders Address, this, STI); 8600fa60416SDaniel Sanders if (Result != MCDisassembler::Fail) { 8610fa60416SDaniel Sanders Size = 4; 8620fa60416SDaniel Sanders return Result; 8630fa60416SDaniel Sanders } 8640fa60416SDaniel Sanders } 8650fa60416SDaniel Sanders 866c171f65aSDaniel Sanders if (hasMips32r6()) { 8670fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n"); 8684aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn, 8695c582b2fSDaniel Sanders Address, this, STI); 8705c582b2fSDaniel Sanders if (Result != MCDisassembler::Fail) { 8715c582b2fSDaniel Sanders Size = 4; 8725c582b2fSDaniel Sanders return Result; 8735c582b2fSDaniel Sanders } 8745c582b2fSDaniel Sanders } 8755c582b2fSDaniel Sanders 8760fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n"); 87771928e68SAkira Hatanaka // Calling the auto-generated decoder function. 8784aa6bea7SRafael Espindola Result = 8794aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI); 88071928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 88171928e68SAkira Hatanaka Size = 4; 88271928e68SAkira Hatanaka return Result; 88371928e68SAkira Hatanaka } 88471928e68SAkira Hatanaka 88571928e68SAkira Hatanaka return MCDisassembler::Fail; 88671928e68SAkira Hatanaka } 88771928e68SAkira Hatanaka 8884aa6bea7SRafael Espindola DecodeStatus Mips64Disassembler::getInstruction(MCInst &Instr, uint64_t &Size, 8897fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 89071928e68SAkira Hatanaka uint64_t Address, 8914aa6bea7SRafael Espindola raw_ostream &VStream, 8924aa6bea7SRafael Espindola raw_ostream &CStream) const { 89371928e68SAkira Hatanaka uint32_t Insn; 89471928e68SAkira Hatanaka 8954aa6bea7SRafael Espindola DecodeStatus Result = 8967fc5b874SRafael Espindola readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); 89771928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 89871928e68SAkira Hatanaka return MCDisassembler::Fail; 89971928e68SAkira Hatanaka 90071928e68SAkira Hatanaka // Calling the auto-generated decoder function. 9014aa6bea7SRafael Espindola Result = 9024aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips6432, Instr, Insn, Address, this, STI); 90371928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 90471928e68SAkira Hatanaka Size = 4; 90571928e68SAkira Hatanaka return Result; 90671928e68SAkira Hatanaka } 90771928e68SAkira Hatanaka // If we fail to decode in Mips64 decoder space we can try in Mips32 9084aa6bea7SRafael Espindola Result = 9094aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI); 91071928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 91171928e68SAkira Hatanaka Size = 4; 91271928e68SAkira Hatanaka return Result; 91371928e68SAkira Hatanaka } 91471928e68SAkira Hatanaka 91571928e68SAkira Hatanaka return MCDisassembler::Fail; 91671928e68SAkira Hatanaka } 91771928e68SAkira Hatanaka 918ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 919ec8a5490SReed Kotler unsigned RegNo, 920ec8a5490SReed Kotler uint64_t Address, 921ec8a5490SReed Kotler const void *Decoder) { 922ec8a5490SReed Kotler 923ec8a5490SReed Kotler return MCDisassembler::Fail; 924ec8a5490SReed Kotler 925ec8a5490SReed Kotler } 926ec8a5490SReed Kotler 92713e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 92871928e68SAkira Hatanaka unsigned RegNo, 92971928e68SAkira Hatanaka uint64_t Address, 93071928e68SAkira Hatanaka const void *Decoder) { 93171928e68SAkira Hatanaka 93271928e68SAkira Hatanaka if (RegNo > 31) 93371928e68SAkira Hatanaka return MCDisassembler::Fail; 93471928e68SAkira Hatanaka 93513e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); 9369bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 93771928e68SAkira Hatanaka return MCDisassembler::Success; 93871928e68SAkira Hatanaka } 93971928e68SAkira Hatanaka 940b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, 941b0852e54SZoran Jovanovic unsigned RegNo, 942b0852e54SZoran Jovanovic uint64_t Address, 943b0852e54SZoran Jovanovic const void *Decoder) { 944ea22c4cfSJozef Kolek if (RegNo > 7) 945b0852e54SZoran Jovanovic return MCDisassembler::Fail; 946ea22c4cfSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo); 947ea22c4cfSJozef Kolek Inst.addOperand(MCOperand::CreateReg(Reg)); 948ea22c4cfSJozef Kolek return MCDisassembler::Success; 949b0852e54SZoran Jovanovic } 950b0852e54SZoran Jovanovic 9511904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, 9521904fa21SJozef Kolek unsigned RegNo, 9531904fa21SJozef Kolek uint64_t Address, 9541904fa21SJozef Kolek const void *Decoder) { 955315e7ecaSJozef Kolek if (RegNo > 7) 9561904fa21SJozef Kolek return MCDisassembler::Fail; 957315e7ecaSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo); 958315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateReg(Reg)); 959315e7ecaSJozef Kolek return MCDisassembler::Success; 9601904fa21SJozef Kolek } 9611904fa21SJozef Kolek 96213e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 96371928e68SAkira Hatanaka unsigned RegNo, 96471928e68SAkira Hatanaka uint64_t Address, 96571928e68SAkira Hatanaka const void *Decoder) { 96671928e68SAkira Hatanaka if (RegNo > 31) 96771928e68SAkira Hatanaka return MCDisassembler::Fail; 96813e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); 9699bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 97071928e68SAkira Hatanaka return MCDisassembler::Success; 97171928e68SAkira Hatanaka } 97271928e68SAkira Hatanaka 9739bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 9749bfa2e2eSAkira Hatanaka unsigned RegNo, 9759bfa2e2eSAkira Hatanaka uint64_t Address, 9769bfa2e2eSAkira Hatanaka const void *Decoder) { 9779bfa2e2eSAkira Hatanaka if (static_cast<const MipsDisassembler *>(Decoder)->isN64()) 9789bfa2e2eSAkira Hatanaka return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); 9799bfa2e2eSAkira Hatanaka 9809bfa2e2eSAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 9819bfa2e2eSAkira Hatanaka } 9829bfa2e2eSAkira Hatanaka 983654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 984ecabd1a5SAkira Hatanaka unsigned RegNo, 985ecabd1a5SAkira Hatanaka uint64_t Address, 986ecabd1a5SAkira Hatanaka const void *Decoder) { 98713e6ccf3SAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 988ecabd1a5SAkira Hatanaka } 989ecabd1a5SAkira Hatanaka 99071928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 99171928e68SAkira Hatanaka unsigned RegNo, 99271928e68SAkira Hatanaka uint64_t Address, 99371928e68SAkira Hatanaka const void *Decoder) { 99471928e68SAkira Hatanaka if (RegNo > 31) 99571928e68SAkira Hatanaka return MCDisassembler::Fail; 99671928e68SAkira Hatanaka 9979bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 9989bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 99971928e68SAkira Hatanaka return MCDisassembler::Success; 100071928e68SAkira Hatanaka } 100171928e68SAkira Hatanaka 100271928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 100371928e68SAkira Hatanaka unsigned RegNo, 100471928e68SAkira Hatanaka uint64_t Address, 100571928e68SAkira Hatanaka const void *Decoder) { 100671928e68SAkira Hatanaka if (RegNo > 31) 100771928e68SAkira Hatanaka return MCDisassembler::Fail; 100871928e68SAkira Hatanaka 10099bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 10109bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 101171928e68SAkira Hatanaka return MCDisassembler::Success; 101271928e68SAkira Hatanaka } 101371928e68SAkira Hatanaka 101471928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 101571928e68SAkira Hatanaka unsigned RegNo, 101671928e68SAkira Hatanaka uint64_t Address, 101771928e68SAkira Hatanaka const void *Decoder) { 1018253777fdSChad Rosier if (RegNo > 31) 1019253777fdSChad Rosier return MCDisassembler::Fail; 1020253777fdSChad Rosier unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); 1021253777fdSChad Rosier Inst.addOperand(MCOperand::CreateReg(Reg)); 102271928e68SAkira Hatanaka return MCDisassembler::Success; 102371928e68SAkira Hatanaka } 102471928e68SAkira Hatanaka 10251fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 10261fb1b8b8SAkira Hatanaka unsigned RegNo, 10271fb1b8b8SAkira Hatanaka uint64_t Address, 10281fb1b8b8SAkira Hatanaka const void *Decoder) { 10291fb1b8b8SAkira Hatanaka if (RegNo > 7) 10301fb1b8b8SAkira Hatanaka return MCDisassembler::Fail; 10311fb1b8b8SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); 10321fb1b8b8SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 10331fb1b8b8SAkira Hatanaka return MCDisassembler::Success; 10341fb1b8b8SAkira Hatanaka } 10351fb1b8b8SAkira Hatanaka 10360fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, 10370fa60416SDaniel Sanders uint64_t Address, 10380fa60416SDaniel Sanders const void *Decoder) { 10390fa60416SDaniel Sanders if (RegNo > 31) 10400fa60416SDaniel Sanders return MCDisassembler::Fail; 10410fa60416SDaniel Sanders 10420fa60416SDaniel Sanders unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo); 10430fa60416SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 10440fa60416SDaniel Sanders return MCDisassembler::Success; 10450fa60416SDaniel Sanders } 10460fa60416SDaniel Sanders 104771928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 104871928e68SAkira Hatanaka unsigned Insn, 104971928e68SAkira Hatanaka uint64_t Address, 105071928e68SAkira Hatanaka const void *Decoder) { 105171928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1052ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1053ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 10549bf2b567SAkira Hatanaka 105513e6ccf3SAkira Hatanaka Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 105613e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 105771928e68SAkira Hatanaka 1058d7ecf49eSVladimir Medic if(Inst.getOpcode() == Mips::SC || 1059d7ecf49eSVladimir Medic Inst.getOpcode() == Mips::SCD){ 10609bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 106171928e68SAkira Hatanaka } 106271928e68SAkira Hatanaka 10639bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 10649bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 106571928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 106671928e68SAkira Hatanaka 106771928e68SAkira Hatanaka return MCDisassembler::Success; 106871928e68SAkira Hatanaka } 106971928e68SAkira Hatanaka 107092db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 107192db6b78SDaniel Sanders unsigned Insn, 107292db6b78SDaniel Sanders uint64_t Address, 107392db6b78SDaniel Sanders const void *Decoder) { 107492db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 107592db6b78SDaniel Sanders unsigned Hint = fieldFromInstruction(Insn, 16, 5); 107692db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 107792db6b78SDaniel Sanders 107892db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 107992db6b78SDaniel Sanders 108092db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 108192db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 108292db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Hint)); 108392db6b78SDaniel Sanders 108492db6b78SDaniel Sanders return MCDisassembler::Success; 108592db6b78SDaniel Sanders } 108692db6b78SDaniel Sanders 1087b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 1088b4484d62SDaniel Sanders unsigned Insn, 1089b4484d62SDaniel Sanders uint64_t Address, 1090b4484d62SDaniel Sanders const void *Decoder) { 1091b4484d62SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 1092b4484d62SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 1093b4484d62SDaniel Sanders 1094b4484d62SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1095b4484d62SDaniel Sanders 1096b4484d62SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 1097b4484d62SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 1098b4484d62SDaniel Sanders 1099b4484d62SDaniel Sanders return MCDisassembler::Success; 1100b4484d62SDaniel Sanders } 1101b4484d62SDaniel Sanders 1102fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 1103fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder) { 1104fe0bf9f6SMatheus Almeida int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10)); 1105fe0bf9f6SMatheus Almeida unsigned Reg = fieldFromInstruction(Insn, 6, 5); 1106fe0bf9f6SMatheus Almeida unsigned Base = fieldFromInstruction(Insn, 11, 5); 1107fe0bf9f6SMatheus Almeida 1108fe0bf9f6SMatheus Almeida Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg); 1109fe0bf9f6SMatheus Almeida Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1110fe0bf9f6SMatheus Almeida 1111fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Reg)); 1112fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Base)); 11136b59c449SMatheus Almeida 11146b59c449SMatheus Almeida // The immediate field of an LD/ST instruction is scaled which means it must 11156b59c449SMatheus Almeida // be multiplied (when decoding) by the size (in bytes) of the instructions' 11166b59c449SMatheus Almeida // data format. 11176b59c449SMatheus Almeida // .b - 1 byte 11186b59c449SMatheus Almeida // .h - 2 bytes 11196b59c449SMatheus Almeida // .w - 4 bytes 11206b59c449SMatheus Almeida // .d - 8 bytes 11216b59c449SMatheus Almeida switch(Inst.getOpcode()) 11226b59c449SMatheus Almeida { 11236b59c449SMatheus Almeida default: 11246b59c449SMatheus Almeida assert (0 && "Unexpected instruction"); 11256b59c449SMatheus Almeida return MCDisassembler::Fail; 11266b59c449SMatheus Almeida break; 11276b59c449SMatheus Almeida case Mips::LD_B: 11286b59c449SMatheus Almeida case Mips::ST_B: 1129fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateImm(Offset)); 11306b59c449SMatheus Almeida break; 11316b59c449SMatheus Almeida case Mips::LD_H: 11326b59c449SMatheus Almeida case Mips::ST_H: 1133d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(Offset * 2)); 11346b59c449SMatheus Almeida break; 11356b59c449SMatheus Almeida case Mips::LD_W: 11366b59c449SMatheus Almeida case Mips::ST_W: 1137d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(Offset * 4)); 11386b59c449SMatheus Almeida break; 11396b59c449SMatheus Almeida case Mips::LD_D: 11406b59c449SMatheus Almeida case Mips::ST_D: 1141d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(Offset * 8)); 11426b59c449SMatheus Almeida break; 11436b59c449SMatheus Almeida } 1144fe0bf9f6SMatheus Almeida 1145fe0bf9f6SMatheus Almeida return MCDisassembler::Success; 1146fe0bf9f6SMatheus Almeida } 1147fe0bf9f6SMatheus Almeida 1148315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 1149315e7ecaSJozef Kolek unsigned Insn, 1150315e7ecaSJozef Kolek uint64_t Address, 1151315e7ecaSJozef Kolek const void *Decoder) { 1152315e7ecaSJozef Kolek unsigned Offset = Insn & 0xf; 1153315e7ecaSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 7, 3); 1154315e7ecaSJozef Kolek unsigned Base = fieldFromInstruction(Insn, 4, 3); 1155315e7ecaSJozef Kolek 1156315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1157315e7ecaSJozef Kolek case Mips::LBU16_MM: 1158315e7ecaSJozef Kolek case Mips::LHU16_MM: 1159315e7ecaSJozef Kolek case Mips::LW16_MM: 1160315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder) 1161315e7ecaSJozef Kolek == MCDisassembler::Fail) 1162315e7ecaSJozef Kolek return MCDisassembler::Fail; 1163315e7ecaSJozef Kolek break; 1164315e7ecaSJozef Kolek case Mips::SB16_MM: 1165315e7ecaSJozef Kolek case Mips::SH16_MM: 1166315e7ecaSJozef Kolek case Mips::SW16_MM: 1167315e7ecaSJozef Kolek if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder) 1168315e7ecaSJozef Kolek == MCDisassembler::Fail) 1169315e7ecaSJozef Kolek return MCDisassembler::Fail; 1170315e7ecaSJozef Kolek break; 1171315e7ecaSJozef Kolek } 1172315e7ecaSJozef Kolek 1173315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder) 1174315e7ecaSJozef Kolek == MCDisassembler::Fail) 1175315e7ecaSJozef Kolek return MCDisassembler::Fail; 1176315e7ecaSJozef Kolek 1177315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1178315e7ecaSJozef Kolek case Mips::LBU16_MM: 1179315e7ecaSJozef Kolek if (Offset == 0xf) 1180315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(-1)); 1181315e7ecaSJozef Kolek else 1182315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset)); 1183315e7ecaSJozef Kolek break; 1184315e7ecaSJozef Kolek case Mips::SB16_MM: 1185315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset)); 1186315e7ecaSJozef Kolek break; 1187315e7ecaSJozef Kolek case Mips::LHU16_MM: 1188315e7ecaSJozef Kolek case Mips::SH16_MM: 1189315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset << 1)); 1190315e7ecaSJozef Kolek break; 1191315e7ecaSJozef Kolek case Mips::LW16_MM: 1192315e7ecaSJozef Kolek case Mips::SW16_MM: 1193315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset << 2)); 1194315e7ecaSJozef Kolek break; 1195315e7ecaSJozef Kolek } 1196315e7ecaSJozef Kolek 1197315e7ecaSJozef Kolek return MCDisassembler::Success; 1198315e7ecaSJozef Kolek } 1199315e7ecaSJozef Kolek 1200dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 1201dde3d582SVladimir Medic unsigned Insn, 1202dde3d582SVladimir Medic uint64_t Address, 1203dde3d582SVladimir Medic const void *Decoder) { 1204dde3d582SVladimir Medic int Offset = SignExtend32<12>(Insn & 0x0fff); 1205dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1206dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1207dde3d582SVladimir Medic 1208dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1209dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1210dde3d582SVladimir Medic 1211a4c4b5fcSZoran Jovanovic switch (Inst.getOpcode()) { 1212a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 1213a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 1214a4c4b5fcSZoran Jovanovic if (DecodeRegListOperand(Inst, Insn, Address, Decoder) 1215a4c4b5fcSZoran Jovanovic == MCDisassembler::Fail) 1216a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 1217a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Base)); 1218a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(Offset)); 1219a4c4b5fcSZoran Jovanovic break; 1220a4c4b5fcSZoran Jovanovic case Mips::SC_MM: 1221285cc289SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Reg)); 1222a4c4b5fcSZoran Jovanovic // fallthrough 1223a4c4b5fcSZoran Jovanovic default: 1224dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Reg)); 1225*2deca348SZoran Jovanovic if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) 1226*2deca348SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Reg+1)); 1227*2deca348SZoran Jovanovic 1228dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Base)); 1229dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Offset)); 1230a4c4b5fcSZoran Jovanovic } 1231dde3d582SVladimir Medic 1232dde3d582SVladimir Medic return MCDisassembler::Success; 1233dde3d582SVladimir Medic } 1234dde3d582SVladimir Medic 1235dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 1236dde3d582SVladimir Medic unsigned Insn, 1237dde3d582SVladimir Medic uint64_t Address, 1238dde3d582SVladimir Medic const void *Decoder) { 1239dde3d582SVladimir Medic int Offset = SignExtend32<16>(Insn & 0xffff); 1240dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1241dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1242dde3d582SVladimir Medic 1243dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1244dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1245dde3d582SVladimir Medic 1246dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Reg)); 1247dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Base)); 1248dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Offset)); 1249dde3d582SVladimir Medic 1250dde3d582SVladimir Medic return MCDisassembler::Success; 1251dde3d582SVladimir Medic } 1252dde3d582SVladimir Medic 125371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, 125471928e68SAkira Hatanaka unsigned Insn, 125571928e68SAkira Hatanaka uint64_t Address, 125671928e68SAkira Hatanaka const void *Decoder) { 125771928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1258ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1259ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 126071928e68SAkira Hatanaka 12619bf2b567SAkira Hatanaka Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 126213e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 12639bf2b567SAkira Hatanaka 12649bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 12659bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 126671928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 126771928e68SAkira Hatanaka 126871928e68SAkira Hatanaka return MCDisassembler::Success; 126971928e68SAkira Hatanaka } 127071928e68SAkira Hatanaka 127192db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, 127292db6b78SDaniel Sanders unsigned Insn, 127392db6b78SDaniel Sanders uint64_t Address, 127492db6b78SDaniel Sanders const void *Decoder) { 127592db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 127692db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 127792db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 127892db6b78SDaniel Sanders 127992db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); 128092db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 128192db6b78SDaniel Sanders 128292db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 128392db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 128492db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 128592db6b78SDaniel Sanders 128692db6b78SDaniel Sanders return MCDisassembler::Success; 128792db6b78SDaniel Sanders } 128892db6b78SDaniel Sanders 128992db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, 129092db6b78SDaniel Sanders unsigned Insn, 129192db6b78SDaniel Sanders uint64_t Address, 129292db6b78SDaniel Sanders const void *Decoder) { 129392db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 129492db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 129592db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 129692db6b78SDaniel Sanders 129792db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP3RegClassID, Reg); 129892db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 129992db6b78SDaniel Sanders 130092db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 130192db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 130292db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 130392db6b78SDaniel Sanders 130492db6b78SDaniel Sanders return MCDisassembler::Success; 130592db6b78SDaniel Sanders } 130692db6b78SDaniel Sanders 13076a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 13086a803f61SDaniel Sanders unsigned Insn, 13096a803f61SDaniel Sanders uint64_t Address, 13106a803f61SDaniel Sanders const void *Decoder) { 13116a803f61SDaniel Sanders int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff); 13126a803f61SDaniel Sanders unsigned Rt = fieldFromInstruction(Insn, 16, 5); 13136a803f61SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 13146a803f61SDaniel Sanders 13156a803f61SDaniel Sanders Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt); 13166a803f61SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 13176a803f61SDaniel Sanders 13186a803f61SDaniel Sanders if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){ 13196a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Rt)); 13206a803f61SDaniel Sanders } 13216a803f61SDaniel Sanders 13226a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Rt)); 13236a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 13246a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 13256a803f61SDaniel Sanders 13266a803f61SDaniel Sanders return MCDisassembler::Success; 13276a803f61SDaniel Sanders } 132871928e68SAkira Hatanaka 132971928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 133071928e68SAkira Hatanaka unsigned RegNo, 133171928e68SAkira Hatanaka uint64_t Address, 133271928e68SAkira Hatanaka const void *Decoder) { 133371928e68SAkira Hatanaka // Currently only hardware register 29 is supported. 133471928e68SAkira Hatanaka if (RegNo != 29) 133571928e68SAkira Hatanaka return MCDisassembler::Fail; 133671928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); 133771928e68SAkira Hatanaka return MCDisassembler::Success; 133871928e68SAkira Hatanaka } 133971928e68SAkira Hatanaka 134071928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 134171928e68SAkira Hatanaka unsigned RegNo, 134271928e68SAkira Hatanaka uint64_t Address, 134371928e68SAkira Hatanaka const void *Decoder) { 13449bf2b567SAkira Hatanaka if (RegNo > 30 || RegNo %2) 134571928e68SAkira Hatanaka return MCDisassembler::Fail; 134671928e68SAkira Hatanaka 13479bf2b567SAkira Hatanaka ; 13489bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 13499bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 135071928e68SAkira Hatanaka return MCDisassembler::Success; 135171928e68SAkira Hatanaka } 135271928e68SAkira Hatanaka 135300fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 1354ecabd1a5SAkira Hatanaka unsigned RegNo, 1355ecabd1a5SAkira Hatanaka uint64_t Address, 1356ecabd1a5SAkira Hatanaka const void *Decoder) { 1357ecabd1a5SAkira Hatanaka if (RegNo >= 4) 1358ecabd1a5SAkira Hatanaka return MCDisassembler::Fail; 1359ecabd1a5SAkira Hatanaka 136000fcf2e1SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo); 1361ecabd1a5SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 1362ecabd1a5SAkira Hatanaka return MCDisassembler::Success; 1363ecabd1a5SAkira Hatanaka } 1364ecabd1a5SAkira Hatanaka 13658002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 136659bfaf77SAkira Hatanaka unsigned RegNo, 136759bfaf77SAkira Hatanaka uint64_t Address, 136859bfaf77SAkira Hatanaka const void *Decoder) { 136959bfaf77SAkira Hatanaka if (RegNo >= 4) 137059bfaf77SAkira Hatanaka return MCDisassembler::Fail; 137159bfaf77SAkira Hatanaka 13728002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo); 137359bfaf77SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 137459bfaf77SAkira Hatanaka return MCDisassembler::Success; 137559bfaf77SAkira Hatanaka } 137659bfaf77SAkira Hatanaka 13778002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 137859bfaf77SAkira Hatanaka unsigned RegNo, 137959bfaf77SAkira Hatanaka uint64_t Address, 138059bfaf77SAkira Hatanaka const void *Decoder) { 138159bfaf77SAkira Hatanaka if (RegNo >= 4) 138259bfaf77SAkira Hatanaka return MCDisassembler::Fail; 138359bfaf77SAkira Hatanaka 13848002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo); 138559bfaf77SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 138659bfaf77SAkira Hatanaka return MCDisassembler::Success; 138759bfaf77SAkira Hatanaka } 138859bfaf77SAkira Hatanaka 13893eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, 13903eb663b0SJack Carter unsigned RegNo, 13913eb663b0SJack Carter uint64_t Address, 13923eb663b0SJack Carter const void *Decoder) { 13933eb663b0SJack Carter if (RegNo > 31) 13943eb663b0SJack Carter return MCDisassembler::Fail; 13953eb663b0SJack Carter 13963eb663b0SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo); 13973eb663b0SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 13983eb663b0SJack Carter return MCDisassembler::Success; 13993eb663b0SJack Carter } 14003eb663b0SJack Carter 14015dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, 14025dc8ac92SJack Carter unsigned RegNo, 14035dc8ac92SJack Carter uint64_t Address, 14045dc8ac92SJack Carter const void *Decoder) { 14055dc8ac92SJack Carter if (RegNo > 31) 14065dc8ac92SJack Carter return MCDisassembler::Fail; 14075dc8ac92SJack Carter 14085dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo); 14095dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 14105dc8ac92SJack Carter return MCDisassembler::Success; 14115dc8ac92SJack Carter } 14125dc8ac92SJack Carter 14135dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, 14145dc8ac92SJack Carter unsigned RegNo, 14155dc8ac92SJack Carter uint64_t Address, 14165dc8ac92SJack Carter const void *Decoder) { 14175dc8ac92SJack Carter if (RegNo > 31) 14185dc8ac92SJack Carter return MCDisassembler::Fail; 14195dc8ac92SJack Carter 14205dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo); 14215dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 14225dc8ac92SJack Carter return MCDisassembler::Success; 14235dc8ac92SJack Carter } 14245dc8ac92SJack Carter 14255dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, 14265dc8ac92SJack Carter unsigned RegNo, 14275dc8ac92SJack Carter uint64_t Address, 14285dc8ac92SJack Carter const void *Decoder) { 14295dc8ac92SJack Carter if (RegNo > 31) 14305dc8ac92SJack Carter return MCDisassembler::Fail; 14315dc8ac92SJack Carter 14325dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo); 14335dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 14345dc8ac92SJack Carter return MCDisassembler::Success; 14355dc8ac92SJack Carter } 14365dc8ac92SJack Carter 1437a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, 1438a591fdc6SMatheus Almeida unsigned RegNo, 1439a591fdc6SMatheus Almeida uint64_t Address, 1440a591fdc6SMatheus Almeida const void *Decoder) { 1441a591fdc6SMatheus Almeida if (RegNo > 7) 1442a591fdc6SMatheus Almeida return MCDisassembler::Fail; 1443a591fdc6SMatheus Almeida 1444a591fdc6SMatheus Almeida unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo); 1445a591fdc6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Reg)); 1446a591fdc6SMatheus Almeida return MCDisassembler::Success; 1447a591fdc6SMatheus Almeida } 1448a591fdc6SMatheus Almeida 14492a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, 14502a83d680SDaniel Sanders unsigned RegNo, 14512a83d680SDaniel Sanders uint64_t Address, 14522a83d680SDaniel Sanders const void *Decoder) { 14532a83d680SDaniel Sanders if (RegNo > 31) 14542a83d680SDaniel Sanders return MCDisassembler::Fail; 14552a83d680SDaniel Sanders 14562a83d680SDaniel Sanders unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo); 14572a83d680SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 14582a83d680SDaniel Sanders return MCDisassembler::Success; 14592a83d680SDaniel Sanders } 14602a83d680SDaniel Sanders 146171928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 146271928e68SAkira Hatanaka unsigned Offset, 146371928e68SAkira Hatanaka uint64_t Address, 146471928e68SAkira Hatanaka const void *Decoder) { 1465d37bab61SAlexey Samsonov int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4; 146671928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 146771928e68SAkira Hatanaka return MCDisassembler::Success; 146871928e68SAkira Hatanaka } 146971928e68SAkira Hatanaka 147071928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 147171928e68SAkira Hatanaka unsigned Insn, 147271928e68SAkira Hatanaka uint64_t Address, 147371928e68SAkira Hatanaka const void *Decoder) { 147471928e68SAkira Hatanaka 1475ecaef49fSJim Grosbach unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 147671928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 147771928e68SAkira Hatanaka return MCDisassembler::Success; 147871928e68SAkira Hatanaka } 147971928e68SAkira Hatanaka 14803c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst, 14813c8869dcSZoran Jovanovic unsigned Offset, 14823c8869dcSZoran Jovanovic uint64_t Address, 14833c8869dcSZoran Jovanovic const void *Decoder) { 1484d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<21>(Offset) * 4; 14853c8869dcSZoran Jovanovic 14863c8869dcSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 14873c8869dcSZoran Jovanovic return MCDisassembler::Success; 14883c8869dcSZoran Jovanovic } 14893c8869dcSZoran Jovanovic 14903c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst, 14913c8869dcSZoran Jovanovic unsigned Offset, 14923c8869dcSZoran Jovanovic uint64_t Address, 14933c8869dcSZoran Jovanovic const void *Decoder) { 1494d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<26>(Offset) * 4; 14953c8869dcSZoran Jovanovic 14963c8869dcSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 14973c8869dcSZoran Jovanovic return MCDisassembler::Success; 14983c8869dcSZoran Jovanovic } 14993c8869dcSZoran Jovanovic 15008a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 15018a80aa76SZoran Jovanovic unsigned Offset, 15028a80aa76SZoran Jovanovic uint64_t Address, 15038a80aa76SZoran Jovanovic const void *Decoder) { 1504d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<16>(Offset) * 2; 15058a80aa76SZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 15068a80aa76SZoran Jovanovic return MCDisassembler::Success; 15078a80aa76SZoran Jovanovic } 15088a80aa76SZoran Jovanovic 1509507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 1510507e084aSZoran Jovanovic unsigned Insn, 1511507e084aSZoran Jovanovic uint64_t Address, 1512507e084aSZoran Jovanovic const void *Decoder) { 1513507e084aSZoran Jovanovic unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1; 1514507e084aSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 1515507e084aSZoran Jovanovic return MCDisassembler::Success; 1516507e084aSZoran Jovanovic } 151771928e68SAkira Hatanaka 1518aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 1519aa2b9278SJozef Kolek unsigned Value, 1520aa2b9278SJozef Kolek uint64_t Address, 1521aa2b9278SJozef Kolek const void *Decoder) { 1522aa2b9278SJozef Kolek if (Value == 0) 1523aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(1)); 1524aa2b9278SJozef Kolek else if (Value == 0x7) 1525aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(-1)); 1526aa2b9278SJozef Kolek else 1527aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(Value << 2)); 1528aa2b9278SJozef Kolek return MCDisassembler::Success; 1529aa2b9278SJozef Kolek } 1530aa2b9278SJozef Kolek 1531aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, 1532aa2b9278SJozef Kolek unsigned Value, 1533aa2b9278SJozef Kolek uint64_t Address, 1534aa2b9278SJozef Kolek const void *Decoder) { 1535aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(Value << 2)); 1536aa2b9278SJozef Kolek return MCDisassembler::Success; 1537aa2b9278SJozef Kolek } 1538aa2b9278SJozef Kolek 1539aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst, 1540aa2b9278SJozef Kolek unsigned Value, 1541aa2b9278SJozef Kolek uint64_t Address, 1542aa2b9278SJozef Kolek const void *Decoder) { 1543aa2b9278SJozef Kolek if (Value == 0x7F) 1544aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(-1)); 1545aa2b9278SJozef Kolek else 1546aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(Value)); 1547aa2b9278SJozef Kolek return MCDisassembler::Success; 1548aa2b9278SJozef Kolek } 1549aa2b9278SJozef Kolek 1550aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst, 1551aa2b9278SJozef Kolek unsigned Value, 1552aa2b9278SJozef Kolek uint64_t Address, 1553aa2b9278SJozef Kolek const void *Decoder) { 1554aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(SignExtend32<4>(Value))); 1555aa2b9278SJozef Kolek return MCDisassembler::Success; 1556aa2b9278SJozef Kolek } 1557aa2b9278SJozef Kolek 155871928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 155971928e68SAkira Hatanaka unsigned Insn, 156071928e68SAkira Hatanaka uint64_t Address, 156171928e68SAkira Hatanaka const void *Decoder) { 156271928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); 156371928e68SAkira Hatanaka return MCDisassembler::Success; 156471928e68SAkira Hatanaka } 156571928e68SAkira Hatanaka 1566779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst, 1567779c5937SMatheus Almeida unsigned Insn, 1568779c5937SMatheus Almeida uint64_t Address, 1569779c5937SMatheus Almeida const void *Decoder) { 1570779c5937SMatheus Almeida // We add one to the immediate field as it was encoded as 'imm - 1'. 1571779c5937SMatheus Almeida Inst.addOperand(MCOperand::CreateImm(Insn + 1)); 1572779c5937SMatheus Almeida return MCDisassembler::Success; 1573779c5937SMatheus Almeida } 1574779c5937SMatheus Almeida 157571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 157671928e68SAkira Hatanaka unsigned Insn, 157771928e68SAkira Hatanaka uint64_t Address, 157871928e68SAkira Hatanaka const void *Decoder) { 157971928e68SAkira Hatanaka // First we need to grab the pos(lsb) from MCInst. 158071928e68SAkira Hatanaka int Pos = Inst.getOperand(2).getImm(); 158171928e68SAkira Hatanaka int Size = (int) Insn - Pos + 1; 158271928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 158371928e68SAkira Hatanaka return MCDisassembler::Success; 158471928e68SAkira Hatanaka } 158571928e68SAkira Hatanaka 158671928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 158771928e68SAkira Hatanaka unsigned Insn, 158871928e68SAkira Hatanaka uint64_t Address, 158971928e68SAkira Hatanaka const void *Decoder) { 159071928e68SAkira Hatanaka int Size = (int) Insn + 1; 159171928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 159271928e68SAkira Hatanaka return MCDisassembler::Success; 159371928e68SAkira Hatanaka } 1594b59e1a41SDaniel Sanders 1595b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 1596b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder) { 1597d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) * 4)); 1598b59e1a41SDaniel Sanders return MCDisassembler::Success; 1599b59e1a41SDaniel Sanders } 16002855142aSZoran Jovanovic 16012855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 16022855142aSZoran Jovanovic uint64_t Address, const void *Decoder) { 1603d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) * 8)); 16042855142aSZoran Jovanovic return MCDisassembler::Success; 16052855142aSZoran Jovanovic } 1606a4c4b5fcSZoran Jovanovic 1607b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 1608b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1609b682ddf3SVladimir Medic int32_t DecodedValue; 1610b682ddf3SVladimir Medic switch (Insn) { 1611b682ddf3SVladimir Medic case 0: DecodedValue = 256; break; 1612b682ddf3SVladimir Medic case 1: DecodedValue = 257; break; 1613b682ddf3SVladimir Medic case 510: DecodedValue = -258; break; 1614b682ddf3SVladimir Medic case 511: DecodedValue = -257; break; 1615b682ddf3SVladimir Medic default: DecodedValue = SignExtend32<9>(Insn); break; 1616b682ddf3SVladimir Medic } 1617b682ddf3SVladimir Medic Inst.addOperand(MCOperand::CreateImm(DecodedValue << 2)); 1618b682ddf3SVladimir Medic return MCDisassembler::Success; 1619b682ddf3SVladimir Medic } 1620b682ddf3SVladimir Medic 1621b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 1622b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1623b682ddf3SVladimir Medic // Insn must be >= 0, since it is unsigned that condition is always true. 1624b682ddf3SVladimir Medic assert(Insn < 16); 1625b682ddf3SVladimir Medic int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 1626b682ddf3SVladimir Medic 255, 32768, 65535}; 1627b682ddf3SVladimir Medic Inst.addOperand(MCOperand::CreateImm(DecodedValues[Insn])); 1628b682ddf3SVladimir Medic return MCDisassembler::Success; 1629b682ddf3SVladimir Medic } 1630b682ddf3SVladimir Medic 1631b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, 1632b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1633b682ddf3SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Insn << 2)); 1634b682ddf3SVladimir Medic return MCDisassembler::Success; 1635b682ddf3SVladimir Medic } 1636b682ddf3SVladimir Medic 1637a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, 1638a4c4b5fcSZoran Jovanovic unsigned Insn, 1639a4c4b5fcSZoran Jovanovic uint64_t Address, 1640a4c4b5fcSZoran Jovanovic const void *Decoder) { 1641a4c4b5fcSZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5, 1642a4c4b5fcSZoran Jovanovic Mips::S6, Mips::FP}; 1643a4c4b5fcSZoran Jovanovic unsigned RegNum; 1644a4c4b5fcSZoran Jovanovic 1645a4c4b5fcSZoran Jovanovic unsigned RegLst = fieldFromInstruction(Insn, 21, 5); 1646a4c4b5fcSZoran Jovanovic // Empty register lists are not allowed. 1647a4c4b5fcSZoran Jovanovic if (RegLst == 0) 1648a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 1649a4c4b5fcSZoran Jovanovic 1650a4c4b5fcSZoran Jovanovic RegNum = RegLst & 0xf; 1651a4c4b5fcSZoran Jovanovic for (unsigned i = 0; i < RegNum; i++) 1652a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Regs[i])); 1653a4c4b5fcSZoran Jovanovic 1654a4c4b5fcSZoran Jovanovic if (RegLst & 0x10) 1655a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Mips::RA)); 1656a4c4b5fcSZoran Jovanovic 1657a4c4b5fcSZoran Jovanovic return MCDisassembler::Success; 1658a4c4b5fcSZoran Jovanovic } 1659f9a02500SZoran Jovanovic 1660f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 1661f9a02500SZoran Jovanovic uint64_t Address, 1662f9a02500SZoran Jovanovic const void *Decoder) { 1663f9a02500SZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3}; 1664f9a02500SZoran Jovanovic unsigned RegNum; 1665f9a02500SZoran Jovanovic 1666f9a02500SZoran Jovanovic unsigned RegLst = fieldFromInstruction(Insn, 4, 2); 1667f9a02500SZoran Jovanovic // Empty register lists are not allowed. 1668f9a02500SZoran Jovanovic if (RegLst == 0) 1669f9a02500SZoran Jovanovic return MCDisassembler::Fail; 1670f9a02500SZoran Jovanovic 1671f9a02500SZoran Jovanovic RegNum = RegLst & 0x3; 1672f9a02500SZoran Jovanovic for (unsigned i = 0; i < RegNum - 1; i++) 1673f9a02500SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Regs[i])); 1674f9a02500SZoran Jovanovic 1675f9a02500SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Mips::RA)); 1676f9a02500SZoran Jovanovic 1677f9a02500SZoran Jovanovic return MCDisassembler::Success; 1678f9a02500SZoran Jovanovic } 1679