1926883e1SEugene Zelenko //===- MipsDisassembler.cpp - Disassembler for Mips -----------------------===// 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 1479220eaeSEugene Zelenko #include "MCTargetDesc/MipsMCTargetDesc.h" 1571928e68SAkira Hatanaka #include "Mips.h" 16926883e1SEugene Zelenko #include "llvm/ADT/ArrayRef.h" 17a1bc0f56SLang Hames #include "llvm/MC/MCContext.h" 18f57c1977SBenjamin Kramer #include "llvm/MC/MCDisassembler/MCDisassembler.h" 19ecaef49fSJim Grosbach #include "llvm/MC/MCFixedLenDisassembler.h" 20ed0881b2SChandler Carruth #include "llvm/MC/MCInst.h" 21926883e1SEugene Zelenko #include "llvm/MC/MCRegisterInfo.h" 226bda14b3SChandler Carruth #include "llvm/MC/MCSubtargetInfo.h" 23926883e1SEugene Zelenko #include "llvm/Support/Compiler.h" 24926883e1SEugene Zelenko #include "llvm/Support/Debug.h" 25926883e1SEugene Zelenko #include "llvm/Support/ErrorHandling.h" 26ed0881b2SChandler Carruth #include "llvm/Support/MathExtras.h" 2771928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h" 286bda14b3SChandler Carruth #include "llvm/Support/raw_ostream.h" 29926883e1SEugene Zelenko #include <cassert> 30926883e1SEugene Zelenko #include <cstdint> 3171928e68SAkira Hatanaka 3271928e68SAkira Hatanaka using namespace llvm; 3371928e68SAkira Hatanaka 34e96dd897SChandler Carruth #define DEBUG_TYPE "mips-disassembler" 35e96dd897SChandler Carruth 3679220eaeSEugene Zelenko using DecodeStatus = MCDisassembler::DecodeStatus; 3771928e68SAkira Hatanaka 38cb3e98cfSBenjamin Kramer namespace { 39cb3e98cfSBenjamin Kramer 40a19216c8SDaniel Sanders class MipsDisassembler : public MCDisassembler { 41dde3d582SVladimir Medic bool IsMicroMips; 42a19216c8SDaniel Sanders bool IsBigEndian; 43926883e1SEugene Zelenko 449bf2b567SAkira Hatanaka public: 45a19216c8SDaniel Sanders MipsDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, bool IsBigEndian) 46a19216c8SDaniel Sanders : MCDisassembler(STI, Ctx), 47db0712f9SMichael Kuperstein IsMicroMips(STI.getFeatureBits()[Mips::FeatureMicroMips]), 48a19216c8SDaniel Sanders IsBigEndian(IsBigEndian) {} 4971928e68SAkira Hatanaka 504fbf76f7SSimon Dardis bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; } 51db0712f9SMichael Kuperstein bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; } 52db0712f9SMichael Kuperstein bool hasMips32() const { return STI.getFeatureBits()[Mips::FeatureMips32]; } 53926883e1SEugene Zelenko 54c171f65aSDaniel Sanders bool hasMips32r6() const { 55db0712f9SMichael Kuperstein return STI.getFeatureBits()[Mips::FeatureMips32r6]; 565c582b2fSDaniel Sanders } 57926883e1SEugene Zelenko 586221be8eSZlatko Buljan bool isFP64() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; } 595c582b2fSDaniel Sanders 60db0712f9SMichael Kuperstein bool isGP64() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; } 610fa60416SDaniel Sanders 624fbf76f7SSimon Dardis bool isPTR64() const { return STI.getFeatureBits()[Mips::FeaturePTR64Bit]; } 634fbf76f7SSimon Dardis 643adf9b8dSKai Nacke bool hasCnMips() const { return STI.getFeatureBits()[Mips::FeatureCnMips]; } 653adf9b8dSKai Nacke 66c171f65aSDaniel Sanders bool hasCOP3() const { 67c171f65aSDaniel Sanders // Only present in MIPS-I and MIPS-II 68c171f65aSDaniel Sanders return !hasMips32() && !hasMips3(); 69c171f65aSDaniel Sanders } 70c171f65aSDaniel Sanders 714aa6bea7SRafael Espindola DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 727fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address, 734aa6bea7SRafael Espindola raw_ostream &VStream, 744aa6bea7SRafael Espindola raw_ostream &CStream) const override; 7571928e68SAkira Hatanaka }; 7671928e68SAkira Hatanaka 77cb3e98cfSBenjamin Kramer } // end anonymous namespace 78cb3e98cfSBenjamin Kramer 7971928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them. 8071928e68SAkira Hatanaka // Definitions are further down. 8113e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 8271928e68SAkira Hatanaka unsigned RegNo, 8371928e68SAkira Hatanaka uint64_t Address, 8471928e68SAkira Hatanaka const void *Decoder); 8571928e68SAkira Hatanaka 86ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 87ec8a5490SReed Kotler unsigned RegNo, 88ec8a5490SReed Kotler uint64_t Address, 89ec8a5490SReed Kotler const void *Decoder); 90ec8a5490SReed Kotler 91b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, 92b0852e54SZoran Jovanovic unsigned RegNo, 93b0852e54SZoran Jovanovic uint64_t Address, 94b0852e54SZoran Jovanovic const void *Decoder); 95b0852e54SZoran Jovanovic 961904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, 971904fa21SJozef Kolek unsigned RegNo, 981904fa21SJozef Kolek uint64_t Address, 991904fa21SJozef Kolek const void *Decoder); 1001904fa21SJozef Kolek 10141688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst, 10241688679SZoran Jovanovic unsigned RegNo, 10341688679SZoran Jovanovic uint64_t Address, 10441688679SZoran Jovanovic const void *Decoder); 10541688679SZoran Jovanovic 10613e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 10771928e68SAkira Hatanaka unsigned RegNo, 10871928e68SAkira Hatanaka uint64_t Address, 10971928e68SAkira Hatanaka const void *Decoder); 11071928e68SAkira Hatanaka 1119bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 1129bfa2e2eSAkira Hatanaka unsigned Insn, 1139bfa2e2eSAkira Hatanaka uint64_t Address, 1149bfa2e2eSAkira Hatanaka const void *Decoder); 1159bfa2e2eSAkira Hatanaka 116654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 117ecabd1a5SAkira Hatanaka unsigned RegNo, 118ecabd1a5SAkira Hatanaka uint64_t Address, 119ecabd1a5SAkira Hatanaka const void *Decoder); 120ecabd1a5SAkira Hatanaka 12171928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 12271928e68SAkira Hatanaka unsigned RegNo, 12371928e68SAkira Hatanaka uint64_t Address, 12471928e68SAkira Hatanaka const void *Decoder); 12571928e68SAkira Hatanaka 12671928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 12771928e68SAkira Hatanaka unsigned RegNo, 12871928e68SAkira Hatanaka uint64_t Address, 12971928e68SAkira Hatanaka const void *Decoder); 13071928e68SAkira Hatanaka 13171928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 13271928e68SAkira Hatanaka unsigned RegNo, 13371928e68SAkira Hatanaka uint64_t Address, 13471928e68SAkira Hatanaka const void *Decoder); 13571928e68SAkira Hatanaka 1361fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 1371fb1b8b8SAkira Hatanaka unsigned RegNo, 1381fb1b8b8SAkira Hatanaka uint64_t Address, 1391fb1b8b8SAkira Hatanaka const void *Decoder); 1401fb1b8b8SAkira Hatanaka 14136901dd1SVasileios Kalintiris static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, 1420fa60416SDaniel Sanders uint64_t Address, 1430fa60416SDaniel Sanders const void *Decoder); 1440fa60416SDaniel Sanders 14571928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 14671928e68SAkira Hatanaka unsigned Insn, 14771928e68SAkira Hatanaka uint64_t Address, 14871928e68SAkira Hatanaka const void *Decoder); 14971928e68SAkira Hatanaka 15071928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 15171928e68SAkira Hatanaka unsigned RegNo, 15271928e68SAkira Hatanaka uint64_t Address, 15371928e68SAkira Hatanaka const void *Decoder); 15471928e68SAkira Hatanaka 15500fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 156ecabd1a5SAkira Hatanaka unsigned RegNo, 157ecabd1a5SAkira Hatanaka uint64_t Address, 158ecabd1a5SAkira Hatanaka const void *Decoder); 159ecabd1a5SAkira Hatanaka 1608002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 16159bfaf77SAkira Hatanaka unsigned RegNo, 16259bfaf77SAkira Hatanaka uint64_t Address, 16359bfaf77SAkira Hatanaka const void *Decoder); 16459bfaf77SAkira Hatanaka 1658002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 16659bfaf77SAkira Hatanaka unsigned RegNo, 16759bfaf77SAkira Hatanaka uint64_t Address, 16859bfaf77SAkira Hatanaka const void *Decoder); 16959bfaf77SAkira Hatanaka 1703eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, 1713eb663b0SJack Carter unsigned RegNo, 1723eb663b0SJack Carter uint64_t Address, 1733eb663b0SJack Carter const void *Decoder); 1743eb663b0SJack Carter 1755dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, 1765dc8ac92SJack Carter unsigned RegNo, 1775dc8ac92SJack Carter uint64_t Address, 1785dc8ac92SJack Carter const void *Decoder); 1795dc8ac92SJack Carter 1805dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, 1815dc8ac92SJack Carter unsigned RegNo, 1825dc8ac92SJack Carter uint64_t Address, 1835dc8ac92SJack Carter const void *Decoder); 1845dc8ac92SJack Carter 1855dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, 1865dc8ac92SJack Carter unsigned RegNo, 1875dc8ac92SJack Carter uint64_t Address, 1885dc8ac92SJack Carter const void *Decoder); 1895dc8ac92SJack Carter 190a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, 191a591fdc6SMatheus Almeida unsigned RegNo, 192a591fdc6SMatheus Almeida uint64_t Address, 193a591fdc6SMatheus Almeida const void *Decoder); 194a591fdc6SMatheus Almeida 195a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, 196a3134faeSDaniel Sanders unsigned RegNo, 197a3134faeSDaniel Sanders uint64_t Address, 198a3134faeSDaniel Sanders const void *Decoder); 199a3134faeSDaniel Sanders 2002a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, 2012a83d680SDaniel Sanders unsigned RegNo, 2022a83d680SDaniel Sanders uint64_t Address, 2032a83d680SDaniel Sanders const void *Decoder); 2042a83d680SDaniel Sanders 20571928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 20671928e68SAkira Hatanaka unsigned Offset, 20771928e68SAkira Hatanaka uint64_t Address, 20871928e68SAkira Hatanaka const void *Decoder); 20971928e68SAkira Hatanaka 2106f09cdfdSHrvoje Varga static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, 2116f09cdfdSHrvoje Varga unsigned Offset, 2126f09cdfdSHrvoje Varga uint64_t Address, 2136f09cdfdSHrvoje Varga const void *Decoder); 2146f09cdfdSHrvoje Varga 21571928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 21671928e68SAkira Hatanaka unsigned Insn, 21771928e68SAkira Hatanaka uint64_t Address, 21871928e68SAkira Hatanaka const void *Decoder); 21971928e68SAkira Hatanaka 2203c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst, 2213c8869dcSZoran Jovanovic unsigned Offset, 2223c8869dcSZoran Jovanovic uint64_t Address, 2233c8869dcSZoran Jovanovic const void *Decoder); 2243c8869dcSZoran Jovanovic 22584e4d59eSZoran Jovanovic static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, 22684e4d59eSZoran Jovanovic unsigned Offset, 22784e4d59eSZoran Jovanovic uint64_t Address, 22884e4d59eSZoran Jovanovic const void *Decoder); 22984e4d59eSZoran Jovanovic 2303c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst, 2313c8869dcSZoran Jovanovic unsigned Offset, 2323c8869dcSZoran Jovanovic uint64_t Address, 2333c8869dcSZoran Jovanovic const void *Decoder); 2343c8869dcSZoran Jovanovic 2359761e96bSJozef Kolek // DecodeBranchTarget7MM - Decode microMIPS branch offset, which is 2369761e96bSJozef Kolek // shifted left by 1 bit. 2379761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, 2389761e96bSJozef Kolek unsigned Offset, 2399761e96bSJozef Kolek uint64_t Address, 2409761e96bSJozef Kolek const void *Decoder); 2419761e96bSJozef Kolek 2425cfebddeSJozef Kolek // DecodeBranchTarget10MM - Decode microMIPS branch offset, which is 2435cfebddeSJozef Kolek // shifted left by 1 bit. 2445cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, 2455cfebddeSJozef Kolek unsigned Offset, 2465cfebddeSJozef Kolek uint64_t Address, 2475cfebddeSJozef Kolek const void *Decoder); 2485cfebddeSJozef Kolek 2498a80aa76SZoran Jovanovic // DecodeBranchTargetMM - Decode microMIPS branch offset, which is 2508a80aa76SZoran Jovanovic // shifted left by 1 bit. 2518a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 2528a80aa76SZoran Jovanovic unsigned Offset, 2538a80aa76SZoran Jovanovic uint64_t Address, 2548a80aa76SZoran Jovanovic const void *Decoder); 2558a80aa76SZoran Jovanovic 256a887b361SZoran Jovanovic // DecodeBranchTarget26MM - Decode microMIPS branch offset, which is 257a887b361SZoran Jovanovic // shifted left by 1 bit. 258a887b361SZoran Jovanovic static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, 259a887b361SZoran Jovanovic unsigned Offset, 260a887b361SZoran Jovanovic uint64_t Address, 261a887b361SZoran Jovanovic const void *Decoder); 262a887b361SZoran Jovanovic 263507e084aSZoran Jovanovic // DecodeJumpTargetMM - Decode microMIPS jump target, which is 264507e084aSZoran Jovanovic // shifted left by 1 bit. 265507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 266507e084aSZoran Jovanovic unsigned Insn, 267507e084aSZoran Jovanovic uint64_t Address, 268507e084aSZoran Jovanovic const void *Decoder); 269507e084aSZoran Jovanovic 27071928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 27171928e68SAkira Hatanaka unsigned Insn, 27271928e68SAkira Hatanaka uint64_t Address, 27371928e68SAkira Hatanaka const void *Decoder); 27471928e68SAkira Hatanaka 275e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst, 276e4e83a7bSDaniel Sanders unsigned Insn, 277e4e83a7bSDaniel Sanders uint64_t Address, 278e4e83a7bSDaniel Sanders const void *Decoder); 279e4e83a7bSDaniel Sanders 2803c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst, 2813c88fbd3SHrvoje Varga unsigned Insn, 2823c88fbd3SHrvoje Varga uint64_t Address, 2833c88fbd3SHrvoje Varga const void *Decoder); 2843c88fbd3SHrvoje Varga 28579220eaeSEugene Zelenko static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address, 28692db6b78SDaniel Sanders const void *Decoder); 28792db6b78SDaniel Sanders 288e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, 289df464ae2SVladimir Medic unsigned Insn, 290df464ae2SVladimir Medic uint64_t Address, 291df464ae2SVladimir Medic const void *Decoder); 292df464ae2SVladimir Medic 293ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst, 294ab6d1cceSJozef Kolek unsigned Insn, 295ab6d1cceSJozef Kolek uint64_t Address, 296ab6d1cceSJozef Kolek const void *Decoder); 297ab6d1cceSJozef Kolek 298d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst, 299d9790793SZoran Jovanovic unsigned Insn, 300d9790793SZoran Jovanovic uint64_t Address, 301d9790793SZoran Jovanovic const void *Decoder); 302d9790793SZoran Jovanovic 303b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 304b4484d62SDaniel Sanders unsigned Insn, 305b4484d62SDaniel Sanders uint64_t Address, 306b4484d62SDaniel Sanders const void *Decoder); 307b4484d62SDaniel Sanders 308eac9301cSSimon Dardis static DecodeStatus DecodeSyncI_MM(MCInst &Inst, 309eac9301cSSimon Dardis unsigned Insn, 310eac9301cSSimon Dardis uint64_t Address, 311eac9301cSSimon Dardis const void *Decoder); 312eac9301cSSimon Dardis 31318148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst, 31418148671SHrvoje Varga unsigned Insn, 31518148671SHrvoje Varga uint64_t Address, 31618148671SHrvoje Varga const void *Decoder); 31718148671SHrvoje Varga 318fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 319fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder); 320fe0bf9f6SMatheus Almeida 321315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 322315e7ecaSJozef Kolek unsigned Insn, 323315e7ecaSJozef Kolek uint64_t Address, 324315e7ecaSJozef Kolek const void *Decoder); 325315e7ecaSJozef Kolek 32612c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, 32712c6982bSJozef Kolek unsigned Insn, 32812c6982bSJozef Kolek uint64_t Address, 32912c6982bSJozef Kolek const void *Decoder); 33012c6982bSJozef Kolek 331e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, 332e10a02ecSJozef Kolek unsigned Insn, 333e10a02ecSJozef Kolek uint64_t Address, 334e10a02ecSJozef Kolek const void *Decoder); 335e10a02ecSJozef Kolek 336d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, 337d68d424aSJozef Kolek unsigned Insn, 338d68d424aSJozef Kolek uint64_t Address, 339d68d424aSJozef Kolek const void *Decoder); 340d68d424aSJozef Kolek 341a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst, 342a6593ff6SZoran Jovanovic unsigned Insn, 343a6593ff6SZoran Jovanovic uint64_t Address, 344a6593ff6SZoran Jovanovic const void *Decoder); 345a6593ff6SZoran Jovanovic 346dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 347dde3d582SVladimir Medic unsigned Insn, 348dde3d582SVladimir Medic uint64_t Address, 349dde3d582SVladimir Medic const void *Decoder); 350dde3d582SVladimir Medic 351dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 352dde3d582SVladimir Medic unsigned Insn, 353dde3d582SVladimir Medic uint64_t Address, 354dde3d582SVladimir Medic const void *Decoder); 355dde3d582SVladimir Medic 35671928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 35771928e68SAkira Hatanaka uint64_t Address, 35871928e68SAkira Hatanaka const void *Decoder); 35971928e68SAkira Hatanaka 360cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn, 361cba9f80bSZlatko Buljan uint64_t Address, 362cba9f80bSZlatko Buljan const void *Decoder); 363cba9f80bSZlatko Buljan 36479220eaeSEugene Zelenko static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address, 36592db6b78SDaniel Sanders const void *Decoder); 36692db6b78SDaniel Sanders 36779220eaeSEugene Zelenko static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address, 36892db6b78SDaniel Sanders const void *Decoder); 36992db6b78SDaniel Sanders 370435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn, 37179220eaeSEugene Zelenko uint64_t Address, const void *Decoder); 372435cf8a4SVladimir Medic 373cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn, 374cba9f80bSZlatko Buljan uint64_t Address, 375cba9f80bSZlatko Buljan const void *Decoder); 376cba9f80bSZlatko Buljan 3776a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 3786a803f61SDaniel Sanders unsigned Insn, 3796a803f61SDaniel Sanders uint64_t Address, 3806a803f61SDaniel Sanders const void *Decoder); 3816a803f61SDaniel Sanders 382aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 383aa2b9278SJozef Kolek unsigned Value, 384aa2b9278SJozef Kolek uint64_t Address, 385aa2b9278SJozef Kolek const void *Decoder); 386aa2b9278SJozef Kolek 38797297770SDaniel Sanders static DecodeStatus DecodeLi16Imm(MCInst &Inst, 388aa2b9278SJozef Kolek unsigned Value, 389aa2b9278SJozef Kolek uint64_t Address, 390aa2b9278SJozef Kolek const void *Decoder); 391aa2b9278SJozef Kolek 3926b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, 3936b28f09dSZoran Jovanovic unsigned Value, 3946b28f09dSZoran Jovanovic uint64_t Address, 3956b28f09dSZoran Jovanovic const void *Decoder); 3966b28f09dSZoran Jovanovic 39719b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale> 39819b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, 39919b7f76aSDaniel Sanders uint64_t Address, 40019b7f76aSDaniel Sanders const void *Decoder); 40119b7f76aSDaniel Sanders 402ea4f653dSDaniel Sanders template <unsigned Bits, int Offset> 403ea4f653dSDaniel Sanders static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value, 40419b7f76aSDaniel Sanders uint64_t Address, 40519b7f76aSDaniel Sanders const void *Decoder) { 40619b7f76aSDaniel Sanders return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address, 40719b7f76aSDaniel Sanders Decoder); 40819b7f76aSDaniel Sanders } 409779c5937SMatheus Almeida 41097297770SDaniel Sanders template <unsigned Bits, int Offset = 0, int ScaleBy = 1> 41197297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value, 41297297770SDaniel Sanders uint64_t Address, 41397297770SDaniel Sanders const void *Decoder); 41478e89020SDaniel Sanders 41571928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 41671928e68SAkira Hatanaka unsigned Insn, 41771928e68SAkira Hatanaka uint64_t Address, 41871928e68SAkira Hatanaka const void *Decoder); 41971928e68SAkira Hatanaka 420b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 421b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder); 422b59e1a41SDaniel Sanders 4232855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 4242855142aSZoran Jovanovic uint64_t Address, const void *Decoder); 4252855142aSZoran Jovanovic 426b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 427b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 428b682ddf3SVladimir Medic 429b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 430b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 431b682ddf3SVladimir Medic 4322c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, 4332c6d7320SJozef Kolek uint64_t Address, const void *Decoder); 4342c6d7320SJozef Kolek 435b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't 436b50ccf8eSDaniel Sanders /// handle. 437b50ccf8eSDaniel Sanders template <typename InsnType> 438b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 439b50ccf8eSDaniel Sanders const void *Decoder); 4405c582b2fSDaniel Sanders 4415c582b2fSDaniel Sanders template <typename InsnType> 442cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address, 443cf060794SSimon Dardis const void *Decoder); 444cf060794SSimon Dardis 445cf060794SSimon Dardis template <typename InsnType> 446cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address, 447cf060794SSimon Dardis const void *Decoder); 448cf060794SSimon Dardis 449cf060794SSimon Dardis template <typename InsnType> 450b3fd189cSSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address, 451b3fd189cSSimon Dardis const void *Decoder); 452b3fd189cSSimon Dardis 453b3fd189cSSimon Dardis template <typename InsnType> 454b3fd189cSSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address, 455b3fd189cSSimon Dardis const void *Decoder); 456b3fd189cSSimon Dardis 457b3fd189cSSimon Dardis template <typename InsnType> 4585c582b2fSDaniel Sanders static DecodeStatus 4595c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4605c582b2fSDaniel Sanders const void *Decoder); 4615c582b2fSDaniel Sanders 4625c582b2fSDaniel Sanders template <typename InsnType> 4635c582b2fSDaniel Sanders static DecodeStatus 464c962c493SHrvoje Varga DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, 465c962c493SHrvoje Varga const void *Decoder); 466c962c493SHrvoje Varga 467c962c493SHrvoje Varga template <typename InsnType> 468c962c493SHrvoje Varga static DecodeStatus 4695c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4705c582b2fSDaniel Sanders const void *Decoder); 4715c582b2fSDaniel Sanders 4725c582b2fSDaniel Sanders template <typename InsnType> 4735c582b2fSDaniel Sanders static DecodeStatus 474c962c493SHrvoje Varga DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, 475c962c493SHrvoje Varga const void *Decoder); 476c962c493SHrvoje Varga 477c962c493SHrvoje Varga template <typename InsnType> 478c962c493SHrvoje Varga static DecodeStatus 479f0ed16eaSHrvoje Varga DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, 480f0ed16eaSHrvoje Varga const void *Decoder); 481f0ed16eaSHrvoje Varga 482f0ed16eaSHrvoje Varga template <typename InsnType> 483f0ed16eaSHrvoje Varga static DecodeStatus 484f0ed16eaSHrvoje Varga DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, 485f0ed16eaSHrvoje Varga const void *Decoder); 486f0ed16eaSHrvoje Varga 487f0ed16eaSHrvoje Varga template <typename InsnType> 488f0ed16eaSHrvoje Varga static DecodeStatus 4895c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4905c582b2fSDaniel Sanders const void *Decoder); 4915c582b2fSDaniel Sanders 4925c582b2fSDaniel Sanders template <typename InsnType> 4935c582b2fSDaniel Sanders static DecodeStatus 4945c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4955c582b2fSDaniel Sanders const void *Decoder); 4965c582b2fSDaniel Sanders 4975c582b2fSDaniel Sanders template <typename InsnType> 4985c582b2fSDaniel Sanders static DecodeStatus 4995c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 5005c582b2fSDaniel Sanders const void *Decoder); 5015c582b2fSDaniel Sanders 50228a0ca07SZoran Jovanovic template <typename InsnType> 50328a0ca07SZoran Jovanovic static DecodeStatus 50428a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 50528a0ca07SZoran Jovanovic const void *Decoder); 50628a0ca07SZoran Jovanovic 507fdbd0a37SZoran Jovanovic template <typename InsnType> 508fdbd0a37SZoran Jovanovic static DecodeStatus 509fdbd0a37SZoran Jovanovic DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, 510fdbd0a37SZoran Jovanovic const void *Decoder); 511fdbd0a37SZoran Jovanovic 512fdbd0a37SZoran Jovanovic template <typename InsnType> 513fdbd0a37SZoran Jovanovic static DecodeStatus 514fdbd0a37SZoran Jovanovic DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, 515fdbd0a37SZoran Jovanovic const void *Decoder); 516fdbd0a37SZoran Jovanovic 5176f83ae38SSimon Dardis template <typename InsnType> 5186f83ae38SSimon Dardis static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address, 5196f83ae38SSimon Dardis const void *Decoder); 5206f83ae38SSimon Dardis 52155e44673SSimon Dardis template <typename InsnType> 52255e44673SSimon Dardis static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address, 52355e44673SSimon Dardis const void *Decoder); 52455e44673SSimon Dardis 5253408caf6SPetar Jovanovic template <typename InsnType> 5263408caf6SPetar Jovanovic static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address, 5273408caf6SPetar Jovanovic const void *Decoder); 5283408caf6SPetar Jovanovic 529a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn, 530a4c4b5fcSZoran Jovanovic uint64_t Address, 531a4c4b5fcSZoran Jovanovic const void *Decoder); 532a4c4b5fcSZoran Jovanovic 533f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 534f9a02500SZoran Jovanovic uint64_t Address, 535f9a02500SZoran Jovanovic const void *Decoder); 536f9a02500SZoran Jovanovic 537169df4e2SSimon Dardis static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair, 53841688679SZoran Jovanovic uint64_t Address, 53941688679SZoran Jovanovic const void *Decoder); 54041688679SZoran Jovanovic 54171928e68SAkira Hatanaka namespace llvm { 542926883e1SEugene Zelenko 543f42454b9SMehdi Amini Target &getTheMipselTarget(); 544f42454b9SMehdi Amini Target &getTheMipsTarget(); 545f42454b9SMehdi Amini Target &getTheMips64Target(); 546f42454b9SMehdi Amini Target &getTheMips64elTarget(); 547926883e1SEugene Zelenko 548926883e1SEugene Zelenko } // end namespace llvm 54971928e68SAkira Hatanaka 55071928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler( 55171928e68SAkira Hatanaka const Target &T, 552a1bc0f56SLang Hames const MCSubtargetInfo &STI, 553a1bc0f56SLang Hames MCContext &Ctx) { 554a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, true); 55571928e68SAkira Hatanaka } 55671928e68SAkira Hatanaka 55771928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler( 55871928e68SAkira Hatanaka const Target &T, 559a1bc0f56SLang Hames const MCSubtargetInfo &STI, 560a1bc0f56SLang Hames MCContext &Ctx) { 561a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, false); 56271928e68SAkira Hatanaka } 56371928e68SAkira Hatanaka 56471928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() { 56571928e68SAkira Hatanaka // Register the disassembler. 566f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(), 56771928e68SAkira Hatanaka createMipsDisassembler); 568f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(), 56971928e68SAkira Hatanaka createMipselDisassembler); 570f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getTheMips64Target(), 571a19216c8SDaniel Sanders createMipsDisassembler); 572f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(), 573a19216c8SDaniel Sanders createMipselDisassembler); 57471928e68SAkira Hatanaka } 57571928e68SAkira Hatanaka 57671928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc" 57771928e68SAkira Hatanaka 5785c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 579a19216c8SDaniel Sanders const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D); 5805c582b2fSDaniel Sanders const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo(); 5815c582b2fSDaniel Sanders return *(RegInfo->getRegClass(RC).begin() + RegNo); 5825c582b2fSDaniel Sanders } 5835c582b2fSDaniel Sanders 584b50ccf8eSDaniel Sanders template <typename InsnType> 585b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 586b50ccf8eSDaniel Sanders const void *Decoder) { 58779220eaeSEugene Zelenko using DecodeFN = DecodeStatus (*)(MCInst &, unsigned, uint64_t, const void *); 58879220eaeSEugene Zelenko 589b50ccf8eSDaniel Sanders // The size of the n field depends on the element size 590b50ccf8eSDaniel Sanders // The register class also depends on this. 591b50ccf8eSDaniel Sanders InsnType tmp = fieldFromInstruction(insn, 17, 5); 592b50ccf8eSDaniel Sanders unsigned NSize = 0; 593b50ccf8eSDaniel Sanders DecodeFN RegDecoder = nullptr; 594b50ccf8eSDaniel Sanders if ((tmp & 0x18) == 0x00) { // INSVE_B 595b50ccf8eSDaniel Sanders NSize = 4; 596b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128BRegisterClass; 597b50ccf8eSDaniel Sanders } else if ((tmp & 0x1c) == 0x10) { // INSVE_H 598b50ccf8eSDaniel Sanders NSize = 3; 599b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128HRegisterClass; 600b50ccf8eSDaniel Sanders } else if ((tmp & 0x1e) == 0x18) { // INSVE_W 601b50ccf8eSDaniel Sanders NSize = 2; 602b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128WRegisterClass; 603b50ccf8eSDaniel Sanders } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D 604b50ccf8eSDaniel Sanders NSize = 1; 605b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128DRegisterClass; 606b50ccf8eSDaniel Sanders } else 607b50ccf8eSDaniel Sanders llvm_unreachable("Invalid encoding"); 608b50ccf8eSDaniel Sanders 609b50ccf8eSDaniel Sanders assert(NSize != 0 && RegDecoder != nullptr); 610b50ccf8eSDaniel Sanders 611b50ccf8eSDaniel Sanders // $wd 612b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 6, 5); 613b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 614b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 615b50ccf8eSDaniel Sanders // $wd_in 616b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 617b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 618b50ccf8eSDaniel Sanders // $n 619b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 16, NSize); 620e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(tmp)); 621b50ccf8eSDaniel Sanders // $ws 622b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 11, 5); 623b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 624b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 625b50ccf8eSDaniel Sanders // $n2 626e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(0)); 627b50ccf8eSDaniel Sanders 628b50ccf8eSDaniel Sanders return MCDisassembler::Success; 629b50ccf8eSDaniel Sanders } 630b50ccf8eSDaniel Sanders 6315c582b2fSDaniel Sanders template <typename InsnType> 632cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address, 633cf060794SSimon Dardis const void *Decoder) { 634b3fd189cSSimon Dardis InsnType Rs = fieldFromInstruction(insn, 16, 5); 635cf060794SSimon Dardis InsnType Imm = fieldFromInstruction(insn, 0, 16); 636cf060794SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, 637b3fd189cSSimon Dardis Rs))); 638cf060794SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, 639b3fd189cSSimon Dardis Rs))); 640cf060794SSimon Dardis MI.addOperand(MCOperand::createImm(Imm)); 641cf060794SSimon Dardis 642cf060794SSimon Dardis return MCDisassembler::Success; 643cf060794SSimon Dardis } 644cf060794SSimon Dardis 645cf060794SSimon Dardis template <typename InsnType> 646cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address, 647cf060794SSimon Dardis const void *Decoder) { 648b3fd189cSSimon Dardis InsnType Rs = fieldFromInstruction(insn, 21, 5); 649cf060794SSimon Dardis InsnType Imm = fieldFromInstruction(insn, 0, 16); 650cf060794SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, 651b3fd189cSSimon Dardis Rs))); 652cf060794SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, 653b3fd189cSSimon Dardis Rs))); 654cf060794SSimon Dardis MI.addOperand(MCOperand::createImm(Imm)); 655cf060794SSimon Dardis 656cf060794SSimon Dardis return MCDisassembler::Success; 657cf060794SSimon Dardis } 658cf060794SSimon Dardis 659cf060794SSimon Dardis template <typename InsnType> 6605c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, 6615c582b2fSDaniel Sanders uint64_t Address, 6625c582b2fSDaniel Sanders const void *Decoder) { 6635c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6645c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 6655c582b2fSDaniel Sanders // ISA's instead). 6665c582b2fSDaniel Sanders // 6675c582b2fSDaniel Sanders // We have: 6685c582b2fSDaniel Sanders // 0b001000 sssss ttttt iiiiiiiiiiiiiiii 6695c582b2fSDaniel Sanders // BOVC if rs >= rt 6705c582b2fSDaniel Sanders // BEQZALC if rs == 0 && rt != 0 6715c582b2fSDaniel Sanders // BEQC if rs < rt && rs != 0 6725c582b2fSDaniel Sanders 6735c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6745c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 675672c710dSSagar Thakur int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 6765c582b2fSDaniel Sanders bool HasRs = false; 6775c582b2fSDaniel Sanders 6785c582b2fSDaniel Sanders if (Rs >= Rt) { 6795c582b2fSDaniel Sanders MI.setOpcode(Mips::BOVC); 6805c582b2fSDaniel Sanders HasRs = true; 6815c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 6825c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQC); 6835c582b2fSDaniel Sanders HasRs = true; 6845c582b2fSDaniel Sanders } else 6855c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQZALC); 6865c582b2fSDaniel Sanders 6875c582b2fSDaniel Sanders if (HasRs) 688e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 6895c582b2fSDaniel Sanders Rs))); 6905c582b2fSDaniel Sanders 691e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 6925c582b2fSDaniel Sanders Rt))); 693e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 6945c582b2fSDaniel Sanders 6955c582b2fSDaniel Sanders return MCDisassembler::Success; 6965c582b2fSDaniel Sanders } 6975c582b2fSDaniel Sanders 6985c582b2fSDaniel Sanders template <typename InsnType> 699c962c493SHrvoje Varga static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, 700c962c493SHrvoje Varga uint64_t Address, 701c962c493SHrvoje Varga const void *Decoder) { 702c962c493SHrvoje Varga InsnType Rt = fieldFromInstruction(insn, 21, 5); 703c962c493SHrvoje Varga InsnType Rs = fieldFromInstruction(insn, 16, 5); 704f0ed16eaSHrvoje Varga int64_t Imm = 0; 705c962c493SHrvoje Varga 706c962c493SHrvoje Varga if (Rs >= Rt) { 707c962c493SHrvoje Varga MI.setOpcode(Mips::BOVC_MMR6); 708c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 709c962c493SHrvoje Varga Rt))); 710c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 711c962c493SHrvoje Varga Rs))); 712f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 713c962c493SHrvoje Varga } else if (Rs != 0 && Rs < Rt) { 714c962c493SHrvoje Varga MI.setOpcode(Mips::BEQC_MMR6); 715c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 716c962c493SHrvoje Varga Rs))); 717c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 718c962c493SHrvoje Varga Rt))); 719f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 720c962c493SHrvoje Varga } else { 721c962c493SHrvoje Varga MI.setOpcode(Mips::BEQZALC_MMR6); 722c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 723c962c493SHrvoje Varga Rt))); 724f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 725c962c493SHrvoje Varga } 726c962c493SHrvoje Varga 727c962c493SHrvoje Varga MI.addOperand(MCOperand::createImm(Imm)); 728c962c493SHrvoje Varga 729c962c493SHrvoje Varga return MCDisassembler::Success; 730c962c493SHrvoje Varga } 731c962c493SHrvoje Varga 732c962c493SHrvoje Varga template <typename InsnType> 7335c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, 7345c582b2fSDaniel Sanders uint64_t Address, 7355c582b2fSDaniel Sanders const void *Decoder) { 7365c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 7375c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 7385c582b2fSDaniel Sanders // ISA's instead). 7395c582b2fSDaniel Sanders // 7405c582b2fSDaniel Sanders // We have: 7415c582b2fSDaniel Sanders // 0b011000 sssss ttttt iiiiiiiiiiiiiiii 7425c582b2fSDaniel Sanders // BNVC if rs >= rt 7435c582b2fSDaniel Sanders // BNEZALC if rs == 0 && rt != 0 7445c582b2fSDaniel Sanders // BNEC if rs < rt && rs != 0 7455c582b2fSDaniel Sanders 7465c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 7475c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 748672c710dSSagar Thakur int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 7495c582b2fSDaniel Sanders bool HasRs = false; 7505c582b2fSDaniel Sanders 7515c582b2fSDaniel Sanders if (Rs >= Rt) { 7525c582b2fSDaniel Sanders MI.setOpcode(Mips::BNVC); 7535c582b2fSDaniel Sanders HasRs = true; 7545c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 7555c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEC); 7565c582b2fSDaniel Sanders HasRs = true; 7575c582b2fSDaniel Sanders } else 7585c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEZALC); 7595c582b2fSDaniel Sanders 7605c582b2fSDaniel Sanders if (HasRs) 761e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 7625c582b2fSDaniel Sanders Rs))); 7635c582b2fSDaniel Sanders 764e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 7655c582b2fSDaniel Sanders Rt))); 766e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 7675c582b2fSDaniel Sanders 7685c582b2fSDaniel Sanders return MCDisassembler::Success; 7695c582b2fSDaniel Sanders } 7705c582b2fSDaniel Sanders 7715c582b2fSDaniel Sanders template <typename InsnType> 772c962c493SHrvoje Varga static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, 773c962c493SHrvoje Varga uint64_t Address, 774c962c493SHrvoje Varga const void *Decoder) { 775c962c493SHrvoje Varga InsnType Rt = fieldFromInstruction(insn, 21, 5); 776c962c493SHrvoje Varga InsnType Rs = fieldFromInstruction(insn, 16, 5); 777f0ed16eaSHrvoje Varga int64_t Imm = 0; 778c962c493SHrvoje Varga 779c962c493SHrvoje Varga if (Rs >= Rt) { 780c962c493SHrvoje Varga MI.setOpcode(Mips::BNVC_MMR6); 781c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 782c962c493SHrvoje Varga Rt))); 783c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 784c962c493SHrvoje Varga Rs))); 785f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 786c962c493SHrvoje Varga } else if (Rs != 0 && Rs < Rt) { 787c962c493SHrvoje Varga MI.setOpcode(Mips::BNEC_MMR6); 788c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 789c962c493SHrvoje Varga Rs))); 790c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 791c962c493SHrvoje Varga Rt))); 792f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 793c962c493SHrvoje Varga } else { 794c962c493SHrvoje Varga MI.setOpcode(Mips::BNEZALC_MMR6); 795c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 796c962c493SHrvoje Varga Rt))); 797f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 798c962c493SHrvoje Varga } 799c962c493SHrvoje Varga 800c962c493SHrvoje Varga MI.addOperand(MCOperand::createImm(Imm)); 801c962c493SHrvoje Varga 802c962c493SHrvoje Varga return MCDisassembler::Success; 803c962c493SHrvoje Varga } 804c962c493SHrvoje Varga 805c962c493SHrvoje Varga template <typename InsnType> 806f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, 807f0ed16eaSHrvoje Varga uint64_t Address, 808f0ed16eaSHrvoje Varga const void *Decoder) { 809f0ed16eaSHrvoje Varga // We have: 810f0ed16eaSHrvoje Varga // 0b110101 ttttt sssss iiiiiiiiiiiiiiii 811f0ed16eaSHrvoje Varga // Invalid if rt == 0 812f0ed16eaSHrvoje Varga // BGTZC_MMR6 if rs == 0 && rt != 0 813f0ed16eaSHrvoje Varga // BLTZC_MMR6 if rs == rt && rt != 0 814f0ed16eaSHrvoje Varga // BLTC_MMR6 if rs != rt && rs != 0 && rt != 0 815f0ed16eaSHrvoje Varga 816f0ed16eaSHrvoje Varga InsnType Rt = fieldFromInstruction(insn, 21, 5); 817f0ed16eaSHrvoje Varga InsnType Rs = fieldFromInstruction(insn, 16, 5); 818f0ed16eaSHrvoje Varga int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 819f0ed16eaSHrvoje Varga bool HasRs = false; 820f0ed16eaSHrvoje Varga 821f0ed16eaSHrvoje Varga if (Rt == 0) 822f0ed16eaSHrvoje Varga return MCDisassembler::Fail; 823f0ed16eaSHrvoje Varga else if (Rs == 0) 824f0ed16eaSHrvoje Varga MI.setOpcode(Mips::BGTZC_MMR6); 825f0ed16eaSHrvoje Varga else if (Rs == Rt) 826f0ed16eaSHrvoje Varga MI.setOpcode(Mips::BLTZC_MMR6); 827f0ed16eaSHrvoje Varga else { 828f0ed16eaSHrvoje Varga MI.setOpcode(Mips::BLTC_MMR6); 829f0ed16eaSHrvoje Varga HasRs = true; 830f0ed16eaSHrvoje Varga } 831f0ed16eaSHrvoje Varga 832f0ed16eaSHrvoje Varga if (HasRs) 833f0ed16eaSHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 834f0ed16eaSHrvoje Varga Rs))); 835f0ed16eaSHrvoje Varga 836f0ed16eaSHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 837f0ed16eaSHrvoje Varga Rt))); 838f0ed16eaSHrvoje Varga 839f0ed16eaSHrvoje Varga MI.addOperand(MCOperand::createImm(Imm)); 840f0ed16eaSHrvoje Varga 841f0ed16eaSHrvoje Varga return MCDisassembler::Success; 842f0ed16eaSHrvoje Varga } 843f0ed16eaSHrvoje Varga 844f0ed16eaSHrvoje Varga template <typename InsnType> 845f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, 846f0ed16eaSHrvoje Varga uint64_t Address, 847f0ed16eaSHrvoje Varga const void *Decoder) { 848f0ed16eaSHrvoje Varga // We have: 849f0ed16eaSHrvoje Varga // 0b111101 ttttt sssss iiiiiiiiiiiiiiii 850f0ed16eaSHrvoje Varga // Invalid if rt == 0 851f0ed16eaSHrvoje Varga // BLEZC_MMR6 if rs == 0 && rt != 0 852f0ed16eaSHrvoje Varga // BGEZC_MMR6 if rs == rt && rt != 0 853f0ed16eaSHrvoje Varga // BGEC_MMR6 if rs != rt && rs != 0 && rt != 0 854f0ed16eaSHrvoje Varga 855f0ed16eaSHrvoje Varga InsnType Rt = fieldFromInstruction(insn, 21, 5); 856f0ed16eaSHrvoje Varga InsnType Rs = fieldFromInstruction(insn, 16, 5); 857f0ed16eaSHrvoje Varga int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 858f0ed16eaSHrvoje Varga bool HasRs = false; 859f0ed16eaSHrvoje Varga 860f0ed16eaSHrvoje Varga if (Rt == 0) 861f0ed16eaSHrvoje Varga return MCDisassembler::Fail; 862f0ed16eaSHrvoje Varga else if (Rs == 0) 863f0ed16eaSHrvoje Varga MI.setOpcode(Mips::BLEZC_MMR6); 864f0ed16eaSHrvoje Varga else if (Rs == Rt) 865f0ed16eaSHrvoje Varga MI.setOpcode(Mips::BGEZC_MMR6); 866f0ed16eaSHrvoje Varga else { 867f0ed16eaSHrvoje Varga HasRs = true; 868f0ed16eaSHrvoje Varga MI.setOpcode(Mips::BGEC_MMR6); 869f0ed16eaSHrvoje Varga } 870f0ed16eaSHrvoje Varga 871f0ed16eaSHrvoje Varga if (HasRs) 872f0ed16eaSHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 873f0ed16eaSHrvoje Varga Rs))); 874f0ed16eaSHrvoje Varga 875f0ed16eaSHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 876f0ed16eaSHrvoje Varga Rt))); 877f0ed16eaSHrvoje Varga 878f0ed16eaSHrvoje Varga MI.addOperand(MCOperand::createImm(Imm)); 879f0ed16eaSHrvoje Varga 880f0ed16eaSHrvoje Varga return MCDisassembler::Success; 881f0ed16eaSHrvoje Varga } 882f0ed16eaSHrvoje Varga 883f0ed16eaSHrvoje Varga template <typename InsnType> 8845c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, 8855c582b2fSDaniel Sanders uint64_t Address, 8865c582b2fSDaniel Sanders const void *Decoder) { 8875c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 8885c582b2fSDaniel Sanders // (otherwise we would have matched the BLEZL instruction from the earlier 8895c582b2fSDaniel Sanders // ISA's instead). 8905c582b2fSDaniel Sanders // 8915c582b2fSDaniel Sanders // We have: 8925c582b2fSDaniel Sanders // 0b010110 sssss ttttt iiiiiiiiiiiiiiii 8935c582b2fSDaniel Sanders // Invalid if rs == 0 8945c582b2fSDaniel Sanders // BLEZC if rs == 0 && rt != 0 8955c582b2fSDaniel Sanders // BGEZC if rs == rt && rt != 0 8965c582b2fSDaniel Sanders // BGEC if rs != rt && rs != 0 && rt != 0 8975c582b2fSDaniel Sanders 8985c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 8995c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 900672c710dSSagar Thakur int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 90128a0ca07SZoran Jovanovic bool HasRs = false; 9025c582b2fSDaniel Sanders 9035c582b2fSDaniel Sanders if (Rt == 0) 9045c582b2fSDaniel Sanders return MCDisassembler::Fail; 9055c582b2fSDaniel Sanders else if (Rs == 0) 9065c582b2fSDaniel Sanders MI.setOpcode(Mips::BLEZC); 9075c582b2fSDaniel Sanders else if (Rs == Rt) 9085c582b2fSDaniel Sanders MI.setOpcode(Mips::BGEZC); 90928a0ca07SZoran Jovanovic else { 91028a0ca07SZoran Jovanovic HasRs = true; 91128a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEC); 91228a0ca07SZoran Jovanovic } 91328a0ca07SZoran Jovanovic 91428a0ca07SZoran Jovanovic if (HasRs) 915e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 91628a0ca07SZoran Jovanovic Rs))); 9175c582b2fSDaniel Sanders 918e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 9195c582b2fSDaniel Sanders Rt))); 9205c582b2fSDaniel Sanders 921e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 9225c582b2fSDaniel Sanders 9235c582b2fSDaniel Sanders return MCDisassembler::Success; 9245c582b2fSDaniel Sanders } 9255c582b2fSDaniel Sanders 9265c582b2fSDaniel Sanders template <typename InsnType> 9275c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, 9285c582b2fSDaniel Sanders uint64_t Address, 9295c582b2fSDaniel Sanders const void *Decoder) { 9305c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 9315c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZL instruction from the earlier 9325c582b2fSDaniel Sanders // ISA's instead). 9335c582b2fSDaniel Sanders // 9345c582b2fSDaniel Sanders // We have: 9355c582b2fSDaniel Sanders // 0b010111 sssss ttttt iiiiiiiiiiiiiiii 9365c582b2fSDaniel Sanders // Invalid if rs == 0 9375c582b2fSDaniel Sanders // BGTZC if rs == 0 && rt != 0 9385c582b2fSDaniel Sanders // BLTZC if rs == rt && rt != 0 9395c582b2fSDaniel Sanders // BLTC if rs != rt && rs != 0 && rt != 0 9405c582b2fSDaniel Sanders 9415c14b069SZoran Jovanovic bool HasRs = false; 9425c14b069SZoran Jovanovic 9435c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 9445c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 945672c710dSSagar Thakur int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 9465c582b2fSDaniel Sanders 9475c582b2fSDaniel Sanders if (Rt == 0) 9485c582b2fSDaniel Sanders return MCDisassembler::Fail; 9495c582b2fSDaniel Sanders else if (Rs == 0) 9505c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZC); 9515c582b2fSDaniel Sanders else if (Rs == Rt) 9525c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZC); 9535c14b069SZoran Jovanovic else { 9545c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTC); 9555c14b069SZoran Jovanovic HasRs = true; 9565c14b069SZoran Jovanovic } 9575c14b069SZoran Jovanovic 9585c14b069SZoran Jovanovic if (HasRs) 959e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 9605c14b069SZoran Jovanovic Rs))); 9615c582b2fSDaniel Sanders 962e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 9635c582b2fSDaniel Sanders Rt))); 9645c582b2fSDaniel Sanders 965e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 9665c582b2fSDaniel Sanders 9675c582b2fSDaniel Sanders return MCDisassembler::Success; 9685c582b2fSDaniel Sanders } 9695c582b2fSDaniel Sanders 9705c582b2fSDaniel Sanders template <typename InsnType> 9715c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, 9725c582b2fSDaniel Sanders uint64_t Address, 9735c582b2fSDaniel Sanders const void *Decoder) { 9745c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 9755c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZ instruction from the earlier 9765c582b2fSDaniel Sanders // ISA's instead). 9775c582b2fSDaniel Sanders // 9785c582b2fSDaniel Sanders // We have: 9795c582b2fSDaniel Sanders // 0b000111 sssss ttttt iiiiiiiiiiiiiiii 9805c582b2fSDaniel Sanders // BGTZ if rt == 0 9815c582b2fSDaniel Sanders // BGTZALC if rs == 0 && rt != 0 9825c582b2fSDaniel Sanders // BLTZALC if rs != 0 && rs == rt 9835c582b2fSDaniel Sanders // BLTUC if rs != 0 && rs != rt 9845c582b2fSDaniel Sanders 9855c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 9865c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 987672c710dSSagar Thakur int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 9885c582b2fSDaniel Sanders bool HasRs = false; 9895c582b2fSDaniel Sanders bool HasRt = false; 9905c582b2fSDaniel Sanders 9915c582b2fSDaniel Sanders if (Rt == 0) { 9925c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZ); 9935c582b2fSDaniel Sanders HasRs = true; 9945c582b2fSDaniel Sanders } else if (Rs == 0) { 9955c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZALC); 9965c582b2fSDaniel Sanders HasRt = true; 9975c582b2fSDaniel Sanders } else if (Rs == Rt) { 9985c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZALC); 9995c582b2fSDaniel Sanders HasRs = true; 10005c14b069SZoran Jovanovic } else { 10015c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTUC); 10025c14b069SZoran Jovanovic HasRs = true; 10035c14b069SZoran Jovanovic HasRt = true; 10045c14b069SZoran Jovanovic } 10055c582b2fSDaniel Sanders 10065c582b2fSDaniel Sanders if (HasRs) 1007e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 10085c582b2fSDaniel Sanders Rs))); 10095c582b2fSDaniel Sanders 10105c582b2fSDaniel Sanders if (HasRt) 1011e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 10125c582b2fSDaniel Sanders Rt))); 10135c582b2fSDaniel Sanders 1014e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 10155c582b2fSDaniel Sanders 10165c582b2fSDaniel Sanders return MCDisassembler::Success; 10175c582b2fSDaniel Sanders } 10185c582b2fSDaniel Sanders 101928a0ca07SZoran Jovanovic template <typename InsnType> 102028a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn, 102128a0ca07SZoran Jovanovic uint64_t Address, 102228a0ca07SZoran Jovanovic const void *Decoder) { 102328a0ca07SZoran Jovanovic // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 102428a0ca07SZoran Jovanovic // (otherwise we would have matched the BLEZL instruction from the earlier 102528a0ca07SZoran Jovanovic // ISA's instead). 102628a0ca07SZoran Jovanovic // 102728a0ca07SZoran Jovanovic // We have: 102828a0ca07SZoran Jovanovic // 0b000110 sssss ttttt iiiiiiiiiiiiiiii 102928a0ca07SZoran Jovanovic // Invalid if rs == 0 103028a0ca07SZoran Jovanovic // BLEZALC if rs == 0 && rt != 0 103128a0ca07SZoran Jovanovic // BGEZALC if rs == rt && rt != 0 103228a0ca07SZoran Jovanovic // BGEUC if rs != rt && rs != 0 && rt != 0 103328a0ca07SZoran Jovanovic 103428a0ca07SZoran Jovanovic InsnType Rs = fieldFromInstruction(insn, 21, 5); 103528a0ca07SZoran Jovanovic InsnType Rt = fieldFromInstruction(insn, 16, 5); 1036672c710dSSagar Thakur int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 103728a0ca07SZoran Jovanovic bool HasRs = false; 103828a0ca07SZoran Jovanovic 103928a0ca07SZoran Jovanovic if (Rt == 0) 104028a0ca07SZoran Jovanovic return MCDisassembler::Fail; 104128a0ca07SZoran Jovanovic else if (Rs == 0) 104228a0ca07SZoran Jovanovic MI.setOpcode(Mips::BLEZALC); 104328a0ca07SZoran Jovanovic else if (Rs == Rt) 104428a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEZALC); 104528a0ca07SZoran Jovanovic else { 104628a0ca07SZoran Jovanovic HasRs = true; 104728a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEUC); 104828a0ca07SZoran Jovanovic } 104928a0ca07SZoran Jovanovic 105028a0ca07SZoran Jovanovic if (HasRs) 1051e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 105228a0ca07SZoran Jovanovic Rs))); 1053e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 105428a0ca07SZoran Jovanovic Rt))); 105528a0ca07SZoran Jovanovic 1056e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 105728a0ca07SZoran Jovanovic 105828a0ca07SZoran Jovanovic return MCDisassembler::Success; 105928a0ca07SZoran Jovanovic } 106028a0ca07SZoran Jovanovic 106155e44673SSimon Dardis // Override the generated disassembler to produce DEXT all the time. This is 106255e44673SSimon Dardis // for feature / behaviour parity with binutils. 106355e44673SSimon Dardis template <typename InsnType> 106455e44673SSimon Dardis static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address, 106555e44673SSimon Dardis const void *Decoder) { 106655e44673SSimon Dardis unsigned Msbd = fieldFromInstruction(Insn, 11, 5); 106755e44673SSimon Dardis unsigned Lsb = fieldFromInstruction(Insn, 6, 5); 106855e44673SSimon Dardis unsigned Size = 0; 106955e44673SSimon Dardis unsigned Pos = 0; 107055e44673SSimon Dardis 107155e44673SSimon Dardis switch (MI.getOpcode()) { 107255e44673SSimon Dardis case Mips::DEXT: 107355e44673SSimon Dardis Pos = Lsb; 107455e44673SSimon Dardis Size = Msbd + 1; 107555e44673SSimon Dardis break; 107655e44673SSimon Dardis case Mips::DEXTM: 107755e44673SSimon Dardis Pos = Lsb; 107855e44673SSimon Dardis Size = Msbd + 1 + 32; 107955e44673SSimon Dardis break; 108055e44673SSimon Dardis case Mips::DEXTU: 108155e44673SSimon Dardis Pos = Lsb + 32; 108255e44673SSimon Dardis Size = Msbd + 1; 108355e44673SSimon Dardis break; 108455e44673SSimon Dardis default: 108555e44673SSimon Dardis llvm_unreachable("Unknown DEXT instruction!"); 108655e44673SSimon Dardis } 108755e44673SSimon Dardis 1088d6dada17SAleksandar Beserminji MI.setOpcode(Mips::DEXT); 108955e44673SSimon Dardis 109055e44673SSimon Dardis InsnType Rs = fieldFromInstruction(Insn, 21, 5); 109155e44673SSimon Dardis InsnType Rt = fieldFromInstruction(Insn, 16, 5); 109255e44673SSimon Dardis 109355e44673SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt))); 109455e44673SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs))); 109555e44673SSimon Dardis MI.addOperand(MCOperand::createImm(Pos)); 109655e44673SSimon Dardis MI.addOperand(MCOperand::createImm(Size)); 109755e44673SSimon Dardis 109855e44673SSimon Dardis return MCDisassembler::Success; 109955e44673SSimon Dardis } 110055e44673SSimon Dardis 11016f83ae38SSimon Dardis // Override the generated disassembler to produce DINS all the time. This is 11026f83ae38SSimon Dardis // for feature / behaviour parity with binutils. 11036f83ae38SSimon Dardis template <typename InsnType> 11046f83ae38SSimon Dardis static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address, 11056f83ae38SSimon Dardis const void *Decoder) { 11066f83ae38SSimon Dardis unsigned Msbd = fieldFromInstruction(Insn, 11, 5); 11076f83ae38SSimon Dardis unsigned Lsb = fieldFromInstruction(Insn, 6, 5); 11086f83ae38SSimon Dardis unsigned Size = 0; 11096f83ae38SSimon Dardis unsigned Pos = 0; 11106f83ae38SSimon Dardis 11116f83ae38SSimon Dardis switch (MI.getOpcode()) { 11126f83ae38SSimon Dardis case Mips::DINS: 11136f83ae38SSimon Dardis Pos = Lsb; 11146f83ae38SSimon Dardis Size = Msbd + 1 - Pos; 11156f83ae38SSimon Dardis break; 11166f83ae38SSimon Dardis case Mips::DINSM: 11176f83ae38SSimon Dardis Pos = Lsb; 11186f83ae38SSimon Dardis Size = Msbd + 33 - Pos; 11196f83ae38SSimon Dardis break; 11206f83ae38SSimon Dardis case Mips::DINSU: 11216f83ae38SSimon Dardis Pos = Lsb + 32; 11226f83ae38SSimon Dardis // mbsd = pos + size - 33 11236f83ae38SSimon Dardis // mbsd - pos + 33 = size 11246f83ae38SSimon Dardis Size = Msbd + 33 - Pos; 11256f83ae38SSimon Dardis break; 11266f83ae38SSimon Dardis default: 11276f83ae38SSimon Dardis llvm_unreachable("Unknown DINS instruction!"); 11286f83ae38SSimon Dardis } 11296f83ae38SSimon Dardis 11306f83ae38SSimon Dardis InsnType Rs = fieldFromInstruction(Insn, 21, 5); 11316f83ae38SSimon Dardis InsnType Rt = fieldFromInstruction(Insn, 16, 5); 11326f83ae38SSimon Dardis 1133d6dada17SAleksandar Beserminji MI.setOpcode(Mips::DINS); 11346f83ae38SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt))); 11356f83ae38SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs))); 11366f83ae38SSimon Dardis MI.addOperand(MCOperand::createImm(Pos)); 11376f83ae38SSimon Dardis MI.addOperand(MCOperand::createImm(Size)); 11386f83ae38SSimon Dardis 11396f83ae38SSimon Dardis return MCDisassembler::Success; 11406f83ae38SSimon Dardis } 11413408caf6SPetar Jovanovic 11423408caf6SPetar Jovanovic // Auto-generated decoder wouldn't add the third operand for CRC32*. 11433408caf6SPetar Jovanovic template <typename InsnType> 11443408caf6SPetar Jovanovic static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address, 11453408caf6SPetar Jovanovic const void *Decoder) { 11463408caf6SPetar Jovanovic InsnType Rs = fieldFromInstruction(Insn, 21, 5); 11473408caf6SPetar Jovanovic InsnType Rt = fieldFromInstruction(Insn, 16, 5); 11483408caf6SPetar Jovanovic MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 11493408caf6SPetar Jovanovic Rt))); 11503408caf6SPetar Jovanovic MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 11513408caf6SPetar Jovanovic Rs))); 11523408caf6SPetar Jovanovic MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 11533408caf6SPetar Jovanovic Rt))); 11543408caf6SPetar Jovanovic return MCDisassembler::Success; 11553408caf6SPetar Jovanovic } 11563408caf6SPetar Jovanovic 1157ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted 1158dcd84335SSimon Pilgrim /// according to the given endianness. 1159ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 1160ea22c4cfSJozef Kolek uint64_t &Size, uint32_t &Insn, 1161ea22c4cfSJozef Kolek bool IsBigEndian) { 1162ea22c4cfSJozef Kolek // We want to read exactly 2 Bytes of data. 1163ea22c4cfSJozef Kolek if (Bytes.size() < 2) { 1164ea22c4cfSJozef Kolek Size = 0; 1165ea22c4cfSJozef Kolek return MCDisassembler::Fail; 1166ea22c4cfSJozef Kolek } 1167ea22c4cfSJozef Kolek 1168ea22c4cfSJozef Kolek if (IsBigEndian) { 1169ea22c4cfSJozef Kolek Insn = (Bytes[0] << 8) | Bytes[1]; 1170ea22c4cfSJozef Kolek } else { 1171ea22c4cfSJozef Kolek Insn = (Bytes[1] << 8) | Bytes[0]; 1172ea22c4cfSJozef Kolek } 1173ea22c4cfSJozef Kolek 1174ea22c4cfSJozef Kolek return MCDisassembler::Success; 1175ea22c4cfSJozef Kolek } 1176ea22c4cfSJozef Kolek 11777fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted 1178dcd84335SSimon Pilgrim /// according to the given endianness. 11797fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 11807fc5b874SRafael Espindola uint64_t &Size, uint32_t &Insn, 11817fc5b874SRafael Espindola bool IsBigEndian, bool IsMicroMips) { 118271928e68SAkira Hatanaka // We want to read exactly 4 Bytes of data. 11837fc5b874SRafael Espindola if (Bytes.size() < 4) { 11844aa6bea7SRafael Espindola Size = 0; 118571928e68SAkira Hatanaka return MCDisassembler::Fail; 118671928e68SAkira Hatanaka } 118771928e68SAkira Hatanaka 1188ea22c4cfSJozef Kolek // High 16 bits of a 32-bit microMIPS instruction (where the opcode is) 1189ea22c4cfSJozef Kolek // always precede the low 16 bits in the instruction stream (that is, they 1190ea22c4cfSJozef Kolek // are placed at lower addresses in the instruction stream). 1191ea22c4cfSJozef Kolek // 1192ea22c4cfSJozef Kolek // microMIPS byte ordering: 1193ea22c4cfSJozef Kolek // Big-endian: 0 | 1 | 2 | 3 1194ea22c4cfSJozef Kolek // Little-endian: 1 | 0 | 3 | 2 1195ea22c4cfSJozef Kolek 11964aa6bea7SRafael Espindola if (IsBigEndian) { 119771928e68SAkira Hatanaka // Encoded as a big-endian 32-bit word in the stream. 11984aa6bea7SRafael Espindola Insn = 11994aa6bea7SRafael Espindola (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24); 12004aa6bea7SRafael Espindola } else { 1201dde3d582SVladimir Medic if (IsMicroMips) { 12024aa6bea7SRafael Espindola Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) | 1203dde3d582SVladimir Medic (Bytes[1] << 24); 1204dde3d582SVladimir Medic } else { 12054aa6bea7SRafael Espindola Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | 120671928e68SAkira Hatanaka (Bytes[3] << 24); 120771928e68SAkira Hatanaka } 1208dde3d582SVladimir Medic } 120971928e68SAkira Hatanaka 121071928e68SAkira Hatanaka return MCDisassembler::Success; 121171928e68SAkira Hatanaka } 121271928e68SAkira Hatanaka 12134aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 12147fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 121571928e68SAkira Hatanaka uint64_t Address, 12164aa6bea7SRafael Espindola raw_ostream &VStream, 12174aa6bea7SRafael Espindola raw_ostream &CStream) const { 121871928e68SAkira Hatanaka uint32_t Insn; 1219ea22c4cfSJozef Kolek DecodeStatus Result; 1220a5f52dc0SSimon Dardis Size = 0; 122171928e68SAkira Hatanaka 1222ea22c4cfSJozef Kolek if (IsMicroMips) { 1223ea22c4cfSJozef Kolek Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); 1224ebee6129SReid Kleckner if (Result == MCDisassembler::Fail) 1225ebee6129SReid Kleckner return MCDisassembler::Fail; 1226ea22c4cfSJozef Kolek 1227ada70918SZoran Jovanovic if (hasMips32r6()) { 1228*d34e60caSNicola Zaghen LLVM_DEBUG( 1229*d34e60caSNicola Zaghen dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n"); 1230ada70918SZoran Jovanovic // Calling the auto-generated decoder function for microMIPS32R6 1231d6dada17SAleksandar Beserminji // 16-bit instructions. 1232ada70918SZoran Jovanovic Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn, 1233ada70918SZoran Jovanovic Address, this, STI); 1234ada70918SZoran Jovanovic if (Result != MCDisassembler::Fail) { 1235ada70918SZoran Jovanovic Size = 2; 1236ada70918SZoran Jovanovic return Result; 1237ada70918SZoran Jovanovic } 1238ada70918SZoran Jovanovic } 1239ada70918SZoran Jovanovic 1240*d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n"); 1241ada70918SZoran Jovanovic // Calling the auto-generated decoder function for microMIPS 16-bit 1242ada70918SZoran Jovanovic // instructions. 1243ea22c4cfSJozef Kolek Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address, 1244ea22c4cfSJozef Kolek this, STI); 1245ea22c4cfSJozef Kolek if (Result != MCDisassembler::Fail) { 1246ea22c4cfSJozef Kolek Size = 2; 1247ea22c4cfSJozef Kolek return Result; 1248ea22c4cfSJozef Kolek } 1249ea22c4cfSJozef Kolek 1250ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true); 125171928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 125271928e68SAkira Hatanaka return MCDisassembler::Fail; 125371928e68SAkira Hatanaka 1254676d6012SJozef Kolek if (hasMips32r6()) { 1255*d34e60caSNicola Zaghen LLVM_DEBUG( 1256*d34e60caSNicola Zaghen dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n"); 1257676d6012SJozef Kolek // Calling the auto-generated decoder function. 1258366783e1SZoran Jovanovic Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address, 1259676d6012SJozef Kolek this, STI); 1260ada70918SZoran Jovanovic if (Result != MCDisassembler::Fail) { 1261ada70918SZoran Jovanovic Size = 4; 1262ada70918SZoran Jovanovic return Result; 1263ada70918SZoran Jovanovic } 1264ada70918SZoran Jovanovic } 1265ada70918SZoran Jovanovic 1266*d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); 1267dde3d582SVladimir Medic // Calling the auto-generated decoder function. 12684aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, 1269dde3d582SVladimir Medic this, STI); 1270dde3d582SVladimir Medic if (Result != MCDisassembler::Fail) { 1271dde3d582SVladimir Medic Size = 4; 1272dde3d582SVladimir Medic return Result; 1273dde3d582SVladimir Medic } 12742cb74ac3SHrvoje Varga 127551a7ae2aSSimon Dardis if (isFP64()) { 1276*d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n"); 127751a7ae2aSSimon Dardis Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn, 12782cb74ac3SHrvoje Varga Address, this, STI); 12792cb74ac3SHrvoje Varga if (Result != MCDisassembler::Fail) { 12802cb74ac3SHrvoje Varga Size = 4; 12812cb74ac3SHrvoje Varga return Result; 12822cb74ac3SHrvoje Varga } 12832cb74ac3SHrvoje Varga } 12842cb74ac3SHrvoje Varga 1285a5f52dc0SSimon Dardis // This is an invalid instruction. Claim that the Size is 2 bytes. Since 1286a5f52dc0SSimon Dardis // microMIPS instructions have a minimum alignment of 2, the next 2 bytes 1287a5f52dc0SSimon Dardis // could form a valid instruction. The two bytes we rejected as an 1288a5f52dc0SSimon Dardis // instruction could have actually beeen an inline constant pool that is 1289a5f52dc0SSimon Dardis // unconditionally branched over. 1290ebee6129SReid Kleckner Size = 2; 1291dde3d582SVladimir Medic return MCDisassembler::Fail; 1292dde3d582SVladimir Medic } 1293dde3d582SVladimir Medic 1294a5f52dc0SSimon Dardis // Attempt to read the instruction so that we can attempt to decode it. If 1295a5f52dc0SSimon Dardis // the buffer is not 4 bytes long, let the higher level logic figure out 1296a5f52dc0SSimon Dardis // what to do with a size of zero and MCDisassembler::Fail. 1297ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); 1298a5f52dc0SSimon Dardis if (Result == MCDisassembler::Fail) 1299ea22c4cfSJozef Kolek return MCDisassembler::Fail; 1300a5f52dc0SSimon Dardis 1301a5f52dc0SSimon Dardis // The only instruction size for standard encoded MIPS. 1302a5f52dc0SSimon Dardis Size = 4; 1303ea22c4cfSJozef Kolek 1304c171f65aSDaniel Sanders if (hasCOP3()) { 1305*d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n"); 1306c171f65aSDaniel Sanders Result = 13074aa6bea7SRafael Espindola decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI); 1308a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 1309c171f65aSDaniel Sanders return Result; 1310c171f65aSDaniel Sanders } 1311c171f65aSDaniel Sanders 1312c171f65aSDaniel Sanders if (hasMips32r6() && isGP64()) { 1313*d34e60caSNicola Zaghen LLVM_DEBUG( 1314*d34e60caSNicola Zaghen dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n"); 131536901dd1SVasileios Kalintiris Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn, 131636901dd1SVasileios Kalintiris Address, this, STI); 1317a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 13180fa60416SDaniel Sanders return Result; 13190fa60416SDaniel Sanders } 13200fa60416SDaniel Sanders 13214fbf76f7SSimon Dardis if (hasMips32r6() && isPTR64()) { 1322*d34e60caSNicola Zaghen LLVM_DEBUG( 1323*d34e60caSNicola Zaghen dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n"); 13244fbf76f7SSimon Dardis Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn, 13254fbf76f7SSimon Dardis Address, this, STI); 1326a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 13274fbf76f7SSimon Dardis return Result; 13284fbf76f7SSimon Dardis } 13294fbf76f7SSimon Dardis 1330c171f65aSDaniel Sanders if (hasMips32r6()) { 1331*d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n"); 13324aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn, 13335c582b2fSDaniel Sanders Address, this, STI); 1334a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 13355c582b2fSDaniel Sanders return Result; 13365c582b2fSDaniel Sanders } 13375c582b2fSDaniel Sanders 13384fbf76f7SSimon Dardis if (hasMips2() && isPTR64()) { 1339*d34e60caSNicola Zaghen LLVM_DEBUG( 1340*d34e60caSNicola Zaghen dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n"); 13414fbf76f7SSimon Dardis Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn, 13424fbf76f7SSimon Dardis Address, this, STI); 1343a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 13444fbf76f7SSimon Dardis return Result; 13454fbf76f7SSimon Dardis } 13464fbf76f7SSimon Dardis 13473adf9b8dSKai Nacke if (hasCnMips()) { 1348*d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n"); 13493adf9b8dSKai Nacke Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn, 13503adf9b8dSKai Nacke Address, this, STI); 1351a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 13523adf9b8dSKai Nacke return Result; 13533adf9b8dSKai Nacke } 13543adf9b8dSKai Nacke 1355a19216c8SDaniel Sanders if (isGP64()) { 1356*d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n"); 1357a19216c8SDaniel Sanders Result = decodeInstruction(DecoderTableMips6432, Instr, Insn, 1358a19216c8SDaniel Sanders Address, this, STI); 1359a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 1360a19216c8SDaniel Sanders return Result; 1361a19216c8SDaniel Sanders } 1362a19216c8SDaniel Sanders 136351a7ae2aSSimon Dardis if (isFP64()) { 1364*d34e60caSNicola Zaghen LLVM_DEBUG( 1365*d34e60caSNicola Zaghen dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n"); 136651a7ae2aSSimon Dardis Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn, 136751a7ae2aSSimon Dardis Address, this, STI); 136851a7ae2aSSimon Dardis if (Result != MCDisassembler::Fail) 136951a7ae2aSSimon Dardis return Result; 137051a7ae2aSSimon Dardis } 137151a7ae2aSSimon Dardis 1372*d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n"); 137371928e68SAkira Hatanaka // Calling the auto-generated decoder function. 13744aa6bea7SRafael Espindola Result = 13754aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI); 1376a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 137771928e68SAkira Hatanaka return Result; 137871928e68SAkira Hatanaka 137971928e68SAkira Hatanaka return MCDisassembler::Fail; 138071928e68SAkira Hatanaka } 138171928e68SAkira Hatanaka 1382ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 1383ec8a5490SReed Kotler unsigned RegNo, 1384ec8a5490SReed Kotler uint64_t Address, 1385ec8a5490SReed Kotler const void *Decoder) { 1386ec8a5490SReed Kotler return MCDisassembler::Fail; 1387ec8a5490SReed Kotler } 1388ec8a5490SReed Kotler 138913e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 139071928e68SAkira Hatanaka unsigned RegNo, 139171928e68SAkira Hatanaka uint64_t Address, 139271928e68SAkira Hatanaka const void *Decoder) { 139371928e68SAkira Hatanaka if (RegNo > 31) 139471928e68SAkira Hatanaka return MCDisassembler::Fail; 139571928e68SAkira Hatanaka 139613e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); 1397e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 139871928e68SAkira Hatanaka return MCDisassembler::Success; 139971928e68SAkira Hatanaka } 140071928e68SAkira Hatanaka 1401b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, 1402b0852e54SZoran Jovanovic unsigned RegNo, 1403b0852e54SZoran Jovanovic uint64_t Address, 1404b0852e54SZoran Jovanovic const void *Decoder) { 1405ea22c4cfSJozef Kolek if (RegNo > 7) 1406b0852e54SZoran Jovanovic return MCDisassembler::Fail; 1407ea22c4cfSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo); 1408e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1409ea22c4cfSJozef Kolek return MCDisassembler::Success; 1410b0852e54SZoran Jovanovic } 1411b0852e54SZoran Jovanovic 14121904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, 14131904fa21SJozef Kolek unsigned RegNo, 14141904fa21SJozef Kolek uint64_t Address, 14151904fa21SJozef Kolek const void *Decoder) { 1416315e7ecaSJozef Kolek if (RegNo > 7) 14171904fa21SJozef Kolek return MCDisassembler::Fail; 1418315e7ecaSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo); 1419e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1420315e7ecaSJozef Kolek return MCDisassembler::Success; 14211904fa21SJozef Kolek } 14221904fa21SJozef Kolek 142341688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst, 142441688679SZoran Jovanovic unsigned RegNo, 142541688679SZoran Jovanovic uint64_t Address, 142641688679SZoran Jovanovic const void *Decoder) { 142741688679SZoran Jovanovic if (RegNo > 7) 142841688679SZoran Jovanovic return MCDisassembler::Fail; 142941688679SZoran Jovanovic unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo); 1430e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 143141688679SZoran Jovanovic return MCDisassembler::Success; 143241688679SZoran Jovanovic } 143341688679SZoran Jovanovic 143413e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 143571928e68SAkira Hatanaka unsigned RegNo, 143671928e68SAkira Hatanaka uint64_t Address, 143771928e68SAkira Hatanaka const void *Decoder) { 143871928e68SAkira Hatanaka if (RegNo > 31) 143971928e68SAkira Hatanaka return MCDisassembler::Fail; 144013e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); 1441e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 144271928e68SAkira Hatanaka return MCDisassembler::Success; 144371928e68SAkira Hatanaka } 144471928e68SAkira Hatanaka 14459bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 14469bfa2e2eSAkira Hatanaka unsigned RegNo, 14479bfa2e2eSAkira Hatanaka uint64_t Address, 14489bfa2e2eSAkira Hatanaka const void *Decoder) { 1449a19216c8SDaniel Sanders if (static_cast<const MipsDisassembler *>(Decoder)->isGP64()) 14509bfa2e2eSAkira Hatanaka return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); 14519bfa2e2eSAkira Hatanaka 14529bfa2e2eSAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 14539bfa2e2eSAkira Hatanaka } 14549bfa2e2eSAkira Hatanaka 1455654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 1456ecabd1a5SAkira Hatanaka unsigned RegNo, 1457ecabd1a5SAkira Hatanaka uint64_t Address, 1458ecabd1a5SAkira Hatanaka const void *Decoder) { 145913e6ccf3SAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 1460ecabd1a5SAkira Hatanaka } 1461ecabd1a5SAkira Hatanaka 146271928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 146371928e68SAkira Hatanaka unsigned RegNo, 146471928e68SAkira Hatanaka uint64_t Address, 146571928e68SAkira Hatanaka const void *Decoder) { 146671928e68SAkira Hatanaka if (RegNo > 31) 146771928e68SAkira Hatanaka return MCDisassembler::Fail; 146871928e68SAkira Hatanaka 14699bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 1470e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 147171928e68SAkira Hatanaka return MCDisassembler::Success; 147271928e68SAkira Hatanaka } 147371928e68SAkira Hatanaka 147471928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 147571928e68SAkira Hatanaka unsigned RegNo, 147671928e68SAkira Hatanaka uint64_t Address, 147771928e68SAkira Hatanaka const void *Decoder) { 147871928e68SAkira Hatanaka if (RegNo > 31) 147971928e68SAkira Hatanaka return MCDisassembler::Fail; 148071928e68SAkira Hatanaka 14819bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 1482e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 148371928e68SAkira Hatanaka return MCDisassembler::Success; 148471928e68SAkira Hatanaka } 148571928e68SAkira Hatanaka 148671928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 148771928e68SAkira Hatanaka unsigned RegNo, 148871928e68SAkira Hatanaka uint64_t Address, 148971928e68SAkira Hatanaka const void *Decoder) { 1490253777fdSChad Rosier if (RegNo > 31) 1491253777fdSChad Rosier return MCDisassembler::Fail; 1492253777fdSChad Rosier unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); 1493e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 149471928e68SAkira Hatanaka return MCDisassembler::Success; 149571928e68SAkira Hatanaka } 149671928e68SAkira Hatanaka 14971fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 14981fb1b8b8SAkira Hatanaka unsigned RegNo, 14991fb1b8b8SAkira Hatanaka uint64_t Address, 15001fb1b8b8SAkira Hatanaka const void *Decoder) { 15011fb1b8b8SAkira Hatanaka if (RegNo > 7) 15021fb1b8b8SAkira Hatanaka return MCDisassembler::Fail; 15031fb1b8b8SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); 1504e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 15051fb1b8b8SAkira Hatanaka return MCDisassembler::Success; 15061fb1b8b8SAkira Hatanaka } 15071fb1b8b8SAkira Hatanaka 150836901dd1SVasileios Kalintiris static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, 15090fa60416SDaniel Sanders uint64_t Address, 15100fa60416SDaniel Sanders const void *Decoder) { 15110fa60416SDaniel Sanders if (RegNo > 31) 15120fa60416SDaniel Sanders return MCDisassembler::Fail; 15130fa60416SDaniel Sanders 151436901dd1SVasileios Kalintiris unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo); 1515e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 15160fa60416SDaniel Sanders return MCDisassembler::Success; 15170fa60416SDaniel Sanders } 15180fa60416SDaniel Sanders 151971928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 152071928e68SAkira Hatanaka unsigned Insn, 152171928e68SAkira Hatanaka uint64_t Address, 152271928e68SAkira Hatanaka const void *Decoder) { 152371928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1524ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1525ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 15269bf2b567SAkira Hatanaka 152713e6ccf3SAkira Hatanaka Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 152813e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 152971928e68SAkira Hatanaka 1530d7ecf49eSVladimir Medic if (Inst.getOpcode() == Mips::SC || 1531e4e83a7bSDaniel Sanders Inst.getOpcode() == Mips::SCD) 1532e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1533e4e83a7bSDaniel Sanders 1534e4e83a7bSDaniel Sanders Inst.addOperand(MCOperand::createReg(Reg)); 1535e4e83a7bSDaniel Sanders Inst.addOperand(MCOperand::createReg(Base)); 1536e4e83a7bSDaniel Sanders Inst.addOperand(MCOperand::createImm(Offset)); 1537e4e83a7bSDaniel Sanders 1538e4e83a7bSDaniel Sanders return MCDisassembler::Success; 153971928e68SAkira Hatanaka } 154071928e68SAkira Hatanaka 1541e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst, 1542e4e83a7bSDaniel Sanders unsigned Insn, 1543e4e83a7bSDaniel Sanders uint64_t Address, 1544e4e83a7bSDaniel Sanders const void *Decoder) { 1545e4e83a7bSDaniel Sanders int Offset = SignExtend32<9>(Insn >> 7); 1546e4e83a7bSDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1547e4e83a7bSDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 1548e4e83a7bSDaniel Sanders 1549e4e83a7bSDaniel Sanders Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1550e4e83a7bSDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1551e4e83a7bSDaniel Sanders 1552e4e83a7bSDaniel Sanders if (Inst.getOpcode() == Mips::SCE) 1553e4e83a7bSDaniel Sanders Inst.addOperand(MCOperand::createReg(Reg)); 1554e4e83a7bSDaniel Sanders 1555e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1556e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1557e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 155871928e68SAkira Hatanaka 155971928e68SAkira Hatanaka return MCDisassembler::Success; 156071928e68SAkira Hatanaka } 156171928e68SAkira Hatanaka 15623c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst, 15633c88fbd3SHrvoje Varga unsigned Insn, 15643c88fbd3SHrvoje Varga uint64_t Address, 15653c88fbd3SHrvoje Varga const void *Decoder) { 15663c88fbd3SHrvoje Varga int Offset = SignExtend32<16>(Insn & 0xffff); 15673c88fbd3SHrvoje Varga unsigned Base = fieldFromInstruction(Insn, 16, 5); 15683c88fbd3SHrvoje Varga unsigned Reg = fieldFromInstruction(Insn, 21, 5); 15693c88fbd3SHrvoje Varga 15703c88fbd3SHrvoje Varga Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 15713c88fbd3SHrvoje Varga Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 15723c88fbd3SHrvoje Varga 15733c88fbd3SHrvoje Varga Inst.addOperand(MCOperand::createReg(Reg)); 15743c88fbd3SHrvoje Varga Inst.addOperand(MCOperand::createReg(Base)); 15753c88fbd3SHrvoje Varga Inst.addOperand(MCOperand::createImm(Offset)); 15763c88fbd3SHrvoje Varga 15773c88fbd3SHrvoje Varga return MCDisassembler::Success; 15783c88fbd3SHrvoje Varga } 15793c88fbd3SHrvoje Varga 158092db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 158192db6b78SDaniel Sanders unsigned Insn, 158292db6b78SDaniel Sanders uint64_t Address, 158392db6b78SDaniel Sanders const void *Decoder) { 158492db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 158592db6b78SDaniel Sanders unsigned Hint = fieldFromInstruction(Insn, 16, 5); 158692db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 158792db6b78SDaniel Sanders 158892db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 158992db6b78SDaniel Sanders 1590e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1591e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1592e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Hint)); 159392db6b78SDaniel Sanders 159492db6b78SDaniel Sanders return MCDisassembler::Success; 159592db6b78SDaniel Sanders } 159692db6b78SDaniel Sanders 1597ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst, 1598ab6d1cceSJozef Kolek unsigned Insn, 1599ab6d1cceSJozef Kolek uint64_t Address, 1600ab6d1cceSJozef Kolek const void *Decoder) { 1601ab6d1cceSJozef Kolek int Offset = SignExtend32<12>(Insn & 0xfff); 1602ab6d1cceSJozef Kolek unsigned Base = fieldFromInstruction(Insn, 16, 5); 1603ab6d1cceSJozef Kolek unsigned Hint = fieldFromInstruction(Insn, 21, 5); 1604ab6d1cceSJozef Kolek 1605ab6d1cceSJozef Kolek Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1606ab6d1cceSJozef Kolek 1607e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1608e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1609e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Hint)); 1610ab6d1cceSJozef Kolek 1611ab6d1cceSJozef Kolek return MCDisassembler::Success; 1612ab6d1cceSJozef Kolek } 1613ab6d1cceSJozef Kolek 1614d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst, 1615d9790793SZoran Jovanovic unsigned Insn, 1616d9790793SZoran Jovanovic uint64_t Address, 1617d9790793SZoran Jovanovic const void *Decoder) { 1618d9790793SZoran Jovanovic int Offset = SignExtend32<9>(Insn & 0x1ff); 1619d9790793SZoran Jovanovic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1620d9790793SZoran Jovanovic unsigned Hint = fieldFromInstruction(Insn, 21, 5); 1621d9790793SZoran Jovanovic 1622d9790793SZoran Jovanovic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1623d9790793SZoran Jovanovic 1624d9790793SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Base)); 1625d9790793SZoran Jovanovic Inst.addOperand(MCOperand::createImm(Offset)); 1626d9790793SZoran Jovanovic Inst.addOperand(MCOperand::createImm(Hint)); 1627d9790793SZoran Jovanovic 1628d9790793SZoran Jovanovic return MCDisassembler::Success; 1629d9790793SZoran Jovanovic } 1630d9790793SZoran Jovanovic 1631e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, 1632df464ae2SVladimir Medic unsigned Insn, 1633df464ae2SVladimir Medic uint64_t Address, 1634df464ae2SVladimir Medic const void *Decoder) { 1635e4e83a7bSDaniel Sanders int Offset = SignExtend32<9>(Insn >> 7); 1636df464ae2SVladimir Medic unsigned Hint = fieldFromInstruction(Insn, 16, 5); 1637df464ae2SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 21, 5); 1638df464ae2SVladimir Medic 1639df464ae2SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1640df464ae2SVladimir Medic 1641e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1642e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1643e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Hint)); 1644df464ae2SVladimir Medic 1645df464ae2SVladimir Medic return MCDisassembler::Success; 1646df464ae2SVladimir Medic } 1647df464ae2SVladimir Medic 1648b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 1649b4484d62SDaniel Sanders unsigned Insn, 1650b4484d62SDaniel Sanders uint64_t Address, 1651b4484d62SDaniel Sanders const void *Decoder) { 1652b4484d62SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 1653b4484d62SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 1654b4484d62SDaniel Sanders 1655b4484d62SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1656b4484d62SDaniel Sanders 1657e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1658e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1659b4484d62SDaniel Sanders 1660b4484d62SDaniel Sanders return MCDisassembler::Success; 1661b4484d62SDaniel Sanders } 1662b4484d62SDaniel Sanders 1663eac9301cSSimon Dardis static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn, 1664eac9301cSSimon Dardis uint64_t Address, const void *Decoder) { 1665eac9301cSSimon Dardis int Offset = SignExtend32<16>(Insn & 0xffff); 1666eac9301cSSimon Dardis unsigned Base = fieldFromInstruction(Insn, 16, 5); 1667eac9301cSSimon Dardis 1668eac9301cSSimon Dardis Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1669eac9301cSSimon Dardis 1670eac9301cSSimon Dardis Inst.addOperand(MCOperand::createReg(Base)); 1671eac9301cSSimon Dardis Inst.addOperand(MCOperand::createImm(Offset)); 1672eac9301cSSimon Dardis 1673eac9301cSSimon Dardis return MCDisassembler::Success; 1674eac9301cSSimon Dardis } 1675eac9301cSSimon Dardis 167618148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst, 167718148671SHrvoje Varga unsigned Insn, 167818148671SHrvoje Varga uint64_t Address, 167918148671SHrvoje Varga const void *Decoder) { 168018148671SHrvoje Varga int Immediate = SignExtend32<16>(Insn & 0xffff); 168118148671SHrvoje Varga unsigned Base = fieldFromInstruction(Insn, 16, 5); 168218148671SHrvoje Varga 168318148671SHrvoje Varga Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 168418148671SHrvoje Varga 168518148671SHrvoje Varga Inst.addOperand(MCOperand::createReg(Base)); 168618148671SHrvoje Varga Inst.addOperand(MCOperand::createImm(Immediate)); 168718148671SHrvoje Varga 168818148671SHrvoje Varga return MCDisassembler::Success; 168918148671SHrvoje Varga } 169018148671SHrvoje Varga 1691fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 1692fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder) { 1693fe0bf9f6SMatheus Almeida int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10)); 1694fe0bf9f6SMatheus Almeida unsigned Reg = fieldFromInstruction(Insn, 6, 5); 1695fe0bf9f6SMatheus Almeida unsigned Base = fieldFromInstruction(Insn, 11, 5); 1696fe0bf9f6SMatheus Almeida 1697fe0bf9f6SMatheus Almeida Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg); 1698fe0bf9f6SMatheus Almeida Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1699fe0bf9f6SMatheus Almeida 1700e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1701e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 17026b59c449SMatheus Almeida 17036b59c449SMatheus Almeida // The immediate field of an LD/ST instruction is scaled which means it must 17046b59c449SMatheus Almeida // be multiplied (when decoding) by the size (in bytes) of the instructions' 17056b59c449SMatheus Almeida // data format. 17066b59c449SMatheus Almeida // .b - 1 byte 17076b59c449SMatheus Almeida // .h - 2 bytes 17086b59c449SMatheus Almeida // .w - 4 bytes 17096b59c449SMatheus Almeida // .d - 8 bytes 17106b59c449SMatheus Almeida switch(Inst.getOpcode()) 17116b59c449SMatheus Almeida { 17126b59c449SMatheus Almeida default: 1713926883e1SEugene Zelenko assert(false && "Unexpected instruction"); 17146b59c449SMatheus Almeida return MCDisassembler::Fail; 17156b59c449SMatheus Almeida break; 17166b59c449SMatheus Almeida case Mips::LD_B: 17176b59c449SMatheus Almeida case Mips::ST_B: 1718e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 17196b59c449SMatheus Almeida break; 17206b59c449SMatheus Almeida case Mips::LD_H: 17216b59c449SMatheus Almeida case Mips::ST_H: 1722e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset * 2)); 17236b59c449SMatheus Almeida break; 17246b59c449SMatheus Almeida case Mips::LD_W: 17256b59c449SMatheus Almeida case Mips::ST_W: 1726e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset * 4)); 17276b59c449SMatheus Almeida break; 17286b59c449SMatheus Almeida case Mips::LD_D: 17296b59c449SMatheus Almeida case Mips::ST_D: 1730e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset * 8)); 17316b59c449SMatheus Almeida break; 17326b59c449SMatheus Almeida } 1733fe0bf9f6SMatheus Almeida 1734fe0bf9f6SMatheus Almeida return MCDisassembler::Success; 1735fe0bf9f6SMatheus Almeida } 1736fe0bf9f6SMatheus Almeida 1737315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 1738315e7ecaSJozef Kolek unsigned Insn, 1739315e7ecaSJozef Kolek uint64_t Address, 1740315e7ecaSJozef Kolek const void *Decoder) { 1741315e7ecaSJozef Kolek unsigned Offset = Insn & 0xf; 1742315e7ecaSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 7, 3); 1743315e7ecaSJozef Kolek unsigned Base = fieldFromInstruction(Insn, 4, 3); 1744315e7ecaSJozef Kolek 1745315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1746315e7ecaSJozef Kolek case Mips::LBU16_MM: 1747315e7ecaSJozef Kolek case Mips::LHU16_MM: 1748315e7ecaSJozef Kolek case Mips::LW16_MM: 1749315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder) 1750315e7ecaSJozef Kolek == MCDisassembler::Fail) 1751315e7ecaSJozef Kolek return MCDisassembler::Fail; 1752315e7ecaSJozef Kolek break; 1753315e7ecaSJozef Kolek case Mips::SB16_MM: 1754797c2aecSZlatko Buljan case Mips::SB16_MMR6: 1755315e7ecaSJozef Kolek case Mips::SH16_MM: 1756797c2aecSZlatko Buljan case Mips::SH16_MMR6: 1757315e7ecaSJozef Kolek case Mips::SW16_MM: 1758797c2aecSZlatko Buljan case Mips::SW16_MMR6: 1759315e7ecaSJozef Kolek if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder) 1760315e7ecaSJozef Kolek == MCDisassembler::Fail) 1761315e7ecaSJozef Kolek return MCDisassembler::Fail; 1762315e7ecaSJozef Kolek break; 1763315e7ecaSJozef Kolek } 1764315e7ecaSJozef Kolek 1765315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder) 1766315e7ecaSJozef Kolek == MCDisassembler::Fail) 1767315e7ecaSJozef Kolek return MCDisassembler::Fail; 1768315e7ecaSJozef Kolek 1769315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1770315e7ecaSJozef Kolek case Mips::LBU16_MM: 1771315e7ecaSJozef Kolek if (Offset == 0xf) 1772e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(-1)); 1773315e7ecaSJozef Kolek else 1774e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1775315e7ecaSJozef Kolek break; 1776315e7ecaSJozef Kolek case Mips::SB16_MM: 1777797c2aecSZlatko Buljan case Mips::SB16_MMR6: 1778e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1779315e7ecaSJozef Kolek break; 1780315e7ecaSJozef Kolek case Mips::LHU16_MM: 1781315e7ecaSJozef Kolek case Mips::SH16_MM: 1782797c2aecSZlatko Buljan case Mips::SH16_MMR6: 1783e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 1)); 1784315e7ecaSJozef Kolek break; 1785315e7ecaSJozef Kolek case Mips::LW16_MM: 1786315e7ecaSJozef Kolek case Mips::SW16_MM: 1787797c2aecSZlatko Buljan case Mips::SW16_MMR6: 1788e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 1789315e7ecaSJozef Kolek break; 1790315e7ecaSJozef Kolek } 1791315e7ecaSJozef Kolek 1792315e7ecaSJozef Kolek return MCDisassembler::Success; 1793315e7ecaSJozef Kolek } 1794315e7ecaSJozef Kolek 179512c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, 179612c6982bSJozef Kolek unsigned Insn, 179712c6982bSJozef Kolek uint64_t Address, 179812c6982bSJozef Kolek const void *Decoder) { 179912c6982bSJozef Kolek unsigned Offset = Insn & 0x1F; 180012c6982bSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 5, 5); 180112c6982bSJozef Kolek 180212c6982bSJozef Kolek Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 180312c6982bSJozef Kolek 1804e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1805e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::SP)); 1806e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 180712c6982bSJozef Kolek 180812c6982bSJozef Kolek return MCDisassembler::Success; 180912c6982bSJozef Kolek } 181012c6982bSJozef Kolek 1811e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, 1812e10a02ecSJozef Kolek unsigned Insn, 1813e10a02ecSJozef Kolek uint64_t Address, 1814e10a02ecSJozef Kolek const void *Decoder) { 1815e10a02ecSJozef Kolek unsigned Offset = Insn & 0x7F; 1816e10a02ecSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 7, 3); 1817e10a02ecSJozef Kolek 1818e10a02ecSJozef Kolek Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1819e10a02ecSJozef Kolek 1820e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1821e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::GP)); 1822e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 1823e10a02ecSJozef Kolek 1824e10a02ecSJozef Kolek return MCDisassembler::Success; 1825e10a02ecSJozef Kolek } 1826e10a02ecSJozef Kolek 1827d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, 1828d68d424aSJozef Kolek unsigned Insn, 1829d68d424aSJozef Kolek uint64_t Address, 1830d68d424aSJozef Kolek const void *Decoder) { 1831797c2aecSZlatko Buljan int Offset; 1832797c2aecSZlatko Buljan switch (Inst.getOpcode()) { 1833797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 1834797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 1835797c2aecSZlatko Buljan Offset = fieldFromInstruction(Insn, 4, 4); 1836797c2aecSZlatko Buljan break; 1837797c2aecSZlatko Buljan default: 1838797c2aecSZlatko Buljan Offset = SignExtend32<4>(Insn & 0xf); 1839797c2aecSZlatko Buljan break; 1840797c2aecSZlatko Buljan } 1841d68d424aSJozef Kolek 1842d68d424aSJozef Kolek if (DecodeRegListOperand16(Inst, Insn, Address, Decoder) 1843d68d424aSJozef Kolek == MCDisassembler::Fail) 1844d68d424aSJozef Kolek return MCDisassembler::Fail; 1845d68d424aSJozef Kolek 1846e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::SP)); 1847e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 1848d68d424aSJozef Kolek 1849d68d424aSJozef Kolek return MCDisassembler::Success; 1850d68d424aSJozef Kolek } 1851d68d424aSJozef Kolek 1852a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst, 1853a6593ff6SZoran Jovanovic unsigned Insn, 1854a6593ff6SZoran Jovanovic uint64_t Address, 1855a6593ff6SZoran Jovanovic const void *Decoder) { 1856a6593ff6SZoran Jovanovic int Offset = SignExtend32<9>(Insn & 0x1ff); 1857a6593ff6SZoran Jovanovic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1858a6593ff6SZoran Jovanovic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1859a6593ff6SZoran Jovanovic 1860a6593ff6SZoran Jovanovic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1861a6593ff6SZoran Jovanovic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1862a6593ff6SZoran Jovanovic 18633ef4dd7bSHrvoje Varga if (Inst.getOpcode() == Mips::SCE_MM) 18643ef4dd7bSHrvoje Varga Inst.addOperand(MCOperand::createReg(Reg)); 18653ef4dd7bSHrvoje Varga 1866a6593ff6SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Reg)); 1867a6593ff6SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Base)); 1868a6593ff6SZoran Jovanovic Inst.addOperand(MCOperand::createImm(Offset)); 1869a6593ff6SZoran Jovanovic 1870a6593ff6SZoran Jovanovic return MCDisassembler::Success; 1871a6593ff6SZoran Jovanovic } 1872a6593ff6SZoran Jovanovic 1873dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 1874dde3d582SVladimir Medic unsigned Insn, 1875dde3d582SVladimir Medic uint64_t Address, 1876dde3d582SVladimir Medic const void *Decoder) { 1877dde3d582SVladimir Medic int Offset = SignExtend32<12>(Insn & 0x0fff); 1878dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1879dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1880dde3d582SVladimir Medic 1881dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1882dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1883dde3d582SVladimir Medic 1884a4c4b5fcSZoran Jovanovic switch (Inst.getOpcode()) { 1885a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 1886a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 1887a4c4b5fcSZoran Jovanovic if (DecodeRegListOperand(Inst, Insn, Address, Decoder) 1888a4c4b5fcSZoran Jovanovic == MCDisassembler::Fail) 1889a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 1890e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1891e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1892a4c4b5fcSZoran Jovanovic break; 1893a4c4b5fcSZoran Jovanovic case Mips::SC_MM: 1894e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1895b03fd12cSJustin Bogner LLVM_FALLTHROUGH; 1896a4c4b5fcSZoran Jovanovic default: 1897e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1898ba553a6eSZlatko Buljan if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM || 1899ba553a6eSZlatko Buljan Inst.getOpcode() == Mips::LWP_MMR6 || Inst.getOpcode() == Mips::SWP_MMR6) 1900e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg+1)); 19012deca348SZoran Jovanovic 1902e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1903e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1904a4c4b5fcSZoran Jovanovic } 1905dde3d582SVladimir Medic 1906dde3d582SVladimir Medic return MCDisassembler::Success; 1907dde3d582SVladimir Medic } 1908dde3d582SVladimir Medic 1909dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 1910dde3d582SVladimir Medic unsigned Insn, 1911dde3d582SVladimir Medic uint64_t Address, 1912dde3d582SVladimir Medic const void *Decoder) { 1913dde3d582SVladimir Medic int Offset = SignExtend32<16>(Insn & 0xffff); 1914dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1915dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1916dde3d582SVladimir Medic 1917dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1918dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1919dde3d582SVladimir Medic 1920e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1921e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1922e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1923dde3d582SVladimir Medic 1924dde3d582SVladimir Medic return MCDisassembler::Success; 1925dde3d582SVladimir Medic } 1926dde3d582SVladimir Medic 192771928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, 192871928e68SAkira Hatanaka unsigned Insn, 192971928e68SAkira Hatanaka uint64_t Address, 193071928e68SAkira Hatanaka const void *Decoder) { 193171928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1932ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1933ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 193471928e68SAkira Hatanaka 19359bf2b567SAkira Hatanaka Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 193613e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 19379bf2b567SAkira Hatanaka 1938e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1939e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1940e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 194171928e68SAkira Hatanaka 194271928e68SAkira Hatanaka return MCDisassembler::Success; 194371928e68SAkira Hatanaka } 194471928e68SAkira Hatanaka 1945cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn, 1946cba9f80bSZlatko Buljan uint64_t Address, const void *Decoder) { 1947cba9f80bSZlatko Buljan // This function is the same as DecodeFMem but with the Reg and Base fields 1948cba9f80bSZlatko Buljan // swapped according to microMIPS spec. 1949cba9f80bSZlatko Buljan int Offset = SignExtend32<16>(Insn & 0xffff); 1950cba9f80bSZlatko Buljan unsigned Base = fieldFromInstruction(Insn, 16, 5); 1951cba9f80bSZlatko Buljan unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1952cba9f80bSZlatko Buljan 1953cba9f80bSZlatko Buljan Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg); 1954cba9f80bSZlatko Buljan Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1955cba9f80bSZlatko Buljan 1956cba9f80bSZlatko Buljan Inst.addOperand(MCOperand::createReg(Reg)); 1957cba9f80bSZlatko Buljan Inst.addOperand(MCOperand::createReg(Base)); 1958cba9f80bSZlatko Buljan Inst.addOperand(MCOperand::createImm(Offset)); 1959cba9f80bSZlatko Buljan 1960cba9f80bSZlatko Buljan return MCDisassembler::Success; 1961cba9f80bSZlatko Buljan } 1962cba9f80bSZlatko Buljan 196392db6b78SDaniel Sanders static DecodeStatus DecodeFMem2(MCInst &Inst, 196492db6b78SDaniel Sanders unsigned Insn, 196592db6b78SDaniel Sanders uint64_t Address, 196692db6b78SDaniel Sanders const void *Decoder) { 196792db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 196892db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 196992db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 197092db6b78SDaniel Sanders 197192db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); 197292db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 197392db6b78SDaniel Sanders 1974e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1975e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1976e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 197792db6b78SDaniel Sanders 197892db6b78SDaniel Sanders return MCDisassembler::Success; 197992db6b78SDaniel Sanders } 198092db6b78SDaniel Sanders 198192db6b78SDaniel Sanders static DecodeStatus DecodeFMem3(MCInst &Inst, 198292db6b78SDaniel Sanders unsigned Insn, 198392db6b78SDaniel Sanders uint64_t Address, 198492db6b78SDaniel Sanders const void *Decoder) { 198592db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 198692db6b78SDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 198792db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 198892db6b78SDaniel Sanders 198992db6b78SDaniel Sanders Reg = getReg(Decoder, Mips::COP3RegClassID, Reg); 199092db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 199192db6b78SDaniel Sanders 1992e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1993e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1994e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 199592db6b78SDaniel Sanders 199692db6b78SDaniel Sanders return MCDisassembler::Success; 199792db6b78SDaniel Sanders } 199892db6b78SDaniel Sanders 1999435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, 2000435cf8a4SVladimir Medic unsigned Insn, 2001435cf8a4SVladimir Medic uint64_t Address, 2002435cf8a4SVladimir Medic const void *Decoder) { 2003435cf8a4SVladimir Medic int Offset = SignExtend32<11>(Insn & 0x07ff); 2004435cf8a4SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 16, 5); 2005435cf8a4SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 11, 5); 2006435cf8a4SVladimir Medic 2007435cf8a4SVladimir Medic Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); 2008435cf8a4SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 2009435cf8a4SVladimir Medic 2010e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 2011e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 2012e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 2013435cf8a4SVladimir Medic 2014435cf8a4SVladimir Medic return MCDisassembler::Success; 2015435cf8a4SVladimir Medic } 2016cba9f80bSZlatko Buljan 2017cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn, 2018cba9f80bSZlatko Buljan uint64_t Address, const void *Decoder) { 2019cba9f80bSZlatko Buljan int Offset = SignExtend32<11>(Insn & 0x07ff); 2020cba9f80bSZlatko Buljan unsigned Reg = fieldFromInstruction(Insn, 21, 5); 2021cba9f80bSZlatko Buljan unsigned Base = fieldFromInstruction(Insn, 16, 5); 2022cba9f80bSZlatko Buljan 2023cba9f80bSZlatko Buljan Reg = getReg(Decoder, Mips::COP2RegClassID, Reg); 2024cba9f80bSZlatko Buljan Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 2025cba9f80bSZlatko Buljan 2026cba9f80bSZlatko Buljan Inst.addOperand(MCOperand::createReg(Reg)); 2027cba9f80bSZlatko Buljan Inst.addOperand(MCOperand::createReg(Base)); 2028cba9f80bSZlatko Buljan Inst.addOperand(MCOperand::createImm(Offset)); 2029cba9f80bSZlatko Buljan 2030cba9f80bSZlatko Buljan return MCDisassembler::Success; 2031cba9f80bSZlatko Buljan } 2032cba9f80bSZlatko Buljan 20336a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 20346a803f61SDaniel Sanders unsigned Insn, 20356a803f61SDaniel Sanders uint64_t Address, 20366a803f61SDaniel Sanders const void *Decoder) { 20376a803f61SDaniel Sanders int64_t Offset = SignExtend64<9>((Insn >> 7) & 0x1ff); 20386a803f61SDaniel Sanders unsigned Rt = fieldFromInstruction(Insn, 16, 5); 20396a803f61SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 20406a803f61SDaniel Sanders 20416a803f61SDaniel Sanders Rt = getReg(Decoder, Mips::GPR32RegClassID, Rt); 20426a803f61SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 20436a803f61SDaniel Sanders 20446a803f61SDaniel Sanders if(Inst.getOpcode() == Mips::SC_R6 || Inst.getOpcode() == Mips::SCD_R6){ 2045e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Rt)); 20466a803f61SDaniel Sanders } 20476a803f61SDaniel Sanders 2048e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Rt)); 2049e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 2050e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 20516a803f61SDaniel Sanders 20526a803f61SDaniel Sanders return MCDisassembler::Success; 20536a803f61SDaniel Sanders } 205471928e68SAkira Hatanaka 205571928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst, 205671928e68SAkira Hatanaka unsigned RegNo, 205771928e68SAkira Hatanaka uint64_t Address, 205871928e68SAkira Hatanaka const void *Decoder) { 205971928e68SAkira Hatanaka // Currently only hardware register 29 is supported. 206071928e68SAkira Hatanaka if (RegNo != 29) 206171928e68SAkira Hatanaka return MCDisassembler::Fail; 2062e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::HWR29)); 206371928e68SAkira Hatanaka return MCDisassembler::Success; 206471928e68SAkira Hatanaka } 206571928e68SAkira Hatanaka 206671928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst, 206771928e68SAkira Hatanaka unsigned RegNo, 206871928e68SAkira Hatanaka uint64_t Address, 206971928e68SAkira Hatanaka const void *Decoder) { 20709bf2b567SAkira Hatanaka if (RegNo > 30 || RegNo %2) 207171928e68SAkira Hatanaka return MCDisassembler::Fail; 207271928e68SAkira Hatanaka 20739bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2); 2074e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 207571928e68SAkira Hatanaka return MCDisassembler::Success; 207671928e68SAkira Hatanaka } 207771928e68SAkira Hatanaka 207800fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst, 2079ecabd1a5SAkira Hatanaka unsigned RegNo, 2080ecabd1a5SAkira Hatanaka uint64_t Address, 2081ecabd1a5SAkira Hatanaka const void *Decoder) { 2082ecabd1a5SAkira Hatanaka if (RegNo >= 4) 2083ecabd1a5SAkira Hatanaka return MCDisassembler::Fail; 2084ecabd1a5SAkira Hatanaka 208500fcf2e1SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo); 2086e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 2087ecabd1a5SAkira Hatanaka return MCDisassembler::Success; 2088ecabd1a5SAkira Hatanaka } 2089ecabd1a5SAkira Hatanaka 20908002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst, 209159bfaf77SAkira Hatanaka unsigned RegNo, 209259bfaf77SAkira Hatanaka uint64_t Address, 209359bfaf77SAkira Hatanaka const void *Decoder) { 209459bfaf77SAkira Hatanaka if (RegNo >= 4) 209559bfaf77SAkira Hatanaka return MCDisassembler::Fail; 209659bfaf77SAkira Hatanaka 20978002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo); 2098e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 209959bfaf77SAkira Hatanaka return MCDisassembler::Success; 210059bfaf77SAkira Hatanaka } 210159bfaf77SAkira Hatanaka 21028002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst, 210359bfaf77SAkira Hatanaka unsigned RegNo, 210459bfaf77SAkira Hatanaka uint64_t Address, 210559bfaf77SAkira Hatanaka const void *Decoder) { 210659bfaf77SAkira Hatanaka if (RegNo >= 4) 210759bfaf77SAkira Hatanaka return MCDisassembler::Fail; 210859bfaf77SAkira Hatanaka 21098002a3f6SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo); 2110e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 211159bfaf77SAkira Hatanaka return MCDisassembler::Success; 211259bfaf77SAkira Hatanaka } 211359bfaf77SAkira Hatanaka 21143eb663b0SJack Carter static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst, 21153eb663b0SJack Carter unsigned RegNo, 21163eb663b0SJack Carter uint64_t Address, 21173eb663b0SJack Carter const void *Decoder) { 21183eb663b0SJack Carter if (RegNo > 31) 21193eb663b0SJack Carter return MCDisassembler::Fail; 21203eb663b0SJack Carter 21213eb663b0SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo); 2122e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 21233eb663b0SJack Carter return MCDisassembler::Success; 21243eb663b0SJack Carter } 21253eb663b0SJack Carter 21265dc8ac92SJack Carter static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst, 21275dc8ac92SJack Carter unsigned RegNo, 21285dc8ac92SJack Carter uint64_t Address, 21295dc8ac92SJack Carter const void *Decoder) { 21305dc8ac92SJack Carter if (RegNo > 31) 21315dc8ac92SJack Carter return MCDisassembler::Fail; 21325dc8ac92SJack Carter 21335dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo); 2134e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 21355dc8ac92SJack Carter return MCDisassembler::Success; 21365dc8ac92SJack Carter } 21375dc8ac92SJack Carter 21385dc8ac92SJack Carter static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst, 21395dc8ac92SJack Carter unsigned RegNo, 21405dc8ac92SJack Carter uint64_t Address, 21415dc8ac92SJack Carter const void *Decoder) { 21425dc8ac92SJack Carter if (RegNo > 31) 21435dc8ac92SJack Carter return MCDisassembler::Fail; 21445dc8ac92SJack Carter 21455dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo); 2146e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 21475dc8ac92SJack Carter return MCDisassembler::Success; 21485dc8ac92SJack Carter } 21495dc8ac92SJack Carter 21505dc8ac92SJack Carter static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst, 21515dc8ac92SJack Carter unsigned RegNo, 21525dc8ac92SJack Carter uint64_t Address, 21535dc8ac92SJack Carter const void *Decoder) { 21545dc8ac92SJack Carter if (RegNo > 31) 21555dc8ac92SJack Carter return MCDisassembler::Fail; 21565dc8ac92SJack Carter 21575dc8ac92SJack Carter unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo); 2158e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 21595dc8ac92SJack Carter return MCDisassembler::Success; 21605dc8ac92SJack Carter } 21615dc8ac92SJack Carter 2162a591fdc6SMatheus Almeida static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst, 2163a591fdc6SMatheus Almeida unsigned RegNo, 2164a591fdc6SMatheus Almeida uint64_t Address, 2165a591fdc6SMatheus Almeida const void *Decoder) { 2166a591fdc6SMatheus Almeida if (RegNo > 7) 2167a591fdc6SMatheus Almeida return MCDisassembler::Fail; 2168a591fdc6SMatheus Almeida 2169a591fdc6SMatheus Almeida unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo); 2170e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 2171a591fdc6SMatheus Almeida return MCDisassembler::Success; 2172a591fdc6SMatheus Almeida } 2173a591fdc6SMatheus Almeida 2174a3134faeSDaniel Sanders static DecodeStatus DecodeCOP0RegisterClass(MCInst &Inst, 2175a3134faeSDaniel Sanders unsigned RegNo, 2176a3134faeSDaniel Sanders uint64_t Address, 2177a3134faeSDaniel Sanders const void *Decoder) { 2178a3134faeSDaniel Sanders if (RegNo > 31) 2179a3134faeSDaniel Sanders return MCDisassembler::Fail; 2180a3134faeSDaniel Sanders 2181a3134faeSDaniel Sanders unsigned Reg = getReg(Decoder, Mips::COP0RegClassID, RegNo); 2182a3134faeSDaniel Sanders Inst.addOperand(MCOperand::createReg(Reg)); 2183a3134faeSDaniel Sanders return MCDisassembler::Success; 2184a3134faeSDaniel Sanders } 2185a3134faeSDaniel Sanders 21862a83d680SDaniel Sanders static DecodeStatus DecodeCOP2RegisterClass(MCInst &Inst, 21872a83d680SDaniel Sanders unsigned RegNo, 21882a83d680SDaniel Sanders uint64_t Address, 21892a83d680SDaniel Sanders const void *Decoder) { 21902a83d680SDaniel Sanders if (RegNo > 31) 21912a83d680SDaniel Sanders return MCDisassembler::Fail; 21922a83d680SDaniel Sanders 21932a83d680SDaniel Sanders unsigned Reg = getReg(Decoder, Mips::COP2RegClassID, RegNo); 2194e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 21952a83d680SDaniel Sanders return MCDisassembler::Success; 21962a83d680SDaniel Sanders } 21972a83d680SDaniel Sanders 219871928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst, 219971928e68SAkira Hatanaka unsigned Offset, 220071928e68SAkira Hatanaka uint64_t Address, 220171928e68SAkira Hatanaka const void *Decoder) { 2202d37bab61SAlexey Samsonov int32_t BranchOffset = (SignExtend32<16>(Offset) * 4) + 4; 2203e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 220471928e68SAkira Hatanaka return MCDisassembler::Success; 220571928e68SAkira Hatanaka } 220671928e68SAkira Hatanaka 22076f09cdfdSHrvoje Varga static DecodeStatus DecodeBranchTarget1SImm16(MCInst &Inst, 22086f09cdfdSHrvoje Varga unsigned Offset, 22096f09cdfdSHrvoje Varga uint64_t Address, 22106f09cdfdSHrvoje Varga const void *Decoder) { 22116f09cdfdSHrvoje Varga int32_t BranchOffset = (SignExtend32<16>(Offset) * 2); 22126f09cdfdSHrvoje Varga Inst.addOperand(MCOperand::createImm(BranchOffset)); 22136f09cdfdSHrvoje Varga return MCDisassembler::Success; 22146f09cdfdSHrvoje Varga } 22156f09cdfdSHrvoje Varga 221671928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst, 221771928e68SAkira Hatanaka unsigned Insn, 221871928e68SAkira Hatanaka uint64_t Address, 221971928e68SAkira Hatanaka const void *Decoder) { 2220ecaef49fSJim Grosbach unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 2221e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(JumpOffset)); 222271928e68SAkira Hatanaka return MCDisassembler::Success; 222371928e68SAkira Hatanaka } 222471928e68SAkira Hatanaka 22253c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget21(MCInst &Inst, 22263c8869dcSZoran Jovanovic unsigned Offset, 22273c8869dcSZoran Jovanovic uint64_t Address, 22283c8869dcSZoran Jovanovic const void *Decoder) { 2229672c710dSSagar Thakur int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4; 22303c8869dcSZoran Jovanovic 2231e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 22323c8869dcSZoran Jovanovic return MCDisassembler::Success; 22333c8869dcSZoran Jovanovic } 22343c8869dcSZoran Jovanovic 223584e4d59eSZoran Jovanovic static DecodeStatus DecodeBranchTarget21MM(MCInst &Inst, 223684e4d59eSZoran Jovanovic unsigned Offset, 223784e4d59eSZoran Jovanovic uint64_t Address, 223884e4d59eSZoran Jovanovic const void *Decoder) { 2239f0ed16eaSHrvoje Varga int32_t BranchOffset = SignExtend32<21>(Offset) * 4 + 4; 224084e4d59eSZoran Jovanovic 224184e4d59eSZoran Jovanovic Inst.addOperand(MCOperand::createImm(BranchOffset)); 224284e4d59eSZoran Jovanovic return MCDisassembler::Success; 224384e4d59eSZoran Jovanovic } 224484e4d59eSZoran Jovanovic 22453c8869dcSZoran Jovanovic static DecodeStatus DecodeBranchTarget26(MCInst &Inst, 22463c8869dcSZoran Jovanovic unsigned Offset, 22473c8869dcSZoran Jovanovic uint64_t Address, 22483c8869dcSZoran Jovanovic const void *Decoder) { 2249672c710dSSagar Thakur int32_t BranchOffset = SignExtend32<26>(Offset) * 4 + 4; 22503c8869dcSZoran Jovanovic 2251e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 22523c8869dcSZoran Jovanovic return MCDisassembler::Success; 22533c8869dcSZoran Jovanovic } 22543c8869dcSZoran Jovanovic 22559761e96bSJozef Kolek static DecodeStatus DecodeBranchTarget7MM(MCInst &Inst, 22569761e96bSJozef Kolek unsigned Offset, 22579761e96bSJozef Kolek uint64_t Address, 22589761e96bSJozef Kolek const void *Decoder) { 225972982e69SSimon Atanasyan int32_t BranchOffset = SignExtend32<8>(Offset << 1); 2260e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 22619761e96bSJozef Kolek return MCDisassembler::Success; 22629761e96bSJozef Kolek } 22639761e96bSJozef Kolek 22645cfebddeSJozef Kolek static DecodeStatus DecodeBranchTarget10MM(MCInst &Inst, 22655cfebddeSJozef Kolek unsigned Offset, 22665cfebddeSJozef Kolek uint64_t Address, 22675cfebddeSJozef Kolek const void *Decoder) { 226872982e69SSimon Atanasyan int32_t BranchOffset = SignExtend32<11>(Offset << 1); 2269e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 22705cfebddeSJozef Kolek return MCDisassembler::Success; 22715cfebddeSJozef Kolek } 22725cfebddeSJozef Kolek 22738a80aa76SZoran Jovanovic static DecodeStatus DecodeBranchTargetMM(MCInst &Inst, 22748a80aa76SZoran Jovanovic unsigned Offset, 22758a80aa76SZoran Jovanovic uint64_t Address, 22768a80aa76SZoran Jovanovic const void *Decoder) { 2277f0ed16eaSHrvoje Varga int32_t BranchOffset = SignExtend32<16>(Offset) * 2 + 4; 2278e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(BranchOffset)); 22798a80aa76SZoran Jovanovic return MCDisassembler::Success; 22808a80aa76SZoran Jovanovic } 22818a80aa76SZoran Jovanovic 2282a887b361SZoran Jovanovic static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, 2283a887b361SZoran Jovanovic unsigned Offset, 2284a887b361SZoran Jovanovic uint64_t Address, 2285a887b361SZoran Jovanovic const void *Decoder) { 228672982e69SSimon Atanasyan int32_t BranchOffset = SignExtend32<27>(Offset << 1); 2287a887b361SZoran Jovanovic 2288a887b361SZoran Jovanovic Inst.addOperand(MCOperand::createImm(BranchOffset)); 2289a887b361SZoran Jovanovic return MCDisassembler::Success; 2290a887b361SZoran Jovanovic } 2291a887b361SZoran Jovanovic 2292507e084aSZoran Jovanovic static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, 2293507e084aSZoran Jovanovic unsigned Insn, 2294507e084aSZoran Jovanovic uint64_t Address, 2295507e084aSZoran Jovanovic const void *Decoder) { 2296507e084aSZoran Jovanovic unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1; 2297e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(JumpOffset)); 2298507e084aSZoran Jovanovic return MCDisassembler::Success; 2299507e084aSZoran Jovanovic } 230071928e68SAkira Hatanaka 2301aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 2302aa2b9278SJozef Kolek unsigned Value, 2303aa2b9278SJozef Kolek uint64_t Address, 2304aa2b9278SJozef Kolek const void *Decoder) { 2305aa2b9278SJozef Kolek if (Value == 0) 2306e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(1)); 2307aa2b9278SJozef Kolek else if (Value == 0x7) 2308e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(-1)); 2309aa2b9278SJozef Kolek else 2310e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Value << 2)); 2311aa2b9278SJozef Kolek return MCDisassembler::Success; 2312aa2b9278SJozef Kolek } 2313aa2b9278SJozef Kolek 231497297770SDaniel Sanders static DecodeStatus DecodeLi16Imm(MCInst &Inst, 2315aa2b9278SJozef Kolek unsigned Value, 2316aa2b9278SJozef Kolek uint64_t Address, 2317aa2b9278SJozef Kolek const void *Decoder) { 2318aa2b9278SJozef Kolek if (Value == 0x7F) 2319e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(-1)); 2320aa2b9278SJozef Kolek else 2321e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Value)); 2322aa2b9278SJozef Kolek return MCDisassembler::Success; 2323aa2b9278SJozef Kolek } 2324aa2b9278SJozef Kolek 23256b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, 23266b28f09dSZoran Jovanovic unsigned Value, 23276b28f09dSZoran Jovanovic uint64_t Address, 23286b28f09dSZoran Jovanovic const void *Decoder) { 23296b28f09dSZoran Jovanovic Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value)); 23306b28f09dSZoran Jovanovic return MCDisassembler::Success; 23316b28f09dSZoran Jovanovic } 23326b28f09dSZoran Jovanovic 233319b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale> 233419b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, 2335779c5937SMatheus Almeida uint64_t Address, 2336779c5937SMatheus Almeida const void *Decoder) { 2337ea4f653dSDaniel Sanders Value &= ((1 << Bits) - 1); 233819b7f76aSDaniel Sanders Value *= Scale; 2339ea4f653dSDaniel Sanders Inst.addOperand(MCOperand::createImm(Value + Offset)); 2340779c5937SMatheus Almeida return MCDisassembler::Success; 2341779c5937SMatheus Almeida } 2342779c5937SMatheus Almeida 234397297770SDaniel Sanders template <unsigned Bits, int Offset, int ScaleBy> 234497297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value, 234578e89020SDaniel Sanders uint64_t Address, 234678e89020SDaniel Sanders const void *Decoder) { 234797297770SDaniel Sanders int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy; 234878e89020SDaniel Sanders Inst.addOperand(MCOperand::createImm(Imm + Offset)); 234978e89020SDaniel Sanders return MCDisassembler::Success; 235078e89020SDaniel Sanders } 235178e89020SDaniel Sanders 235271928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 235371928e68SAkira Hatanaka unsigned Insn, 235471928e68SAkira Hatanaka uint64_t Address, 235571928e68SAkira Hatanaka const void *Decoder) { 235671928e68SAkira Hatanaka // First we need to grab the pos(lsb) from MCInst. 23576f83ae38SSimon Dardis // This function only handles the 32 bit variants of ins, as dins 23586f83ae38SSimon Dardis // variants are handled differently. 235971928e68SAkira Hatanaka int Pos = Inst.getOperand(2).getImm(); 23606f83ae38SSimon Dardis int Size = (int) Insn - Pos + 1; 2361e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size))); 236271928e68SAkira Hatanaka return MCDisassembler::Success; 236371928e68SAkira Hatanaka } 236471928e68SAkira Hatanaka 2365b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 2366b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder) { 2367e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4)); 2368b59e1a41SDaniel Sanders return MCDisassembler::Success; 2369b59e1a41SDaniel Sanders } 23702855142aSZoran Jovanovic 23712855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 23722855142aSZoran Jovanovic uint64_t Address, const void *Decoder) { 2373e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8)); 23742855142aSZoran Jovanovic return MCDisassembler::Success; 23752855142aSZoran Jovanovic } 2376a4c4b5fcSZoran Jovanovic 2377b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 2378b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 2379b682ddf3SVladimir Medic int32_t DecodedValue; 2380b682ddf3SVladimir Medic switch (Insn) { 2381b682ddf3SVladimir Medic case 0: DecodedValue = 256; break; 2382b682ddf3SVladimir Medic case 1: DecodedValue = 257; break; 2383b682ddf3SVladimir Medic case 510: DecodedValue = -258; break; 2384b682ddf3SVladimir Medic case 511: DecodedValue = -257; break; 2385b682ddf3SVladimir Medic default: DecodedValue = SignExtend32<9>(Insn); break; 2386b682ddf3SVladimir Medic } 2387e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(DecodedValue * 4)); 2388b682ddf3SVladimir Medic return MCDisassembler::Success; 2389b682ddf3SVladimir Medic } 2390b682ddf3SVladimir Medic 2391b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 2392b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 2393b682ddf3SVladimir Medic // Insn must be >= 0, since it is unsigned that condition is always true. 2394b682ddf3SVladimir Medic assert(Insn < 16); 2395b682ddf3SVladimir Medic int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 2396b682ddf3SVladimir Medic 255, 32768, 65535}; 2397e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(DecodedValues[Insn])); 2398b682ddf3SVladimir Medic return MCDisassembler::Success; 2399b682ddf3SVladimir Medic } 2400b682ddf3SVladimir Medic 2401a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, 2402a4c4b5fcSZoran Jovanovic unsigned Insn, 2403a4c4b5fcSZoran Jovanovic uint64_t Address, 2404a4c4b5fcSZoran Jovanovic const void *Decoder) { 2405a4c4b5fcSZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5, 2406dc4b8c27SZoran Jovanovic Mips::S6, Mips::S7, Mips::FP}; 2407a4c4b5fcSZoran Jovanovic unsigned RegNum; 2408a4c4b5fcSZoran Jovanovic 2409a4c4b5fcSZoran Jovanovic unsigned RegLst = fieldFromInstruction(Insn, 21, 5); 2410df19a5e6SDaniel Sanders 2411a4c4b5fcSZoran Jovanovic // Empty register lists are not allowed. 2412a4c4b5fcSZoran Jovanovic if (RegLst == 0) 2413a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 2414a4c4b5fcSZoran Jovanovic 2415a4c4b5fcSZoran Jovanovic RegNum = RegLst & 0xf; 2416df19a5e6SDaniel Sanders 2417df19a5e6SDaniel Sanders // RegLst values 10-15, and 26-31 are reserved. 2418df19a5e6SDaniel Sanders if (RegNum > 9) 2419df19a5e6SDaniel Sanders return MCDisassembler::Fail; 2420df19a5e6SDaniel Sanders 2421a4c4b5fcSZoran Jovanovic for (unsigned i = 0; i < RegNum; i++) 2422e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Regs[i])); 2423a4c4b5fcSZoran Jovanovic 2424a4c4b5fcSZoran Jovanovic if (RegLst & 0x10) 2425e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::RA)); 2426a4c4b5fcSZoran Jovanovic 2427a4c4b5fcSZoran Jovanovic return MCDisassembler::Success; 2428a4c4b5fcSZoran Jovanovic } 2429f9a02500SZoran Jovanovic 2430f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 2431f9a02500SZoran Jovanovic uint64_t Address, 2432f9a02500SZoran Jovanovic const void *Decoder) { 2433f9a02500SZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3}; 2434797c2aecSZlatko Buljan unsigned RegLst; 2435797c2aecSZlatko Buljan switch(Inst.getOpcode()) { 2436797c2aecSZlatko Buljan default: 2437797c2aecSZlatko Buljan RegLst = fieldFromInstruction(Insn, 4, 2); 2438797c2aecSZlatko Buljan break; 2439797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 2440797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 2441797c2aecSZlatko Buljan RegLst = fieldFromInstruction(Insn, 8, 2); 2442797c2aecSZlatko Buljan break; 2443797c2aecSZlatko Buljan } 2444d68d424aSJozef Kolek unsigned RegNum = RegLst & 0x3; 2445f9a02500SZoran Jovanovic 2446d68d424aSJozef Kolek for (unsigned i = 0; i <= RegNum; i++) 2447e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Regs[i])); 2448f9a02500SZoran Jovanovic 2449e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::RA)); 2450f9a02500SZoran Jovanovic 2451f9a02500SZoran Jovanovic return MCDisassembler::Success; 2452f9a02500SZoran Jovanovic } 24532c6d7320SJozef Kolek 2454169df4e2SSimon Dardis static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair, 245541688679SZoran Jovanovic uint64_t Address, const void *Decoder) { 245641688679SZoran Jovanovic switch (RegPair) { 245741688679SZoran Jovanovic default: 245841688679SZoran Jovanovic return MCDisassembler::Fail; 245941688679SZoran Jovanovic case 0: 2460e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A1)); 2461e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A2)); 246241688679SZoran Jovanovic break; 246341688679SZoran Jovanovic case 1: 2464e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A1)); 2465e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A3)); 246641688679SZoran Jovanovic break; 246741688679SZoran Jovanovic case 2: 2468e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A2)); 2469e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A3)); 247041688679SZoran Jovanovic break; 247141688679SZoran Jovanovic case 3: 2472e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2473e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::S5)); 247441688679SZoran Jovanovic break; 247541688679SZoran Jovanovic case 4: 2476e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2477e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::S6)); 247841688679SZoran Jovanovic break; 247941688679SZoran Jovanovic case 5: 2480e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2481e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A1)); 248241688679SZoran Jovanovic break; 248341688679SZoran Jovanovic case 6: 2484e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2485e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A2)); 248641688679SZoran Jovanovic break; 248741688679SZoran Jovanovic case 7: 2488e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2489e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A3)); 249041688679SZoran Jovanovic break; 249141688679SZoran Jovanovic } 249241688679SZoran Jovanovic 249341688679SZoran Jovanovic return MCDisassembler::Success; 249441688679SZoran Jovanovic } 249541688679SZoran Jovanovic 24962c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, 24972c6d7320SJozef Kolek uint64_t Address, const void *Decoder) { 24986499b5f0SJustin Bogner Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2))); 24992c6d7320SJozef Kolek return MCDisassembler::Success; 25002c6d7320SJozef Kolek } 2501fdbd0a37SZoran Jovanovic 2502fdbd0a37SZoran Jovanovic template <typename InsnType> 2503fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, 2504fdbd0a37SZoran Jovanovic uint64_t Address, 2505fdbd0a37SZoran Jovanovic const void *Decoder) { 2506fdbd0a37SZoran Jovanovic // We have: 2507fdbd0a37SZoran Jovanovic // 0b000111 ttttt sssss iiiiiiiiiiiiiiii 2508fdbd0a37SZoran Jovanovic // Invalid if rt == 0 2509fdbd0a37SZoran Jovanovic // BGTZALC_MMR6 if rs == 0 && rt != 0 2510fdbd0a37SZoran Jovanovic // BLTZALC_MMR6 if rs != 0 && rs == rt 2511fdbd0a37SZoran Jovanovic // BLTUC_MMR6 if rs != 0 && rs != rt 2512fdbd0a37SZoran Jovanovic 2513fdbd0a37SZoran Jovanovic InsnType Rt = fieldFromInstruction(insn, 21, 5); 2514fdbd0a37SZoran Jovanovic InsnType Rs = fieldFromInstruction(insn, 16, 5); 2515f0ed16eaSHrvoje Varga InsnType Imm = 0; 2516fdbd0a37SZoran Jovanovic bool HasRs = false; 2517fdbd0a37SZoran Jovanovic bool HasRt = false; 2518fdbd0a37SZoran Jovanovic 2519fdbd0a37SZoran Jovanovic if (Rt == 0) 2520fdbd0a37SZoran Jovanovic return MCDisassembler::Fail; 2521fdbd0a37SZoran Jovanovic else if (Rs == 0) { 2522fdbd0a37SZoran Jovanovic MI.setOpcode(Mips::BGTZALC_MMR6); 2523fdbd0a37SZoran Jovanovic HasRt = true; 2524f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 2525fdbd0a37SZoran Jovanovic } 2526fdbd0a37SZoran Jovanovic else if (Rs == Rt) { 2527fdbd0a37SZoran Jovanovic MI.setOpcode(Mips::BLTZALC_MMR6); 2528fdbd0a37SZoran Jovanovic HasRs = true; 2529f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 2530fdbd0a37SZoran Jovanovic } 2531fdbd0a37SZoran Jovanovic else { 2532fdbd0a37SZoran Jovanovic MI.setOpcode(Mips::BLTUC_MMR6); 2533fdbd0a37SZoran Jovanovic HasRs = true; 2534fdbd0a37SZoran Jovanovic HasRt = true; 2535f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 2536fdbd0a37SZoran Jovanovic } 2537fdbd0a37SZoran Jovanovic 2538fdbd0a37SZoran Jovanovic if (HasRs) 2539fdbd0a37SZoran Jovanovic MI.addOperand( 2540fdbd0a37SZoran Jovanovic MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); 2541fdbd0a37SZoran Jovanovic 2542fdbd0a37SZoran Jovanovic if (HasRt) 2543fdbd0a37SZoran Jovanovic MI.addOperand( 2544fdbd0a37SZoran Jovanovic MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); 2545fdbd0a37SZoran Jovanovic 2546fdbd0a37SZoran Jovanovic MI.addOperand(MCOperand::createImm(Imm)); 2547fdbd0a37SZoran Jovanovic 2548fdbd0a37SZoran Jovanovic return MCDisassembler::Success; 2549fdbd0a37SZoran Jovanovic } 2550fdbd0a37SZoran Jovanovic 2551fdbd0a37SZoran Jovanovic template <typename InsnType> 2552fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, 2553fdbd0a37SZoran Jovanovic uint64_t Address, 2554fdbd0a37SZoran Jovanovic const void *Decoder) { 2555fdbd0a37SZoran Jovanovic // We have: 2556fdbd0a37SZoran Jovanovic // 0b000110 ttttt sssss iiiiiiiiiiiiiiii 2557f0ed16eaSHrvoje Varga // Invalid if rt == 0 2558fdbd0a37SZoran Jovanovic // BLEZALC_MMR6 if rs == 0 && rt != 0 2559fdbd0a37SZoran Jovanovic // BGEZALC_MMR6 if rs == rt && rt != 0 2560fdbd0a37SZoran Jovanovic // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0 2561fdbd0a37SZoran Jovanovic 2562fdbd0a37SZoran Jovanovic InsnType Rt = fieldFromInstruction(insn, 21, 5); 2563fdbd0a37SZoran Jovanovic InsnType Rs = fieldFromInstruction(insn, 16, 5); 2564f0ed16eaSHrvoje Varga InsnType Imm = 0; 2565fdbd0a37SZoran Jovanovic bool HasRs = false; 2566fdbd0a37SZoran Jovanovic 2567fdbd0a37SZoran Jovanovic if (Rt == 0) 2568fdbd0a37SZoran Jovanovic return MCDisassembler::Fail; 2569f0ed16eaSHrvoje Varga else if (Rs == 0) { 2570fdbd0a37SZoran Jovanovic MI.setOpcode(Mips::BLEZALC_MMR6); 2571f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 2572f0ed16eaSHrvoje Varga } 2573f0ed16eaSHrvoje Varga else if (Rs == Rt) { 2574fdbd0a37SZoran Jovanovic MI.setOpcode(Mips::BGEZALC_MMR6); 2575f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 2576f0ed16eaSHrvoje Varga } 2577fdbd0a37SZoran Jovanovic else { 2578fdbd0a37SZoran Jovanovic HasRs = true; 2579fdbd0a37SZoran Jovanovic MI.setOpcode(Mips::BGEUC_MMR6); 2580f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 2581fdbd0a37SZoran Jovanovic } 2582fdbd0a37SZoran Jovanovic 2583fdbd0a37SZoran Jovanovic if (HasRs) 2584fdbd0a37SZoran Jovanovic MI.addOperand( 2585fdbd0a37SZoran Jovanovic MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); 2586fdbd0a37SZoran Jovanovic MI.addOperand( 2587fdbd0a37SZoran Jovanovic MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); 2588fdbd0a37SZoran Jovanovic 2589fdbd0a37SZoran Jovanovic MI.addOperand(MCOperand::createImm(Imm)); 2590fdbd0a37SZoran Jovanovic 2591fdbd0a37SZoran Jovanovic return MCDisassembler::Success; 2592fdbd0a37SZoran Jovanovic } 2593