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 238*5cfebddeSJozef Kolek // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is 239*5cfebddeSJozef Kolek // shifted left by 1 bit. 240*5cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, 241*5cfebddeSJozef Kolek unsigned Offset, 242*5cfebddeSJozef Kolek uint64_t Address, 243*5cfebddeSJozef Kolek const void *Decoder); 244*5cfebddeSJozef Kolek 2458a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is 2468a80aa76SZoran Jovanovic // shifted left by 1 bit. 2478a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 2488a80aa76SZoran Jovanovic unsigned Offset, 2498a80aa76SZoran Jovanovic uint64_t Address, 2508a80aa76SZoran Jovanovic const void *Decoder); 2518a80aa76SZoran Jovanovic 252507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is 253507e084aSZoran Jovanovic // shifted left by 1 bit. 254507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 255507e084aSZoran Jovanovic unsigned Insn, 256507e084aSZoran Jovanovic uint64_t Address, 257507e084aSZoran Jovanovic const void *Decoder); 258507e084aSZoran Jovanovic 25971928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 26071928e68SAkira Hatanaka unsigned Insn, 26171928e68SAkira Hatanaka uint64_t Address, 26271928e68SAkira Hatanaka const void *Decoder); 26371928e68SAkira Hatanaka 26492db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 26592db6b78SDaniel Sanders unsigned Insn, 26692db6b78SDaniel Sanders uint64_t Address, 26792db6b78SDaniel Sanders const void *Decoder); 26892db6b78SDaniel Sanders 269ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst, 270ab6d1cceSJozef Kolek unsigned Insn, 271ab6d1cceSJozef Kolek uint64_t Address, 272ab6d1cceSJozef Kolek const void *Decoder); 273ab6d1cceSJozef Kolek 274b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 275b4484d62SDaniel Sanders unsigned Insn, 276b4484d62SDaniel Sanders uint64_t Address, 277b4484d62SDaniel Sanders const void *Decoder); 278b4484d62SDaniel Sanders 279fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 280fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder); 281fe0bf9f6SMatheus Almeida 282315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 283315e7ecaSJozef Kolek unsigned Insn, 284315e7ecaSJozef Kolek uint64_t Address, 285315e7ecaSJozef Kolek const void *Decoder); 286315e7ecaSJozef Kolek 28712c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, 28812c6982bSJozef Kolek unsigned Insn, 28912c6982bSJozef Kolek uint64_t Address, 29012c6982bSJozef Kolek const void *Decoder); 29112c6982bSJozef Kolek 292dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 293dde3d582SVladimir Medic unsigned Insn, 294dde3d582SVladimir Medic uint64_t Address, 295dde3d582SVladimir Medic const void *Decoder); 296dde3d582SVladimir Medic 297dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 298dde3d582SVladimir Medic unsigned Insn, 299dde3d582SVladimir Medic uint64_t Address, 300dde3d582SVladimir Medic const void *Decoder); 301dde3d582SVladimir Medic 30271928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 30371928e68SAkira Hatanaka uint64_t Address, 30471928e68SAkira Hatanaka const void *Decoder); 30571928e68SAkira Hatanaka 30692db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, 30792db6b78SDaniel Sanders uint64_t Address, 30892db6b78SDaniel Sanders const void *Decoder); 30992db6b78SDaniel Sanders 31092db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, 31192db6b78SDaniel Sanders uint64_t Address, 31292db6b78SDaniel Sanders const void *Decoder); 31392db6b78SDaniel Sanders 314435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn, 315435cf8a4SVladimir Medic uint64_t Address, 316435cf8a4SVladimir Medic const void *Decoder); 317435cf8a4SVladimir Medic 3186a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 3196a803f61SDaniel Sanders unsigned Insn, 3206a803f61SDaniel Sanders uint64_t Address, 3216a803f61SDaniel Sanders const void *Decoder); 3226a803f61SDaniel Sanders 323aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 324aa2b9278SJozef Kolek unsigned Value, 325aa2b9278SJozef Kolek uint64_t Address, 326aa2b9278SJozef Kolek const void *Decoder); 327aa2b9278SJozef Kolek 328aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, 329aa2b9278SJozef Kolek unsigned Value, 330aa2b9278SJozef Kolek uint64_t Address, 331aa2b9278SJozef Kolek const void *Decoder); 332aa2b9278SJozef Kolek 333aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst, 334aa2b9278SJozef Kolek unsigned Value, 335aa2b9278SJozef Kolek uint64_t Address, 336aa2b9278SJozef Kolek const void *Decoder); 337aa2b9278SJozef Kolek 338aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst, 339aa2b9278SJozef Kolek unsigned Value, 340aa2b9278SJozef Kolek uint64_t Address, 341aa2b9278SJozef Kolek const void *Decoder); 342aa2b9278SJozef Kolek 34371928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 34471928e68SAkira Hatanaka unsigned Insn, 34571928e68SAkira Hatanaka uint64_t Address, 34671928e68SAkira Hatanaka const void *Decoder); 34771928e68SAkira Hatanaka 348779c5937SMatheus Almeida // Decode the immediate field of an LSA instruction which 349779c5937SMatheus Almeida // is off by one. 350779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst, 351779c5937SMatheus Almeida unsigned Insn, 352779c5937SMatheus Almeida uint64_t Address, 353779c5937SMatheus Almeida const void *Decoder); 354779c5937SMatheus Almeida 35571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 35671928e68SAkira Hatanaka unsigned Insn, 35771928e68SAkira Hatanaka uint64_t Address, 35871928e68SAkira Hatanaka const void *Decoder); 35971928e68SAkira Hatanaka 36071928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 36171928e68SAkira Hatanaka unsigned Insn, 36271928e68SAkira Hatanaka uint64_t Address, 36371928e68SAkira Hatanaka const void *Decoder); 36471928e68SAkira Hatanaka 365b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 366b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder); 367b59e1a41SDaniel Sanders 3682855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 3692855142aSZoran Jovanovic uint64_t Address, const void *Decoder); 3702855142aSZoran Jovanovic 371b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 372b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 373b682ddf3SVladimir Medic 374b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 375b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 376b682ddf3SVladimir Medic 377b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, 378b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 379b682ddf3SVladimir Medic 3802c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, 3812c6d7320SJozef Kolek uint64_t Address, const void *Decoder); 3822c6d7320SJozef Kolek 383b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't 384b50ccf8eSDaniel Sanders /// handle. 385b50ccf8eSDaniel Sanders template <typename InsnType> 386b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 387b50ccf8eSDaniel Sanders const void *Decoder); 3885c582b2fSDaniel Sanders 3895c582b2fSDaniel Sanders template <typename InsnType> 3905c582b2fSDaniel Sanders static DecodeStatus 3915c582b2fSDaniel Sanders DecodeAddiGroupBranch(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 DecodeDaddiGroupBranch(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 DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4025c582b2fSDaniel Sanders const void *Decoder); 4035c582b2fSDaniel Sanders 4045c582b2fSDaniel Sanders template <typename InsnType> 4055c582b2fSDaniel Sanders static DecodeStatus 4065c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4075c582b2fSDaniel Sanders const void *Decoder); 4085c582b2fSDaniel Sanders 4095c582b2fSDaniel Sanders template <typename InsnType> 4105c582b2fSDaniel Sanders static DecodeStatus 4115c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4125c582b2fSDaniel Sanders const void *Decoder); 4135c582b2fSDaniel Sanders 41428a0ca07SZoran Jovanovic template <typename InsnType> 41528a0ca07SZoran Jovanovic static DecodeStatus 41628a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 41728a0ca07SZoran Jovanovic const void *Decoder); 41828a0ca07SZoran Jovanovic 419a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn, 420a4c4b5fcSZoran Jovanovic uint64_t Address, 421a4c4b5fcSZoran Jovanovic const void *Decoder); 422a4c4b5fcSZoran Jovanovic 423f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 424f9a02500SZoran Jovanovic uint64_t Address, 425f9a02500SZoran Jovanovic const void *Decoder); 426f9a02500SZoran Jovanovic 42771928e68SAkira Hatanaka namespace llvm { 42871928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target, 42971928e68SAkira Hatanaka TheMips64elTarget; 43071928e68SAkira Hatanaka } 43171928e68SAkira Hatanaka 43271928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler( 43371928e68SAkira Hatanaka const Target &T, 434a1bc0f56SLang Hames const MCSubtargetInfo &STI, 435a1bc0f56SLang Hames MCContext &Ctx) { 436a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, true); 43771928e68SAkira Hatanaka } 43871928e68SAkira Hatanaka 43971928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler( 44071928e68SAkira Hatanaka const Target &T, 441a1bc0f56SLang Hames const MCSubtargetInfo &STI, 442a1bc0f56SLang Hames MCContext &Ctx) { 443a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, false); 44471928e68SAkira Hatanaka } 44571928e68SAkira Hatanaka 44671928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler( 44771928e68SAkira Hatanaka const Target &T, 448a1bc0f56SLang Hames const MCSubtargetInfo &STI, 449a1bc0f56SLang Hames MCContext &Ctx) { 450a1bc0f56SLang Hames return new Mips64Disassembler(STI, Ctx, true); 45171928e68SAkira Hatanaka } 45271928e68SAkira Hatanaka 45371928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler( 45471928e68SAkira Hatanaka const Target &T, 455a1bc0f56SLang Hames const MCSubtargetInfo &STI, 456a1bc0f56SLang Hames MCContext &Ctx) { 457a1bc0f56SLang Hames return new Mips64Disassembler(STI, Ctx, false); 45871928e68SAkira Hatanaka } 45971928e68SAkira Hatanaka 46071928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() { 46171928e68SAkira Hatanaka // Register the disassembler. 46271928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipsTarget, 46371928e68SAkira Hatanaka createMipsDisassembler); 46471928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMipselTarget, 46571928e68SAkira Hatanaka createMipselDisassembler); 46671928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64Target, 46771928e68SAkira Hatanaka createMips64Disassembler); 46871928e68SAkira Hatanaka TargetRegistry::RegisterMCDisassembler(TheMips64elTarget, 46971928e68SAkira Hatanaka createMips64elDisassembler); 47071928e68SAkira Hatanaka } 47171928e68SAkira Hatanaka 47271928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc" 47371928e68SAkira Hatanaka 4745c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 4755c582b2fSDaniel Sanders const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D); 4765c582b2fSDaniel Sanders const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo(); 4775c582b2fSDaniel Sanders return *(RegInfo->getRegClass(RC).begin() + RegNo); 4785c582b2fSDaniel Sanders } 4795c582b2fSDaniel Sanders 480b50ccf8eSDaniel Sanders template <typename InsnType> 481b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 482b50ccf8eSDaniel Sanders const void *Decoder) { 483b50ccf8eSDaniel Sanders typedef DecodeStatus (*DecodeFN)(MCInst &, unsigned, uint64_t, const void *); 484b50ccf8eSDaniel Sanders // The size of the n field depends on the element size 485b50ccf8eSDaniel Sanders // The register class also depends on this. 486b50ccf8eSDaniel Sanders InsnType tmp = fieldFromInstruction(insn, 17, 5); 487b50ccf8eSDaniel Sanders unsigned NSize = 0; 488b50ccf8eSDaniel Sanders DecodeFN RegDecoder = nullptr; 489b50ccf8eSDaniel Sanders if ((tmp & 0x18) == 0x00) { // INSVE_B 490b50ccf8eSDaniel Sanders NSize = 4; 491b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128BRegisterClass; 492b50ccf8eSDaniel Sanders } else if ((tmp & 0x1c) == 0x10) { // INSVE_H 493b50ccf8eSDaniel Sanders NSize = 3; 494b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128HRegisterClass; 495b50ccf8eSDaniel Sanders } else if ((tmp & 0x1e) == 0x18) { // INSVE_W 496b50ccf8eSDaniel Sanders NSize = 2; 497b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128WRegisterClass; 498b50ccf8eSDaniel Sanders } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D 499b50ccf8eSDaniel Sanders NSize = 1; 500b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128DRegisterClass; 501b50ccf8eSDaniel Sanders } else 502b50ccf8eSDaniel Sanders llvm_unreachable("Invalid encoding"); 503b50ccf8eSDaniel Sanders 504b50ccf8eSDaniel Sanders assert(NSize != 0 && RegDecoder != nullptr); 505b50ccf8eSDaniel Sanders 506b50ccf8eSDaniel Sanders // $wd 507b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 6, 5); 508b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 509b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 510b50ccf8eSDaniel Sanders // $wd_in 511b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 512b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 513b50ccf8eSDaniel Sanders // $n 514b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 16, NSize); 515b50ccf8eSDaniel Sanders MI.addOperand(MCOperand::CreateImm(tmp)); 516b50ccf8eSDaniel Sanders // $ws 517b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 11, 5); 518b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 519b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 520b50ccf8eSDaniel Sanders // $n2 521b50ccf8eSDaniel Sanders MI.addOperand(MCOperand::CreateImm(0)); 522b50ccf8eSDaniel Sanders 523b50ccf8eSDaniel Sanders return MCDisassembler::Success; 524b50ccf8eSDaniel Sanders } 525b50ccf8eSDaniel Sanders 5265c582b2fSDaniel Sanders template <typename InsnType> 5275c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, 5285c582b2fSDaniel Sanders uint64_t Address, 5295c582b2fSDaniel Sanders const void *Decoder) { 5305c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5315c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 5325c582b2fSDaniel Sanders // ISA's instead). 5335c582b2fSDaniel Sanders // 5345c582b2fSDaniel Sanders // We have: 5355c582b2fSDaniel Sanders // 0b001000 sssss ttttt iiiiiiiiiiiiiiii 5365c582b2fSDaniel Sanders // BOVC if rs >= rt 5375c582b2fSDaniel Sanders // BEQZALC if rs == 0 && rt != 0 5385c582b2fSDaniel Sanders // BEQC if rs < rt && rs != 0 5395c582b2fSDaniel Sanders 5405c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 5415c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 542d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 5435c582b2fSDaniel Sanders bool HasRs = false; 5445c582b2fSDaniel Sanders 5455c582b2fSDaniel Sanders if (Rs >= Rt) { 5465c582b2fSDaniel Sanders MI.setOpcode(Mips::BOVC); 5475c582b2fSDaniel Sanders HasRs = true; 5485c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 5495c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQC); 5505c582b2fSDaniel Sanders HasRs = true; 5515c582b2fSDaniel Sanders } else 5525c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQZALC); 5535c582b2fSDaniel Sanders 5545c582b2fSDaniel Sanders if (HasRs) 5555c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5565c582b2fSDaniel Sanders Rs))); 5575c582b2fSDaniel Sanders 5585c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5595c582b2fSDaniel Sanders Rt))); 5605c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 5615c582b2fSDaniel Sanders 5625c582b2fSDaniel Sanders return MCDisassembler::Success; 5635c582b2fSDaniel Sanders } 5645c582b2fSDaniel Sanders 5655c582b2fSDaniel Sanders template <typename InsnType> 5665c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, 5675c582b2fSDaniel Sanders uint64_t Address, 5685c582b2fSDaniel Sanders const void *Decoder) { 5695c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 5705c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 5715c582b2fSDaniel Sanders // ISA's instead). 5725c582b2fSDaniel Sanders // 5735c582b2fSDaniel Sanders // We have: 5745c582b2fSDaniel Sanders // 0b011000 sssss ttttt iiiiiiiiiiiiiiii 5755c582b2fSDaniel Sanders // BNVC if rs >= rt 5765c582b2fSDaniel Sanders // BNEZALC if rs == 0 && rt != 0 5775c582b2fSDaniel Sanders // BNEC if rs < rt && rs != 0 5785c582b2fSDaniel Sanders 5795c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 5805c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 581d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 5825c582b2fSDaniel Sanders bool HasRs = false; 5835c582b2fSDaniel Sanders 5845c582b2fSDaniel Sanders if (Rs >= Rt) { 5855c582b2fSDaniel Sanders MI.setOpcode(Mips::BNVC); 5865c582b2fSDaniel Sanders HasRs = true; 5875c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 5885c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEC); 5895c582b2fSDaniel Sanders HasRs = true; 5905c582b2fSDaniel Sanders } else 5915c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEZALC); 5925c582b2fSDaniel Sanders 5935c582b2fSDaniel Sanders if (HasRs) 5945c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5955c582b2fSDaniel Sanders Rs))); 5965c582b2fSDaniel Sanders 5975c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 5985c582b2fSDaniel Sanders Rt))); 5995c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 6005c582b2fSDaniel Sanders 6015c582b2fSDaniel Sanders return MCDisassembler::Success; 6025c582b2fSDaniel Sanders } 6035c582b2fSDaniel Sanders 6045c582b2fSDaniel Sanders template <typename InsnType> 6055c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, 6065c582b2fSDaniel Sanders uint64_t Address, 6075c582b2fSDaniel Sanders const void *Decoder) { 6085c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6095c582b2fSDaniel Sanders // (otherwise we would have matched the BLEZL instruction from the earlier 6105c582b2fSDaniel Sanders // ISA's instead). 6115c582b2fSDaniel Sanders // 6125c582b2fSDaniel Sanders // We have: 6135c582b2fSDaniel Sanders // 0b010110 sssss ttttt iiiiiiiiiiiiiiii 6145c582b2fSDaniel Sanders // Invalid if rs == 0 6155c582b2fSDaniel Sanders // BLEZC if rs == 0 && rt != 0 6165c582b2fSDaniel Sanders // BGEZC if rs == rt && rt != 0 6175c582b2fSDaniel Sanders // BGEC if rs != rt && rs != 0 && rt != 0 6185c582b2fSDaniel Sanders 6195c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6205c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 621d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 62228a0ca07SZoran Jovanovic bool HasRs = false; 6235c582b2fSDaniel Sanders 6245c582b2fSDaniel Sanders if (Rt == 0) 6255c582b2fSDaniel Sanders return MCDisassembler::Fail; 6265c582b2fSDaniel Sanders else if (Rs == 0) 6275c582b2fSDaniel Sanders MI.setOpcode(Mips::BLEZC); 6285c582b2fSDaniel Sanders else if (Rs == Rt) 6295c582b2fSDaniel Sanders MI.setOpcode(Mips::BGEZC); 63028a0ca07SZoran Jovanovic else { 63128a0ca07SZoran Jovanovic HasRs = true; 63228a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEC); 63328a0ca07SZoran Jovanovic } 63428a0ca07SZoran Jovanovic 63528a0ca07SZoran Jovanovic if (HasRs) 63628a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 63728a0ca07SZoran Jovanovic Rs))); 6385c582b2fSDaniel Sanders 6395c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6405c582b2fSDaniel Sanders Rt))); 6415c582b2fSDaniel Sanders 6425c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 6435c582b2fSDaniel Sanders 6445c582b2fSDaniel Sanders return MCDisassembler::Success; 6455c582b2fSDaniel Sanders } 6465c582b2fSDaniel Sanders 6475c582b2fSDaniel Sanders template <typename InsnType> 6485c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, 6495c582b2fSDaniel Sanders uint64_t Address, 6505c582b2fSDaniel Sanders const void *Decoder) { 6515c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6525c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZL instruction from the earlier 6535c582b2fSDaniel Sanders // ISA's instead). 6545c582b2fSDaniel Sanders // 6555c582b2fSDaniel Sanders // We have: 6565c582b2fSDaniel Sanders // 0b010111 sssss ttttt iiiiiiiiiiiiiiii 6575c582b2fSDaniel Sanders // Invalid if rs == 0 6585c582b2fSDaniel Sanders // BGTZC if rs == 0 && rt != 0 6595c582b2fSDaniel Sanders // BLTZC if rs == rt && rt != 0 6605c582b2fSDaniel Sanders // BLTC if rs != rt && rs != 0 && rt != 0 6615c582b2fSDaniel Sanders 6625c14b069SZoran Jovanovic bool HasRs = false; 6635c14b069SZoran Jovanovic 6645c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6655c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 666d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 6675c582b2fSDaniel Sanders 6685c582b2fSDaniel Sanders if (Rt == 0) 6695c582b2fSDaniel Sanders return MCDisassembler::Fail; 6705c582b2fSDaniel Sanders else if (Rs == 0) 6715c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZC); 6725c582b2fSDaniel Sanders else if (Rs == Rt) 6735c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZC); 6745c14b069SZoran Jovanovic else { 6755c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTC); 6765c14b069SZoran Jovanovic HasRs = true; 6775c14b069SZoran Jovanovic } 6785c14b069SZoran Jovanovic 6795c14b069SZoran Jovanovic if (HasRs) 6805c14b069SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6815c14b069SZoran Jovanovic Rs))); 6825c582b2fSDaniel Sanders 6835c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 6845c582b2fSDaniel Sanders Rt))); 6855c582b2fSDaniel Sanders 6865c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 6875c582b2fSDaniel Sanders 6885c582b2fSDaniel Sanders return MCDisassembler::Success; 6895c582b2fSDaniel Sanders } 6905c582b2fSDaniel Sanders 6915c582b2fSDaniel Sanders template <typename InsnType> 6925c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, 6935c582b2fSDaniel Sanders uint64_t Address, 6945c582b2fSDaniel Sanders const void *Decoder) { 6955c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6965c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZ instruction from the earlier 6975c582b2fSDaniel Sanders // ISA's instead). 6985c582b2fSDaniel Sanders // 6995c582b2fSDaniel Sanders // We have: 7005c582b2fSDaniel Sanders // 0b000111 sssss ttttt iiiiiiiiiiiiiiii 7015c582b2fSDaniel Sanders // BGTZ if rt == 0 7025c582b2fSDaniel Sanders // BGTZALC if rs == 0 && rt != 0 7035c582b2fSDaniel Sanders // BLTZALC if rs != 0 && rs == rt 7045c582b2fSDaniel Sanders // BLTUC if rs != 0 && rs != rt 7055c582b2fSDaniel Sanders 7065c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 7075c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 708d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 7095c582b2fSDaniel Sanders bool HasRs = false; 7105c582b2fSDaniel Sanders bool HasRt = false; 7115c582b2fSDaniel Sanders 7125c582b2fSDaniel Sanders if (Rt == 0) { 7135c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZ); 7145c582b2fSDaniel Sanders HasRs = true; 7155c582b2fSDaniel Sanders } else if (Rs == 0) { 7165c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZALC); 7175c582b2fSDaniel Sanders HasRt = true; 7185c582b2fSDaniel Sanders } else if (Rs == Rt) { 7195c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZALC); 7205c582b2fSDaniel Sanders HasRs = true; 7215c14b069SZoran Jovanovic } else { 7225c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTUC); 7235c14b069SZoran Jovanovic HasRs = true; 7245c14b069SZoran Jovanovic HasRt = true; 7255c14b069SZoran Jovanovic } 7265c582b2fSDaniel Sanders 7275c582b2fSDaniel Sanders if (HasRs) 7285c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 7295c582b2fSDaniel Sanders Rs))); 7305c582b2fSDaniel Sanders 7315c582b2fSDaniel Sanders if (HasRt) 7325c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 7335c582b2fSDaniel Sanders Rt))); 7345c582b2fSDaniel Sanders 7355c582b2fSDaniel Sanders MI.addOperand(MCOperand::CreateImm(Imm)); 7365c582b2fSDaniel Sanders 7375c582b2fSDaniel Sanders return MCDisassembler::Success; 7385c582b2fSDaniel Sanders } 7395c582b2fSDaniel Sanders 74028a0ca07SZoran Jovanovic template <typename InsnType> 74128a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn, 74228a0ca07SZoran Jovanovic uint64_t Address, 74328a0ca07SZoran Jovanovic const void *Decoder) { 74428a0ca07SZoran Jovanovic // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 74528a0ca07SZoran Jovanovic // (otherwise we would have matched the BLEZL instruction from the earlier 74628a0ca07SZoran Jovanovic // ISA's instead). 74728a0ca07SZoran Jovanovic // 74828a0ca07SZoran Jovanovic // We have: 74928a0ca07SZoran Jovanovic // 0b000110 sssss ttttt iiiiiiiiiiiiiiii 75028a0ca07SZoran Jovanovic // Invalid if rs == 0 75128a0ca07SZoran Jovanovic // BLEZALC if rs == 0 && rt != 0 75228a0ca07SZoran Jovanovic // BGEZALC if rs == rt && rt != 0 75328a0ca07SZoran Jovanovic // BGEUC if rs != rt && rs != 0 && rt != 0 75428a0ca07SZoran Jovanovic 75528a0ca07SZoran Jovanovic InsnType Rs = fieldFromInstruction(insn, 21, 5); 75628a0ca07SZoran Jovanovic InsnType Rt = fieldFromInstruction(insn, 16, 5); 757d37bab61SAlexey Samsonov InsnType Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; 75828a0ca07SZoran Jovanovic bool HasRs = false; 75928a0ca07SZoran Jovanovic 76028a0ca07SZoran Jovanovic if (Rt == 0) 76128a0ca07SZoran Jovanovic return MCDisassembler::Fail; 76228a0ca07SZoran Jovanovic else if (Rs == 0) 76328a0ca07SZoran Jovanovic MI.setOpcode(Mips::BLEZALC); 76428a0ca07SZoran Jovanovic else if (Rs == Rt) 76528a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEZALC); 76628a0ca07SZoran Jovanovic else { 76728a0ca07SZoran Jovanovic HasRs = true; 76828a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEUC); 76928a0ca07SZoran Jovanovic } 77028a0ca07SZoran Jovanovic 77128a0ca07SZoran Jovanovic if (HasRs) 77228a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 77328a0ca07SZoran Jovanovic Rs))); 77428a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateReg(getReg(Decoder, Mips::GPR32RegClassID, 77528a0ca07SZoran Jovanovic Rt))); 77628a0ca07SZoran Jovanovic 77728a0ca07SZoran Jovanovic MI.addOperand(MCOperand::CreateImm(Imm)); 77828a0ca07SZoran Jovanovic 77928a0ca07SZoran Jovanovic return MCDisassembler::Success; 78028a0ca07SZoran Jovanovic } 78128a0ca07SZoran Jovanovic 782ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted 783ea22c4cfSJozef Kolek /// according to the given endianess. 784ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 785ea22c4cfSJozef Kolek uint64_t &Size, uint32_t &Insn, 786ea22c4cfSJozef Kolek bool IsBigEndian) { 787ea22c4cfSJozef Kolek // We want to read exactly 2 Bytes of data. 788ea22c4cfSJozef Kolek if (Bytes.size() < 2) { 789ea22c4cfSJozef Kolek Size = 0; 790ea22c4cfSJozef Kolek return MCDisassembler::Fail; 791ea22c4cfSJozef Kolek } 792ea22c4cfSJozef Kolek 793ea22c4cfSJozef Kolek if (IsBigEndian) { 794ea22c4cfSJozef Kolek Insn = (Bytes[0] << 8) | Bytes[1]; 795ea22c4cfSJozef Kolek } else { 796ea22c4cfSJozef Kolek Insn = (Bytes[1] << 8) | Bytes[0]; 797ea22c4cfSJozef Kolek } 798ea22c4cfSJozef Kolek 799ea22c4cfSJozef Kolek return MCDisassembler::Success; 800ea22c4cfSJozef Kolek } 801ea22c4cfSJozef Kolek 8027fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted 8034aa6bea7SRafael Espindola /// according to the given endianess 8047fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 8057fc5b874SRafael Espindola uint64_t &Size, uint32_t &Insn, 8067fc5b874SRafael Espindola bool IsBigEndian, bool IsMicroMips) { 80771928e68SAkira Hatanaka // We want to read exactly 4 Bytes of data. 8087fc5b874SRafael Espindola if (Bytes.size() < 4) { 8094aa6bea7SRafael Espindola Size = 0; 81071928e68SAkira Hatanaka return MCDisassembler::Fail; 81171928e68SAkira Hatanaka } 81271928e68SAkira Hatanaka 813ea22c4cfSJozef Kolek // High 16 bits of a 32-bit microMIPS instruction (where the opcode is) 814ea22c4cfSJozef Kolek // always precede the low 16 bits in the instruction stream (that is, they 815ea22c4cfSJozef Kolek // are placed at lower addresses in the instruction stream). 816ea22c4cfSJozef Kolek // 817ea22c4cfSJozef Kolek // microMIPS byte ordering: 818ea22c4cfSJozef Kolek // Big-endian: 0 | 1 | 2 | 3 819ea22c4cfSJozef Kolek // Little-endian: 1 | 0 | 3 | 2 820ea22c4cfSJozef Kolek 8214aa6bea7SRafael Espindola if (IsBigEndian) { 82271928e68SAkira Hatanaka // Encoded as a big-endian 32-bit word in the stream. 8234aa6bea7SRafael Espindola Insn = 8244aa6bea7SRafael Espindola (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24); 8254aa6bea7SRafael Espindola } else { 826dde3d582SVladimir Medic if (IsMicroMips) { 8274aa6bea7SRafael Espindola Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) | 828dde3d582SVladimir Medic (Bytes[1] << 24); 829dde3d582SVladimir Medic } else { 8304aa6bea7SRafael Espindola Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | 83171928e68SAkira Hatanaka (Bytes[3] << 24); 83271928e68SAkira Hatanaka } 833dde3d582SVladimir Medic } 83471928e68SAkira Hatanaka 83571928e68SAkira Hatanaka return MCDisassembler::Success; 83671928e68SAkira Hatanaka } 83771928e68SAkira Hatanaka 8384aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 8397fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 84071928e68SAkira Hatanaka uint64_t Address, 8414aa6bea7SRafael Espindola raw_ostream &VStream, 8424aa6bea7SRafael Espindola raw_ostream &CStream) const { 84371928e68SAkira Hatanaka uint32_t Insn; 844ea22c4cfSJozef Kolek DecodeStatus Result; 84571928e68SAkira Hatanaka 846ea22c4cfSJozef Kolek if (IsMicroMips) { 847ea22c4cfSJozef Kolek Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); 848ea22c4cfSJozef Kolek 849ea22c4cfSJozef Kolek DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n"); 850ea22c4cfSJozef Kolek // Calling the auto-generated decoder function. 851ea22c4cfSJozef Kolek Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address, 852ea22c4cfSJozef Kolek this, STI); 853ea22c4cfSJozef Kolek if (Result != MCDisassembler::Fail) { 854ea22c4cfSJozef Kolek Size = 2; 855ea22c4cfSJozef Kolek return Result; 856ea22c4cfSJozef Kolek } 857ea22c4cfSJozef Kolek 858ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true); 85971928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 86071928e68SAkira Hatanaka return MCDisassembler::Fail; 86171928e68SAkira Hatanaka 862ea22c4cfSJozef Kolek DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); 863dde3d582SVladimir Medic // Calling the auto-generated decoder function. 8644aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, 865dde3d582SVladimir Medic this, STI); 866dde3d582SVladimir Medic if (Result != MCDisassembler::Fail) { 867dde3d582SVladimir Medic Size = 4; 868dde3d582SVladimir Medic return Result; 869dde3d582SVladimir Medic } 870dde3d582SVladimir Medic return MCDisassembler::Fail; 871dde3d582SVladimir Medic } 872dde3d582SVladimir Medic 873ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); 874ea22c4cfSJozef Kolek if (Result == MCDisassembler::Fail) 875ea22c4cfSJozef Kolek return MCDisassembler::Fail; 876ea22c4cfSJozef Kolek 877c171f65aSDaniel Sanders if (hasCOP3()) { 878c171f65aSDaniel Sanders DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n"); 879c171f65aSDaniel Sanders Result = 8804aa6bea7SRafael Espindola decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI); 881c171f65aSDaniel Sanders if (Result != MCDisassembler::Fail) { 882c171f65aSDaniel Sanders Size = 4; 883c171f65aSDaniel Sanders return Result; 884c171f65aSDaniel Sanders } 885c171f65aSDaniel Sanders } 886c171f65aSDaniel Sanders 887c171f65aSDaniel Sanders if (hasMips32r6() && isGP64()) { 8880fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n"); 8894aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn, 8900fa60416SDaniel Sanders Address, this, STI); 8910fa60416SDaniel Sanders if (Result != MCDisassembler::Fail) { 8920fa60416SDaniel Sanders Size = 4; 8930fa60416SDaniel Sanders return Result; 8940fa60416SDaniel Sanders } 8950fa60416SDaniel Sanders } 8960fa60416SDaniel Sanders 897c171f65aSDaniel Sanders if (hasMips32r6()) { 8980fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n"); 8994aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn, 9005c582b2fSDaniel Sanders Address, this, STI); 9015c582b2fSDaniel Sanders if (Result != MCDisassembler::Fail) { 9025c582b2fSDaniel Sanders Size = 4; 9035c582b2fSDaniel Sanders return Result; 9045c582b2fSDaniel Sanders } 9055c582b2fSDaniel Sanders } 9065c582b2fSDaniel Sanders 9070fa60416SDaniel Sanders DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n"); 90871928e68SAkira Hatanaka // Calling the auto-generated decoder function. 9094aa6bea7SRafael Espindola Result = 9104aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI); 91171928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 91271928e68SAkira Hatanaka Size = 4; 91371928e68SAkira Hatanaka return Result; 91471928e68SAkira Hatanaka } 91571928e68SAkira Hatanaka 91671928e68SAkira Hatanaka return MCDisassembler::Fail; 91771928e68SAkira Hatanaka } 91871928e68SAkira Hatanaka 9194aa6bea7SRafael Espindola DecodeStatus Mips64Disassembler::getInstruction(MCInst &Instr, uint64_t &Size, 9207fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 92171928e68SAkira Hatanaka uint64_t Address, 9224aa6bea7SRafael Espindola raw_ostream &VStream, 9234aa6bea7SRafael Espindola raw_ostream &CStream) const { 92471928e68SAkira Hatanaka uint32_t Insn; 92571928e68SAkira Hatanaka 9264aa6bea7SRafael Espindola DecodeStatus Result = 9277fc5b874SRafael Espindola readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); 92871928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 92971928e68SAkira Hatanaka return MCDisassembler::Fail; 93071928e68SAkira Hatanaka 93171928e68SAkira Hatanaka // Calling the auto-generated decoder function. 9324aa6bea7SRafael Espindola Result = 9334aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips6432, Instr, Insn, Address, this, STI); 93471928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 93571928e68SAkira Hatanaka Size = 4; 93671928e68SAkira Hatanaka return Result; 93771928e68SAkira Hatanaka } 93871928e68SAkira Hatanaka // If we fail to decode in Mips64 decoder space we can try in Mips32 9394aa6bea7SRafael Espindola Result = 9404aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI); 94171928e68SAkira Hatanaka if (Result != MCDisassembler::Fail) { 94271928e68SAkira Hatanaka Size = 4; 94371928e68SAkira Hatanaka return Result; 94471928e68SAkira Hatanaka } 94571928e68SAkira Hatanaka 94671928e68SAkira Hatanaka return MCDisassembler::Fail; 94771928e68SAkira Hatanaka } 94871928e68SAkira Hatanaka 949ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 950ec8a5490SReed Kotler unsigned RegNo, 951ec8a5490SReed Kotler uint64_t Address, 952ec8a5490SReed Kotler const void *Decoder) { 953ec8a5490SReed Kotler 954ec8a5490SReed Kotler return MCDisassembler::Fail; 955ec8a5490SReed Kotler 956ec8a5490SReed Kotler } 957ec8a5490SReed Kotler 95813e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 95971928e68SAkira Hatanaka unsigned RegNo, 96071928e68SAkira Hatanaka uint64_t Address, 96171928e68SAkira Hatanaka const void *Decoder) { 96271928e68SAkira Hatanaka 96371928e68SAkira Hatanaka if (RegNo > 31) 96471928e68SAkira Hatanaka return MCDisassembler::Fail; 96571928e68SAkira Hatanaka 96613e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); 9679bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 96871928e68SAkira Hatanaka return MCDisassembler::Success; 96971928e68SAkira Hatanaka } 97071928e68SAkira Hatanaka 971b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, 972b0852e54SZoran Jovanovic unsigned RegNo, 973b0852e54SZoran Jovanovic uint64_t Address, 974b0852e54SZoran Jovanovic const void *Decoder) { 975ea22c4cfSJozef Kolek if (RegNo > 7) 976b0852e54SZoran Jovanovic return MCDisassembler::Fail; 977ea22c4cfSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo); 978ea22c4cfSJozef Kolek Inst.addOperand(MCOperand::CreateReg(Reg)); 979ea22c4cfSJozef Kolek return MCDisassembler::Success; 980b0852e54SZoran Jovanovic } 981b0852e54SZoran Jovanovic 9821904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, 9831904fa21SJozef Kolek unsigned RegNo, 9841904fa21SJozef Kolek uint64_t Address, 9851904fa21SJozef Kolek const void *Decoder) { 986315e7ecaSJozef Kolek if (RegNo > 7) 9871904fa21SJozef Kolek return MCDisassembler::Fail; 988315e7ecaSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo); 989315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateReg(Reg)); 990315e7ecaSJozef Kolek return MCDisassembler::Success; 9911904fa21SJozef Kolek } 9921904fa21SJozef Kolek 99313e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 99471928e68SAkira Hatanaka unsigned RegNo, 99571928e68SAkira Hatanaka uint64_t Address, 99671928e68SAkira Hatanaka const void *Decoder) { 99771928e68SAkira Hatanaka if (RegNo > 31) 99871928e68SAkira Hatanaka return MCDisassembler::Fail; 99913e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); 10009bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 100171928e68SAkira Hatanaka return MCDisassembler::Success; 100271928e68SAkira Hatanaka } 100371928e68SAkira Hatanaka 10049bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 10059bfa2e2eSAkira Hatanaka unsigned RegNo, 10069bfa2e2eSAkira Hatanaka uint64_t Address, 10079bfa2e2eSAkira Hatanaka const void *Decoder) { 1008e8860938SVladimir Medic if (static_cast<const MipsDisassembler *>(Decoder)->isGP64Bit()) 10099bfa2e2eSAkira Hatanaka return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); 10109bfa2e2eSAkira Hatanaka 10119bfa2e2eSAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 10129bfa2e2eSAkira Hatanaka } 10139bfa2e2eSAkira Hatanaka 1014654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 1015ecabd1a5SAkira Hatanaka unsigned RegNo, 1016ecabd1a5SAkira Hatanaka uint64_t Address, 1017ecabd1a5SAkira Hatanaka const void *Decoder) { 101813e6ccf3SAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 1019ecabd1a5SAkira Hatanaka } 1020ecabd1a5SAkira Hatanaka 102171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 102271928e68SAkira Hatanaka unsigned RegNo, 102371928e68SAkira Hatanaka uint64_t Address, 102471928e68SAkira Hatanaka const void *Decoder) { 102571928e68SAkira Hatanaka if (RegNo > 31) 102671928e68SAkira Hatanaka return MCDisassembler::Fail; 102771928e68SAkira Hatanaka 10289bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 10299bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 103071928e68SAkira Hatanaka return MCDisassembler::Success; 103171928e68SAkira Hatanaka } 103271928e68SAkira Hatanaka 103371928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 103471928e68SAkira Hatanaka unsigned RegNo, 103571928e68SAkira Hatanaka uint64_t Address, 103671928e68SAkira Hatanaka const void *Decoder) { 103771928e68SAkira Hatanaka if (RegNo > 31) 103871928e68SAkira Hatanaka return MCDisassembler::Fail; 103971928e68SAkira Hatanaka 10409bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 10419bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 104271928e68SAkira Hatanaka return MCDisassembler::Success; 104371928e68SAkira Hatanaka } 104471928e68SAkira Hatanaka 104571928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 104671928e68SAkira Hatanaka unsigned RegNo, 104771928e68SAkira Hatanaka uint64_t Address, 104871928e68SAkira Hatanaka const void *Decoder) { 1049253777fdSChad Rosier if (RegNo > 31) 1050253777fdSChad Rosier return MCDisassembler::Fail; 1051253777fdSChad Rosier unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); 1052253777fdSChad Rosier Inst.addOperand(MCOperand::CreateReg(Reg)); 105371928e68SAkira Hatanaka return MCDisassembler::Success; 105471928e68SAkira Hatanaka } 105571928e68SAkira Hatanaka 10561fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 10571fb1b8b8SAkira Hatanaka unsigned RegNo, 10581fb1b8b8SAkira Hatanaka uint64_t Address, 10591fb1b8b8SAkira Hatanaka const void *Decoder) { 10601fb1b8b8SAkira Hatanaka if (RegNo > 7) 10611fb1b8b8SAkira Hatanaka return MCDisassembler::Fail; 10621fb1b8b8SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); 10631fb1b8b8SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 10641fb1b8b8SAkira Hatanaka return MCDisassembler::Success; 10651fb1b8b8SAkira Hatanaka } 10661fb1b8b8SAkira Hatanaka 10670fa60416SDaniel Sanders static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, 10680fa60416SDaniel Sanders uint64_t Address, 10690fa60416SDaniel Sanders const void *Decoder) { 10700fa60416SDaniel Sanders if (RegNo > 31) 10710fa60416SDaniel Sanders return MCDisassembler::Fail; 10720fa60416SDaniel Sanders 10730fa60416SDaniel Sanders unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo); 10740fa60416SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 10750fa60416SDaniel Sanders return MCDisassembler::Success; 10760fa60416SDaniel Sanders } 10770fa60416SDaniel Sanders 107871928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 107971928e68SAkira Hatanaka unsigned Insn, 108071928e68SAkira Hatanaka uint64_t Address, 108171928e68SAkira Hatanaka const void *Decoder) { 108271928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1083ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1084ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 10859bf2b567SAkira Hatanaka 108613e6ccf3SAkira Hatanaka Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 108713e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 108871928e68SAkira Hatanaka 1089d7ecf49eSVladimir Medic if(Inst.getOpcode() == Mips::SC || 1090d7ecf49eSVladimir Medic Inst.getOpcode() == Mips::SCD){ 10919bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 109271928e68SAkira Hatanaka } 109371928e68SAkira Hatanaka 10949bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 10959bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 109671928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 109771928e68SAkira Hatanaka 109871928e68SAkira Hatanaka return MCDisassembler::Success; 109971928e68SAkira Hatanaka } 110071928e68SAkira Hatanaka 110192db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 110292db6b78SDaniel Sanders unsigned Insn, 110392db6b78SDaniel Sanders uint64_t Address, 110492db6b78SDaniel Sanders const void *Decoder) { 110592db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 110692db6b78SDaniel Sanders unsigned Hint = fieldFromInstruction(Insn, 16, 5); 110792db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 110892db6b78SDaniel Sanders 110992db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 111092db6b78SDaniel Sanders 111192db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 111292db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 111392db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Hint)); 111492db6b78SDaniel Sanders 111592db6b78SDaniel Sanders return MCDisassembler::Success; 111692db6b78SDaniel Sanders } 111792db6b78SDaniel Sanders 1118ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst, 1119ab6d1cceSJozef Kolek unsigned Insn, 1120ab6d1cceSJozef Kolek uint64_t Address, 1121ab6d1cceSJozef Kolek const void *Decoder) { 1122ab6d1cceSJozef Kolek int Offset = SignExtend32<12>(Insn & 0xfff); 1123ab6d1cceSJozef Kolek unsigned Base = fieldFromInstruction(Insn, 16, 5); 1124ab6d1cceSJozef Kolek unsigned Hint = fieldFromInstruction(Insn, 21, 5); 1125ab6d1cceSJozef Kolek 1126ab6d1cceSJozef Kolek Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1127ab6d1cceSJozef Kolek 1128ab6d1cceSJozef Kolek Inst.addOperand(MCOperand::CreateReg(Base)); 1129ab6d1cceSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset)); 1130ab6d1cceSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Hint)); 1131ab6d1cceSJozef Kolek 1132ab6d1cceSJozef Kolek return MCDisassembler::Success; 1133ab6d1cceSJozef Kolek } 1134ab6d1cceSJozef Kolek 1135b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 1136b4484d62SDaniel Sanders unsigned Insn, 1137b4484d62SDaniel Sanders uint64_t Address, 1138b4484d62SDaniel Sanders const void *Decoder) { 1139b4484d62SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 1140b4484d62SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 1141b4484d62SDaniel Sanders 1142b4484d62SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1143b4484d62SDaniel Sanders 1144b4484d62SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 1145b4484d62SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 1146b4484d62SDaniel Sanders 1147b4484d62SDaniel Sanders return MCDisassembler::Success; 1148b4484d62SDaniel Sanders } 1149b4484d62SDaniel Sanders 1150fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 1151fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder) { 1152fe0bf9f6SMatheus Almeida int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10)); 1153fe0bf9f6SMatheus Almeida unsigned Reg = fieldFromInstruction(Insn, 6, 5); 1154fe0bf9f6SMatheus Almeida unsigned Base = fieldFromInstruction(Insn, 11, 5); 1155fe0bf9f6SMatheus Almeida 1156fe0bf9f6SMatheus Almeida Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg); 1157fe0bf9f6SMatheus Almeida Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1158fe0bf9f6SMatheus Almeida 1159fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Reg)); 1160fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Base)); 11616b59c449SMatheus Almeida 11626b59c449SMatheus Almeida // The immediate field of an LD/ST instruction is scaled which means it must 11636b59c449SMatheus Almeida // be multiplied (when decoding) by the size (in bytes) of the instructions' 11646b59c449SMatheus Almeida // data format. 11656b59c449SMatheus Almeida // .b - 1 byte 11666b59c449SMatheus Almeida // .h - 2 bytes 11676b59c449SMatheus Almeida // .w - 4 bytes 11686b59c449SMatheus Almeida // .d - 8 bytes 11696b59c449SMatheus Almeida switch(Inst.getOpcode()) 11706b59c449SMatheus Almeida { 11716b59c449SMatheus Almeida default: 11726b59c449SMatheus Almeida assert (0 && "Unexpected instruction"); 11736b59c449SMatheus Almeida return MCDisassembler::Fail; 11746b59c449SMatheus Almeida break; 11756b59c449SMatheus Almeida case Mips::LD_B: 11766b59c449SMatheus Almeida case Mips::ST_B: 1177fe0bf9f6SMatheus Almeida Inst.addOperand(MCOperand::CreateImm(Offset)); 11786b59c449SMatheus Almeida break; 11796b59c449SMatheus Almeida case Mips::LD_H: 11806b59c449SMatheus Almeida case Mips::ST_H: 1181d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(Offset * 2)); 11826b59c449SMatheus Almeida break; 11836b59c449SMatheus Almeida case Mips::LD_W: 11846b59c449SMatheus Almeida case Mips::ST_W: 1185d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(Offset * 4)); 11866b59c449SMatheus Almeida break; 11876b59c449SMatheus Almeida case Mips::LD_D: 11886b59c449SMatheus Almeida case Mips::ST_D: 1189d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(Offset * 8)); 11906b59c449SMatheus Almeida break; 11916b59c449SMatheus Almeida } 1192fe0bf9f6SMatheus Almeida 1193fe0bf9f6SMatheus Almeida return MCDisassembler::Success; 1194fe0bf9f6SMatheus Almeida } 1195fe0bf9f6SMatheus Almeida 1196315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 1197315e7ecaSJozef Kolek unsigned Insn, 1198315e7ecaSJozef Kolek uint64_t Address, 1199315e7ecaSJozef Kolek const void *Decoder) { 1200315e7ecaSJozef Kolek unsigned Offset = Insn & 0xf; 1201315e7ecaSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 7, 3); 1202315e7ecaSJozef Kolek unsigned Base = fieldFromInstruction(Insn, 4, 3); 1203315e7ecaSJozef Kolek 1204315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1205315e7ecaSJozef Kolek case Mips::LBU16_MM: 1206315e7ecaSJozef Kolek case Mips::LHU16_MM: 1207315e7ecaSJozef Kolek case Mips::LW16_MM: 1208315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder) 1209315e7ecaSJozef Kolek == MCDisassembler::Fail) 1210315e7ecaSJozef Kolek return MCDisassembler::Fail; 1211315e7ecaSJozef Kolek break; 1212315e7ecaSJozef Kolek case Mips::SB16_MM: 1213315e7ecaSJozef Kolek case Mips::SH16_MM: 1214315e7ecaSJozef Kolek case Mips::SW16_MM: 1215315e7ecaSJozef Kolek if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder) 1216315e7ecaSJozef Kolek == MCDisassembler::Fail) 1217315e7ecaSJozef Kolek return MCDisassembler::Fail; 1218315e7ecaSJozef Kolek break; 1219315e7ecaSJozef Kolek } 1220315e7ecaSJozef Kolek 1221315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder) 1222315e7ecaSJozef Kolek == MCDisassembler::Fail) 1223315e7ecaSJozef Kolek return MCDisassembler::Fail; 1224315e7ecaSJozef Kolek 1225315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1226315e7ecaSJozef Kolek case Mips::LBU16_MM: 1227315e7ecaSJozef Kolek if (Offset == 0xf) 1228315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(-1)); 1229315e7ecaSJozef Kolek else 1230315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset)); 1231315e7ecaSJozef Kolek break; 1232315e7ecaSJozef Kolek case Mips::SB16_MM: 1233315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset)); 1234315e7ecaSJozef Kolek break; 1235315e7ecaSJozef Kolek case Mips::LHU16_MM: 1236315e7ecaSJozef Kolek case Mips::SH16_MM: 1237315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset << 1)); 1238315e7ecaSJozef Kolek break; 1239315e7ecaSJozef Kolek case Mips::LW16_MM: 1240315e7ecaSJozef Kolek case Mips::SW16_MM: 1241315e7ecaSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset << 2)); 1242315e7ecaSJozef Kolek break; 1243315e7ecaSJozef Kolek } 1244315e7ecaSJozef Kolek 1245315e7ecaSJozef Kolek return MCDisassembler::Success; 1246315e7ecaSJozef Kolek } 1247315e7ecaSJozef Kolek 124812c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, 124912c6982bSJozef Kolek unsigned Insn, 125012c6982bSJozef Kolek uint64_t Address, 125112c6982bSJozef Kolek const void *Decoder) { 125212c6982bSJozef Kolek unsigned Offset = Insn & 0x1F; 125312c6982bSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 5, 5); 125412c6982bSJozef Kolek 125512c6982bSJozef Kolek Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 125612c6982bSJozef Kolek 125712c6982bSJozef Kolek Inst.addOperand(MCOperand::CreateReg(Reg)); 125812c6982bSJozef Kolek Inst.addOperand(MCOperand::CreateReg(Mips::SP)); 125912c6982bSJozef Kolek Inst.addOperand(MCOperand::CreateImm(Offset << 2)); 126012c6982bSJozef Kolek 126112c6982bSJozef Kolek return MCDisassembler::Success; 126212c6982bSJozef Kolek } 126312c6982bSJozef Kolek 1264dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 1265dde3d582SVladimir Medic unsigned Insn, 1266dde3d582SVladimir Medic uint64_t Address, 1267dde3d582SVladimir Medic const void *Decoder) { 1268dde3d582SVladimir Medic int Offset = SignExtend32<12>(Insn & 0x0fff); 1269dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1270dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1271dde3d582SVladimir Medic 1272dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1273dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1274dde3d582SVladimir Medic 1275a4c4b5fcSZoran Jovanovic switch (Inst.getOpcode()) { 1276a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 1277a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 1278a4c4b5fcSZoran Jovanovic if (DecodeRegListOperand(Inst, Insn, Address, Decoder) 1279a4c4b5fcSZoran Jovanovic == MCDisassembler::Fail) 1280a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 1281a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Base)); 1282a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(Offset)); 1283a4c4b5fcSZoran Jovanovic break; 1284a4c4b5fcSZoran Jovanovic case Mips::SC_MM: 1285285cc289SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Reg)); 1286a4c4b5fcSZoran Jovanovic // fallthrough 1287a4c4b5fcSZoran Jovanovic default: 1288dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Reg)); 12892deca348SZoran Jovanovic if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) 12902deca348SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Reg+1)); 12912deca348SZoran Jovanovic 1292dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Base)); 1293dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Offset)); 1294a4c4b5fcSZoran Jovanovic } 1295dde3d582SVladimir Medic 1296dde3d582SVladimir Medic return MCDisassembler::Success; 1297dde3d582SVladimir Medic } 1298dde3d582SVladimir Medic 1299dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 1300dde3d582SVladimir Medic unsigned Insn, 1301dde3d582SVladimir Medic uint64_t Address, 1302dde3d582SVladimir Medic const void *Decoder) { 1303dde3d582SVladimir Medic int Offset = SignExtend32<16>(Insn & 0xffff); 1304dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1305dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1306dde3d582SVladimir Medic 1307dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1308dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1309dde3d582SVladimir Medic 1310dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Reg)); 1311dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Base)); 1312dde3d582SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Offset)); 1313dde3d582SVladimir Medic 1314dde3d582SVladimir Medic return MCDisassembler::Success; 1315dde3d582SVladimir Medic } 1316dde3d582SVladimir Medic 131771928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, 131871928e68SAkira Hatanaka unsigned Insn, 131971928e68SAkira Hatanaka uint64_t Address, 132071928e68SAkira Hatanaka const void *Decoder) { 132171928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1322ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1323ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 132471928e68SAkira Hatanaka 13259bf2b567SAkira Hatanaka Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 132613e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 13279bf2b567SAkira Hatanaka 13289bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 13299bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Base)); 133071928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(Offset)); 133171928e68SAkira Hatanaka 133271928e68SAkira Hatanaka return MCDisassembler::Success; 133371928e68SAkira Hatanaka } 133471928e68SAkira Hatanaka 133592db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, 133692db6b78SDaniel Sanders unsigned Insn, 133792db6b78SDaniel Sanders uint64_t Address, 133892db6b78SDaniel Sanders const void *Decoder) { 133992db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 134092db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 134192db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 134292db6b78SDaniel Sanders 134392db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); 134492db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 134592db6b78SDaniel Sanders 134692db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 134792db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 134892db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 134992db6b78SDaniel Sanders 135092db6b78SDaniel Sanders return MCDisassembler::Success; 135192db6b78SDaniel Sanders } 135292db6b78SDaniel Sanders 135392db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, 135492db6b78SDaniel Sanders unsigned Insn, 135592db6b78SDaniel Sanders uint64_t Address, 135692db6b78SDaniel Sanders const void *Decoder) { 135792db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 135892db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 135992db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 136092db6b78SDaniel Sanders 136192db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP3RegClassID, Reg); 136292db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 136392db6b78SDaniel Sanders 136492db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 136592db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 136692db6b78SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 136792db6b78SDaniel Sanders 136892db6b78SDaniel Sanders return MCDisassembler::Success; 136992db6b78SDaniel Sanders } 137092db6b78SDaniel Sanders 1371435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, 1372435cf8a4SVladimir Medic unsigned Insn, 1373435cf8a4SVladimir Medic uint64_t Address, 1374435cf8a4SVladimir Medic const void *Decoder) { 1375435cf8a4SVladimir Medic int Offset = SignExtend32<11>(Insn & 0x07ff); 1376435cf8a4SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1377435cf8a4SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 11, 5); 1378435cf8a4SVladimir Medic 1379435cf8a4SVladimir Medic Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); 1380435cf8a4SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1381435cf8a4SVladimir Medic 1382435cf8a4SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Reg)); 1383435cf8a4SVladimir Medic Inst.addOperand(MCOperand::CreateReg(Base)); 1384435cf8a4SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Offset)); 1385435cf8a4SVladimir Medic 1386435cf8a4SVladimir Medic return MCDisassembler::Success; 1387435cf8a4SVladimir Medic } 13886a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 13896a803f61SDaniel Sanders unsigned Insn, 13906a803f61SDaniel Sanders uint64_t Address, 13916a803f61SDaniel Sanders const void *Decoder) { 13926a803f61SDaniel Sanders int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff); 13936a803f61SDaniel Sanders unsigned Rt = fieldFromInstruction(Insn, 16, 5); 13946a803f61SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 13956a803f61SDaniel Sanders 13966a803f61SDaniel Sanders Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt); 13976a803f61SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 13986a803f61SDaniel Sanders 13996a803f61SDaniel Sanders if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){ 14006a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Rt)); 14016a803f61SDaniel Sanders } 14026a803f61SDaniel Sanders 14036a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Rt)); 14046a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Base)); 14056a803f61SDaniel Sanders Inst.addOperand(MCOperand::CreateImm(Offset)); 14066a803f61SDaniel Sanders 14076a803f61SDaniel Sanders return MCDisassembler::Success; 14086a803f61SDaniel Sanders } 140971928e68SAkira Hatanaka 141071928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 141171928e68SAkira Hatanaka unsigned RegNo, 141271928e68SAkira Hatanaka uint64_t Address, 141371928e68SAkira Hatanaka const void *Decoder) { 141471928e68SAkira Hatanaka // Currently only hardware register 29 is supported. 141571928e68SAkira Hatanaka if (RegNo != 29) 141671928e68SAkira Hatanaka return MCDisassembler::Fail; 141771928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Mips::HWR29)); 141871928e68SAkira Hatanaka return MCDisassembler::Success; 141971928e68SAkira Hatanaka } 142071928e68SAkira Hatanaka 142171928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 142271928e68SAkira Hatanaka unsigned RegNo, 142371928e68SAkira Hatanaka uint64_t Address, 142471928e68SAkira Hatanaka const void *Decoder) { 14259bf2b567SAkira Hatanaka if (RegNo > 30 || RegNo %2) 142671928e68SAkira Hatanaka return MCDisassembler::Fail; 142771928e68SAkira Hatanaka 14289bf2b567SAkira Hatanaka ; 14299bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 14309bf2b567SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 143171928e68SAkira Hatanaka return MCDisassembler::Success; 143271928e68SAkira Hatanaka } 143371928e68SAkira Hatanaka 143400fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 1435ecabd1a5SAkira Hatanaka unsigned RegNo, 1436ecabd1a5SAkira Hatanaka uint64_t Address, 1437ecabd1a5SAkira Hatanaka const void *Decoder) { 1438ecabd1a5SAkira Hatanaka if (RegNo >= 4) 1439ecabd1a5SAkira Hatanaka return MCDisassembler::Fail; 1440ecabd1a5SAkira Hatanaka 144100fcf2e1SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo); 1442ecabd1a5SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 1443ecabd1a5SAkira Hatanaka return MCDisassembler::Success; 1444ecabd1a5SAkira Hatanaka } 1445ecabd1a5SAkira Hatanaka 14468002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 144759bfaf77SAkira Hatanaka unsigned RegNo, 144859bfaf77SAkira Hatanaka uint64_t Address, 144959bfaf77SAkira Hatanaka const void *Decoder) { 145059bfaf77SAkira Hatanaka if (RegNo >= 4) 145159bfaf77SAkira Hatanaka return MCDisassembler::Fail; 145259bfaf77SAkira Hatanaka 14538002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo); 145459bfaf77SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 145559bfaf77SAkira Hatanaka return MCDisassembler::Success; 145659bfaf77SAkira Hatanaka } 145759bfaf77SAkira Hatanaka 14588002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 145959bfaf77SAkira Hatanaka unsigned RegNo, 146059bfaf77SAkira Hatanaka uint64_t Address, 146159bfaf77SAkira Hatanaka const void *Decoder) { 146259bfaf77SAkira Hatanaka if (RegNo >= 4) 146359bfaf77SAkira Hatanaka return MCDisassembler::Fail; 146459bfaf77SAkira Hatanaka 14658002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo); 146659bfaf77SAkira Hatanaka Inst.addOperand(MCOperand::CreateReg(Reg)); 146759bfaf77SAkira Hatanaka return MCDisassembler::Success; 146859bfaf77SAkira Hatanaka } 146959bfaf77SAkira Hatanaka 14703eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, 14713eb663b0SJack Carter unsigned RegNo, 14723eb663b0SJack Carter uint64_t Address, 14733eb663b0SJack Carter const void *Decoder) { 14743eb663b0SJack Carter if (RegNo > 31) 14753eb663b0SJack Carter return MCDisassembler::Fail; 14763eb663b0SJack Carter 14773eb663b0SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo); 14783eb663b0SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 14793eb663b0SJack Carter return MCDisassembler::Success; 14803eb663b0SJack Carter } 14813eb663b0SJack Carter 14825dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, 14835dc8ac92SJack Carter unsigned RegNo, 14845dc8ac92SJack Carter uint64_t Address, 14855dc8ac92SJack Carter const void *Decoder) { 14865dc8ac92SJack Carter if (RegNo > 31) 14875dc8ac92SJack Carter return MCDisassembler::Fail; 14885dc8ac92SJack Carter 14895dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo); 14905dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 14915dc8ac92SJack Carter return MCDisassembler::Success; 14925dc8ac92SJack Carter } 14935dc8ac92SJack Carter 14945dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, 14955dc8ac92SJack Carter unsigned RegNo, 14965dc8ac92SJack Carter uint64_t Address, 14975dc8ac92SJack Carter const void *Decoder) { 14985dc8ac92SJack Carter if (RegNo > 31) 14995dc8ac92SJack Carter return MCDisassembler::Fail; 15005dc8ac92SJack Carter 15015dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo); 15025dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 15035dc8ac92SJack Carter return MCDisassembler::Success; 15045dc8ac92SJack Carter } 15055dc8ac92SJack Carter 15065dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, 15075dc8ac92SJack Carter unsigned RegNo, 15085dc8ac92SJack Carter uint64_t Address, 15095dc8ac92SJack Carter const void *Decoder) { 15105dc8ac92SJack Carter if (RegNo > 31) 15115dc8ac92SJack Carter return MCDisassembler::Fail; 15125dc8ac92SJack Carter 15135dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo); 15145dc8ac92SJack Carter Inst.addOperand(MCOperand::CreateReg(Reg)); 15155dc8ac92SJack Carter return MCDisassembler::Success; 15165dc8ac92SJack Carter } 15175dc8ac92SJack Carter 1518a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, 1519a591fdc6SMatheus Almeida unsigned RegNo, 1520a591fdc6SMatheus Almeida uint64_t Address, 1521a591fdc6SMatheus Almeida const void *Decoder) { 1522a591fdc6SMatheus Almeida if (RegNo > 7) 1523a591fdc6SMatheus Almeida return MCDisassembler::Fail; 1524a591fdc6SMatheus Almeida 1525a591fdc6SMatheus Almeida unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo); 1526a591fdc6SMatheus Almeida Inst.addOperand(MCOperand::CreateReg(Reg)); 1527a591fdc6SMatheus Almeida return MCDisassembler::Success; 1528a591fdc6SMatheus Almeida } 1529a591fdc6SMatheus Almeida 15302a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, 15312a83d680SDaniel Sanders unsigned RegNo, 15322a83d680SDaniel Sanders uint64_t Address, 15332a83d680SDaniel Sanders const void *Decoder) { 15342a83d680SDaniel Sanders if (RegNo > 31) 15352a83d680SDaniel Sanders return MCDisassembler::Fail; 15362a83d680SDaniel Sanders 15372a83d680SDaniel Sanders unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo); 15382a83d680SDaniel Sanders Inst.addOperand(MCOperand::CreateReg(Reg)); 15392a83d680SDaniel Sanders return MCDisassembler::Success; 15402a83d680SDaniel Sanders } 15412a83d680SDaniel Sanders 154271928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 154371928e68SAkira Hatanaka unsigned Offset, 154471928e68SAkira Hatanaka uint64_t Address, 154571928e68SAkira Hatanaka const void *Decoder) { 1546d37bab61SAlexey Samsonov int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4; 154771928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 154871928e68SAkira Hatanaka return MCDisassembler::Success; 154971928e68SAkira Hatanaka } 155071928e68SAkira Hatanaka 155171928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 155271928e68SAkira Hatanaka unsigned Insn, 155371928e68SAkira Hatanaka uint64_t Address, 155471928e68SAkira Hatanaka const void *Decoder) { 155571928e68SAkira Hatanaka 1556ecaef49fSJim Grosbach unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 155771928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 155871928e68SAkira Hatanaka return MCDisassembler::Success; 155971928e68SAkira Hatanaka } 156071928e68SAkira Hatanaka 15613c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst, 15623c8869dcSZoran Jovanovic unsigned Offset, 15633c8869dcSZoran Jovanovic uint64_t Address, 15643c8869dcSZoran Jovanovic const void *Decoder) { 1565d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<21>(Offset) * 4; 15663c8869dcSZoran Jovanovic 15673c8869dcSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 15683c8869dcSZoran Jovanovic return MCDisassembler::Success; 15693c8869dcSZoran Jovanovic } 15703c8869dcSZoran Jovanovic 15713c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst, 15723c8869dcSZoran Jovanovic unsigned Offset, 15733c8869dcSZoran Jovanovic uint64_t Address, 15743c8869dcSZoran Jovanovic const void *Decoder) { 1575d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<26>(Offset) * 4; 15763c8869dcSZoran Jovanovic 15773c8869dcSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 15783c8869dcSZoran Jovanovic return MCDisassembler::Success; 15793c8869dcSZoran Jovanovic } 15803c8869dcSZoran Jovanovic 15819761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, 15829761e96bSJozef Kolek unsigned Offset, 15839761e96bSJozef Kolek uint64_t Address, 15849761e96bSJozef Kolek const void *Decoder) { 15859761e96bSJozef Kolek int32_t BranchOffset = SignExtend32<7>(Offset) << 1; 15869761e96bSJozef Kolek Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 15879761e96bSJozef Kolek return MCDisassembler::Success; 15889761e96bSJozef Kolek } 15899761e96bSJozef Kolek 1590*5cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, 1591*5cfebddeSJozef Kolek unsigned Offset, 1592*5cfebddeSJozef Kolek uint64_t Address, 1593*5cfebddeSJozef Kolek const void *Decoder) { 1594*5cfebddeSJozef Kolek int32_t BranchOffset = SignExtend32<10>(Offset) << 1; 1595*5cfebddeSJozef Kolek Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 1596*5cfebddeSJozef Kolek return MCDisassembler::Success; 1597*5cfebddeSJozef Kolek } 1598*5cfebddeSJozef Kolek 15998a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 16008a80aa76SZoran Jovanovic unsigned Offset, 16018a80aa76SZoran Jovanovic uint64_t Address, 16028a80aa76SZoran Jovanovic const void *Decoder) { 1603d37bab61SAlexey Samsonov int32_t BranchOffset = SignExtend32<16>(Offset) * 2; 16048a80aa76SZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(BranchOffset)); 16058a80aa76SZoran Jovanovic return MCDisassembler::Success; 16068a80aa76SZoran Jovanovic } 16078a80aa76SZoran Jovanovic 1608507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 1609507e084aSZoran Jovanovic unsigned Insn, 1610507e084aSZoran Jovanovic uint64_t Address, 1611507e084aSZoran Jovanovic const void *Decoder) { 1612507e084aSZoran Jovanovic unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1; 1613507e084aSZoran Jovanovic Inst.addOperand(MCOperand::CreateImm(JumpOffset)); 1614507e084aSZoran Jovanovic return MCDisassembler::Success; 1615507e084aSZoran Jovanovic } 161671928e68SAkira Hatanaka 1617aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 1618aa2b9278SJozef Kolek unsigned Value, 1619aa2b9278SJozef Kolek uint64_t Address, 1620aa2b9278SJozef Kolek const void *Decoder) { 1621aa2b9278SJozef Kolek if (Value == 0) 1622aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(1)); 1623aa2b9278SJozef Kolek else if (Value == 0x7) 1624aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(-1)); 1625aa2b9278SJozef Kolek else 1626aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(Value << 2)); 1627aa2b9278SJozef Kolek return MCDisassembler::Success; 1628aa2b9278SJozef Kolek } 1629aa2b9278SJozef Kolek 1630aa2b9278SJozef Kolek static DecodeStatus DecodeUImm6Lsl2(MCInst &Inst, 1631aa2b9278SJozef Kolek unsigned Value, 1632aa2b9278SJozef Kolek uint64_t Address, 1633aa2b9278SJozef Kolek const void *Decoder) { 1634aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(Value << 2)); 1635aa2b9278SJozef Kolek return MCDisassembler::Success; 1636aa2b9278SJozef Kolek } 1637aa2b9278SJozef Kolek 1638aa2b9278SJozef Kolek static DecodeStatus DecodeLiSimm7(MCInst &Inst, 1639aa2b9278SJozef Kolek unsigned Value, 1640aa2b9278SJozef Kolek uint64_t Address, 1641aa2b9278SJozef Kolek const void *Decoder) { 1642aa2b9278SJozef Kolek if (Value == 0x7F) 1643aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(-1)); 1644aa2b9278SJozef Kolek else 1645aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(Value)); 1646aa2b9278SJozef Kolek return MCDisassembler::Success; 1647aa2b9278SJozef Kolek } 1648aa2b9278SJozef Kolek 1649aa2b9278SJozef Kolek static DecodeStatus DecodeSimm4(MCInst &Inst, 1650aa2b9278SJozef Kolek unsigned Value, 1651aa2b9278SJozef Kolek uint64_t Address, 1652aa2b9278SJozef Kolek const void *Decoder) { 1653aa2b9278SJozef Kolek Inst.addOperand(MCOperand::CreateImm(SignExtend32<4>(Value))); 1654aa2b9278SJozef Kolek return MCDisassembler::Success; 1655aa2b9278SJozef Kolek } 1656aa2b9278SJozef Kolek 165771928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst, 165871928e68SAkira Hatanaka unsigned Insn, 165971928e68SAkira Hatanaka uint64_t Address, 166071928e68SAkira Hatanaka const void *Decoder) { 166171928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn))); 166271928e68SAkira Hatanaka return MCDisassembler::Success; 166371928e68SAkira Hatanaka } 166471928e68SAkira Hatanaka 1665779c5937SMatheus Almeida static DecodeStatus DecodeLSAImm(MCInst &Inst, 1666779c5937SMatheus Almeida unsigned Insn, 1667779c5937SMatheus Almeida uint64_t Address, 1668779c5937SMatheus Almeida const void *Decoder) { 1669779c5937SMatheus Almeida // We add one to the immediate field as it was encoded as 'imm - 1'. 1670779c5937SMatheus Almeida Inst.addOperand(MCOperand::CreateImm(Insn + 1)); 1671779c5937SMatheus Almeida return MCDisassembler::Success; 1672779c5937SMatheus Almeida } 1673779c5937SMatheus Almeida 167471928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 167571928e68SAkira Hatanaka unsigned Insn, 167671928e68SAkira Hatanaka uint64_t Address, 167771928e68SAkira Hatanaka const void *Decoder) { 167871928e68SAkira Hatanaka // First we need to grab the pos(lsb) from MCInst. 167971928e68SAkira Hatanaka int Pos = Inst.getOperand(2).getImm(); 168071928e68SAkira Hatanaka int Size = (int) Insn - Pos + 1; 168171928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 168271928e68SAkira Hatanaka return MCDisassembler::Success; 168371928e68SAkira Hatanaka } 168471928e68SAkira Hatanaka 168571928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst, 168671928e68SAkira Hatanaka unsigned Insn, 168771928e68SAkira Hatanaka uint64_t Address, 168871928e68SAkira Hatanaka const void *Decoder) { 168971928e68SAkira Hatanaka int Size = (int) Insn + 1; 169071928e68SAkira Hatanaka Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size))); 169171928e68SAkira Hatanaka return MCDisassembler::Success; 169271928e68SAkira Hatanaka } 1693b59e1a41SDaniel Sanders 1694b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 1695b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder) { 1696d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(SignExtend32<19>(Insn) * 4)); 1697b59e1a41SDaniel Sanders return MCDisassembler::Success; 1698b59e1a41SDaniel Sanders } 16992855142aSZoran Jovanovic 17002855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 17012855142aSZoran Jovanovic uint64_t Address, const void *Decoder) { 1702d37bab61SAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(SignExtend32<18>(Insn) * 8)); 17032855142aSZoran Jovanovic return MCDisassembler::Success; 17042855142aSZoran Jovanovic } 1705a4c4b5fcSZoran Jovanovic 1706b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 1707b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1708b682ddf3SVladimir Medic int32_t DecodedValue; 1709b682ddf3SVladimir Medic switch (Insn) { 1710b682ddf3SVladimir Medic case 0: DecodedValue = 256; break; 1711b682ddf3SVladimir Medic case 1: DecodedValue = 257; break; 1712b682ddf3SVladimir Medic case 510: DecodedValue = -258; break; 1713b682ddf3SVladimir Medic case 511: DecodedValue = -257; break; 1714b682ddf3SVladimir Medic default: DecodedValue = SignExtend32<9>(Insn); break; 1715b682ddf3SVladimir Medic } 17162c55974dSAlexey Samsonov Inst.addOperand(MCOperand::CreateImm(DecodedValue * 4)); 1717b682ddf3SVladimir Medic return MCDisassembler::Success; 1718b682ddf3SVladimir Medic } 1719b682ddf3SVladimir Medic 1720b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 1721b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1722b682ddf3SVladimir Medic // Insn must be >= 0, since it is unsigned that condition is always true. 1723b682ddf3SVladimir Medic assert(Insn < 16); 1724b682ddf3SVladimir Medic int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 1725b682ddf3SVladimir Medic 255, 32768, 65535}; 1726b682ddf3SVladimir Medic Inst.addOperand(MCOperand::CreateImm(DecodedValues[Insn])); 1727b682ddf3SVladimir Medic return MCDisassembler::Success; 1728b682ddf3SVladimir Medic } 1729b682ddf3SVladimir Medic 1730b682ddf3SVladimir Medic static DecodeStatus DecodeUImm5lsl2(MCInst &Inst, unsigned Insn, 1731b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 1732b682ddf3SVladimir Medic Inst.addOperand(MCOperand::CreateImm(Insn << 2)); 1733b682ddf3SVladimir Medic return MCDisassembler::Success; 1734b682ddf3SVladimir Medic } 1735b682ddf3SVladimir Medic 1736a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, 1737a4c4b5fcSZoran Jovanovic unsigned Insn, 1738a4c4b5fcSZoran Jovanovic uint64_t Address, 1739a4c4b5fcSZoran Jovanovic const void *Decoder) { 1740a4c4b5fcSZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5, 1741a4c4b5fcSZoran Jovanovic Mips::S6, Mips::FP}; 1742a4c4b5fcSZoran Jovanovic unsigned RegNum; 1743a4c4b5fcSZoran Jovanovic 1744a4c4b5fcSZoran Jovanovic unsigned RegLst = fieldFromInstruction(Insn, 21, 5); 1745a4c4b5fcSZoran Jovanovic // Empty register lists are not allowed. 1746a4c4b5fcSZoran Jovanovic if (RegLst == 0) 1747a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 1748a4c4b5fcSZoran Jovanovic 1749a4c4b5fcSZoran Jovanovic RegNum = RegLst & 0xf; 1750a4c4b5fcSZoran Jovanovic for (unsigned i = 0; i < RegNum; i++) 1751a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Regs[i])); 1752a4c4b5fcSZoran Jovanovic 1753a4c4b5fcSZoran Jovanovic if (RegLst & 0x10) 1754a4c4b5fcSZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Mips::RA)); 1755a4c4b5fcSZoran Jovanovic 1756a4c4b5fcSZoran Jovanovic return MCDisassembler::Success; 1757a4c4b5fcSZoran Jovanovic } 1758f9a02500SZoran Jovanovic 1759f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 1760f9a02500SZoran Jovanovic uint64_t Address, 1761f9a02500SZoran Jovanovic const void *Decoder) { 1762f9a02500SZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3}; 1763f9a02500SZoran Jovanovic unsigned RegNum; 1764f9a02500SZoran Jovanovic 1765f9a02500SZoran Jovanovic unsigned RegLst = fieldFromInstruction(Insn, 4, 2); 1766f9a02500SZoran Jovanovic // Empty register lists are not allowed. 1767f9a02500SZoran Jovanovic if (RegLst == 0) 1768f9a02500SZoran Jovanovic return MCDisassembler::Fail; 1769f9a02500SZoran Jovanovic 1770f9a02500SZoran Jovanovic RegNum = RegLst & 0x3; 1771f9a02500SZoran Jovanovic for (unsigned i = 0; i < RegNum - 1; i++) 1772f9a02500SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Regs[i])); 1773f9a02500SZoran Jovanovic 1774f9a02500SZoran Jovanovic Inst.addOperand(MCOperand::CreateReg(Mips::RA)); 1775f9a02500SZoran Jovanovic 1776f9a02500SZoran Jovanovic return MCDisassembler::Success; 1777f9a02500SZoran Jovanovic } 17782c6d7320SJozef Kolek 17792c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, 17802c6d7320SJozef Kolek uint64_t Address, const void *Decoder) { 17812c6d7320SJozef Kolek Inst.addOperand(MCOperand::CreateImm(SignExtend32<23>(Insn) << 2)); 17822c6d7320SJozef Kolek return MCDisassembler::Success; 17832c6d7320SJozef Kolek } 1784