1926883e1SEugene Zelenko //===- MipsDisassembler.cpp - Disassembler for Mips -----------------------===// 271928e68SAkira Hatanaka // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 671928e68SAkira Hatanaka // 771928e68SAkira Hatanaka //===----------------------------------------------------------------------===// 871928e68SAkira Hatanaka // 971928e68SAkira Hatanaka // This file is part of the Mips Disassembler. 1071928e68SAkira Hatanaka // 1171928e68SAkira Hatanaka //===----------------------------------------------------------------------===// 1271928e68SAkira Hatanaka 1379220eaeSEugene Zelenko #include "MCTargetDesc/MipsMCTargetDesc.h" 1471928e68SAkira Hatanaka #include "Mips.h" 15313b7815SRichard Trieu #include "TargetInfo/MipsTargetInfo.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 270*56e4ea2bSSimon Atanasyan // DecodeJumpTargetXMM - Decode microMIPS jump and link exchange target, 271*56e4ea2bSSimon Atanasyan // which is shifted left by 2 bit. 272*56e4ea2bSSimon Atanasyan static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst, 273*56e4ea2bSSimon Atanasyan unsigned Insn, 274*56e4ea2bSSimon Atanasyan uint64_t Address, 275*56e4ea2bSSimon Atanasyan const void *Decoder); 276*56e4ea2bSSimon Atanasyan 27771928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 27871928e68SAkira Hatanaka unsigned Insn, 27971928e68SAkira Hatanaka uint64_t Address, 28071928e68SAkira Hatanaka const void *Decoder); 28171928e68SAkira Hatanaka 282e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst, 283e4e83a7bSDaniel Sanders unsigned Insn, 284e4e83a7bSDaniel Sanders uint64_t Address, 285e4e83a7bSDaniel Sanders const void *Decoder); 286e4e83a7bSDaniel Sanders 2873c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst, 2883c88fbd3SHrvoje Varga unsigned Insn, 2893c88fbd3SHrvoje Varga uint64_t Address, 2903c88fbd3SHrvoje Varga const void *Decoder); 2913c88fbd3SHrvoje Varga 29279220eaeSEugene Zelenko static DecodeStatus DecodeCacheOp(MCInst &Inst, unsigned Insn, uint64_t Address, 29392db6b78SDaniel Sanders const void *Decoder); 29492db6b78SDaniel Sanders 295e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, 296df464ae2SVladimir Medic unsigned Insn, 297df464ae2SVladimir Medic uint64_t Address, 298df464ae2SVladimir Medic const void *Decoder); 299df464ae2SVladimir Medic 300ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst, 301ab6d1cceSJozef Kolek unsigned Insn, 302ab6d1cceSJozef Kolek uint64_t Address, 303ab6d1cceSJozef Kolek const void *Decoder); 304ab6d1cceSJozef Kolek 305d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst, 306d9790793SZoran Jovanovic unsigned Insn, 307d9790793SZoran Jovanovic uint64_t Address, 308d9790793SZoran Jovanovic const void *Decoder); 309d9790793SZoran Jovanovic 310b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 311b4484d62SDaniel Sanders unsigned Insn, 312b4484d62SDaniel Sanders uint64_t Address, 313b4484d62SDaniel Sanders const void *Decoder); 314b4484d62SDaniel Sanders 315eac9301cSSimon Dardis static DecodeStatus DecodeSyncI_MM(MCInst &Inst, 316eac9301cSSimon Dardis unsigned Insn, 317eac9301cSSimon Dardis uint64_t Address, 318eac9301cSSimon Dardis const void *Decoder); 319eac9301cSSimon Dardis 32018148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst, 32118148671SHrvoje Varga unsigned Insn, 32218148671SHrvoje Varga uint64_t Address, 32318148671SHrvoje Varga const void *Decoder); 32418148671SHrvoje Varga 325fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 326fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder); 327fe0bf9f6SMatheus Almeida 328315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 329315e7ecaSJozef Kolek unsigned Insn, 330315e7ecaSJozef Kolek uint64_t Address, 331315e7ecaSJozef Kolek const void *Decoder); 332315e7ecaSJozef Kolek 33312c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, 33412c6982bSJozef Kolek unsigned Insn, 33512c6982bSJozef Kolek uint64_t Address, 33612c6982bSJozef Kolek const void *Decoder); 33712c6982bSJozef Kolek 338e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, 339e10a02ecSJozef Kolek unsigned Insn, 340e10a02ecSJozef Kolek uint64_t Address, 341e10a02ecSJozef Kolek const void *Decoder); 342e10a02ecSJozef Kolek 343d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, 344d68d424aSJozef Kolek unsigned Insn, 345d68d424aSJozef Kolek uint64_t Address, 346d68d424aSJozef Kolek const void *Decoder); 347d68d424aSJozef Kolek 348a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst, 349a6593ff6SZoran Jovanovic unsigned Insn, 350a6593ff6SZoran Jovanovic uint64_t Address, 351a6593ff6SZoran Jovanovic const void *Decoder); 352a6593ff6SZoran Jovanovic 353dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 354dde3d582SVladimir Medic unsigned Insn, 355dde3d582SVladimir Medic uint64_t Address, 356dde3d582SVladimir Medic const void *Decoder); 357dde3d582SVladimir Medic 358dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm16(MCInst &Inst, 359dde3d582SVladimir Medic unsigned Insn, 360dde3d582SVladimir Medic uint64_t Address, 361dde3d582SVladimir Medic const void *Decoder); 362dde3d582SVladimir Medic 36371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn, 36471928e68SAkira Hatanaka uint64_t Address, 36571928e68SAkira Hatanaka const void *Decoder); 36671928e68SAkira Hatanaka 367cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemMMR2(MCInst &Inst, unsigned Insn, 368cba9f80bSZlatko Buljan uint64_t Address, 369cba9f80bSZlatko Buljan const void *Decoder); 370cba9f80bSZlatko Buljan 37179220eaeSEugene Zelenko static DecodeStatus DecodeFMem2(MCInst &Inst, unsigned Insn, uint64_t Address, 37292db6b78SDaniel Sanders const void *Decoder); 37392db6b78SDaniel Sanders 37479220eaeSEugene Zelenko static DecodeStatus DecodeFMem3(MCInst &Inst, unsigned Insn, uint64_t Address, 37592db6b78SDaniel Sanders const void *Decoder); 37692db6b78SDaniel Sanders 377435cf8a4SVladimir Medic static DecodeStatus DecodeFMemCop2R6(MCInst &Inst, unsigned Insn, 37879220eaeSEugene Zelenko uint64_t Address, const void *Decoder); 379435cf8a4SVladimir Medic 380cba9f80bSZlatko Buljan static DecodeStatus DecodeFMemCop2MMR6(MCInst &Inst, unsigned Insn, 381cba9f80bSZlatko Buljan uint64_t Address, 382cba9f80bSZlatko Buljan const void *Decoder); 383cba9f80bSZlatko Buljan 3846a803f61SDaniel Sanders static DecodeStatus DecodeSpecial3LlSc(MCInst &Inst, 3856a803f61SDaniel Sanders unsigned Insn, 3866a803f61SDaniel Sanders uint64_t Address, 3876a803f61SDaniel Sanders const void *Decoder); 3886a803f61SDaniel Sanders 389aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 390aa2b9278SJozef Kolek unsigned Value, 391aa2b9278SJozef Kolek uint64_t Address, 392aa2b9278SJozef Kolek const void *Decoder); 393aa2b9278SJozef Kolek 39497297770SDaniel Sanders static DecodeStatus DecodeLi16Imm(MCInst &Inst, 395aa2b9278SJozef Kolek unsigned Value, 396aa2b9278SJozef Kolek uint64_t Address, 397aa2b9278SJozef Kolek const void *Decoder); 398aa2b9278SJozef Kolek 3996b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, 4006b28f09dSZoran Jovanovic unsigned Value, 4016b28f09dSZoran Jovanovic uint64_t Address, 4026b28f09dSZoran Jovanovic const void *Decoder); 4036b28f09dSZoran Jovanovic 40419b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale> 40519b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, 40619b7f76aSDaniel Sanders uint64_t Address, 40719b7f76aSDaniel Sanders const void *Decoder); 40819b7f76aSDaniel Sanders 409ea4f653dSDaniel Sanders template <unsigned Bits, int Offset> 410ea4f653dSDaniel Sanders static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value, 41119b7f76aSDaniel Sanders uint64_t Address, 41219b7f76aSDaniel Sanders const void *Decoder) { 41319b7f76aSDaniel Sanders return DecodeUImmWithOffsetAndScale<Bits, Offset, 1>(Inst, Value, Address, 41419b7f76aSDaniel Sanders Decoder); 41519b7f76aSDaniel Sanders } 416779c5937SMatheus Almeida 41797297770SDaniel Sanders template <unsigned Bits, int Offset = 0, int ScaleBy = 1> 41897297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value, 41997297770SDaniel Sanders uint64_t Address, 42097297770SDaniel Sanders const void *Decoder); 42178e89020SDaniel Sanders 42271928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 42371928e68SAkira Hatanaka unsigned Insn, 42471928e68SAkira Hatanaka uint64_t Address, 42571928e68SAkira Hatanaka const void *Decoder); 42671928e68SAkira Hatanaka 427b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 428b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder); 429b59e1a41SDaniel Sanders 4302855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 4312855142aSZoran Jovanovic uint64_t Address, const void *Decoder); 4322855142aSZoran Jovanovic 433b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 434b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 435b682ddf3SVladimir Medic 436b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 437b682ddf3SVladimir Medic uint64_t Address, const void *Decoder); 438b682ddf3SVladimir Medic 4392c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, 4402c6d7320SJozef Kolek uint64_t Address, const void *Decoder); 4412c6d7320SJozef Kolek 442b50ccf8eSDaniel Sanders /// INSVE_[BHWD] have an implicit operand that the generated decoder doesn't 443b50ccf8eSDaniel Sanders /// handle. 444b50ccf8eSDaniel Sanders template <typename InsnType> 445b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 446b50ccf8eSDaniel Sanders const void *Decoder); 4475c582b2fSDaniel Sanders 4485c582b2fSDaniel Sanders template <typename InsnType> 449cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address, 450cf060794SSimon Dardis const void *Decoder); 451cf060794SSimon Dardis 452cf060794SSimon Dardis template <typename InsnType> 453cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address, 454cf060794SSimon Dardis const void *Decoder); 455cf060794SSimon Dardis 456cf060794SSimon Dardis template <typename InsnType> 457b3fd189cSSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address, 458b3fd189cSSimon Dardis const void *Decoder); 459b3fd189cSSimon Dardis 460b3fd189cSSimon Dardis template <typename InsnType> 461b3fd189cSSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address, 462b3fd189cSSimon Dardis const void *Decoder); 463b3fd189cSSimon Dardis 464b3fd189cSSimon Dardis template <typename InsnType> 4655c582b2fSDaniel Sanders static DecodeStatus 4665c582b2fSDaniel Sanders DecodeAddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4675c582b2fSDaniel Sanders const void *Decoder); 4685c582b2fSDaniel Sanders 4695c582b2fSDaniel Sanders template <typename InsnType> 4705c582b2fSDaniel Sanders static DecodeStatus 471c962c493SHrvoje Varga DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, 472c962c493SHrvoje Varga const void *Decoder); 473c962c493SHrvoje Varga 474c962c493SHrvoje Varga template <typename InsnType> 475c962c493SHrvoje Varga static DecodeStatus 4765c582b2fSDaniel Sanders DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4775c582b2fSDaniel Sanders const void *Decoder); 4785c582b2fSDaniel Sanders 4795c582b2fSDaniel Sanders template <typename InsnType> 4805c582b2fSDaniel Sanders static DecodeStatus 481c962c493SHrvoje Varga DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, 482c962c493SHrvoje Varga const void *Decoder); 483c962c493SHrvoje Varga 484c962c493SHrvoje Varga template <typename InsnType> 485c962c493SHrvoje Varga static DecodeStatus 486f0ed16eaSHrvoje Varga DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, 487f0ed16eaSHrvoje Varga const void *Decoder); 488f0ed16eaSHrvoje Varga 489f0ed16eaSHrvoje Varga template <typename InsnType> 490f0ed16eaSHrvoje Varga static DecodeStatus 491f0ed16eaSHrvoje Varga DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, 492f0ed16eaSHrvoje Varga const void *Decoder); 493f0ed16eaSHrvoje Varga 494f0ed16eaSHrvoje Varga template <typename InsnType> 495f0ed16eaSHrvoje Varga static DecodeStatus 4965c582b2fSDaniel Sanders DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 4975c582b2fSDaniel Sanders const void *Decoder); 4985c582b2fSDaniel Sanders 4995c582b2fSDaniel Sanders template <typename InsnType> 5005c582b2fSDaniel Sanders static DecodeStatus 5015c582b2fSDaniel Sanders DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 5025c582b2fSDaniel Sanders const void *Decoder); 5035c582b2fSDaniel Sanders 5045c582b2fSDaniel Sanders template <typename InsnType> 5055c582b2fSDaniel Sanders static DecodeStatus 5065c582b2fSDaniel Sanders DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 5075c582b2fSDaniel Sanders const void *Decoder); 5085c582b2fSDaniel Sanders 50928a0ca07SZoran Jovanovic template <typename InsnType> 51028a0ca07SZoran Jovanovic static DecodeStatus 51128a0ca07SZoran Jovanovic DecodeBlezGroupBranch(MCInst &MI, InsnType insn, uint64_t Address, 51228a0ca07SZoran Jovanovic const void *Decoder); 51328a0ca07SZoran Jovanovic 514fdbd0a37SZoran Jovanovic template <typename InsnType> 515fdbd0a37SZoran Jovanovic static DecodeStatus 516fdbd0a37SZoran Jovanovic DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, 517fdbd0a37SZoran Jovanovic const void *Decoder); 518fdbd0a37SZoran Jovanovic 519fdbd0a37SZoran Jovanovic template <typename InsnType> 520fdbd0a37SZoran Jovanovic static DecodeStatus 521fdbd0a37SZoran Jovanovic DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, uint64_t Address, 522fdbd0a37SZoran Jovanovic const void *Decoder); 523fdbd0a37SZoran Jovanovic 5246f83ae38SSimon Dardis template <typename InsnType> 5256f83ae38SSimon Dardis static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address, 5266f83ae38SSimon Dardis const void *Decoder); 5276f83ae38SSimon Dardis 52855e44673SSimon Dardis template <typename InsnType> 52955e44673SSimon Dardis static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address, 53055e44673SSimon Dardis const void *Decoder); 53155e44673SSimon Dardis 5323408caf6SPetar Jovanovic template <typename InsnType> 5333408caf6SPetar Jovanovic static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address, 5343408caf6SPetar Jovanovic const void *Decoder); 5353408caf6SPetar Jovanovic 536a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Insn, 537a4c4b5fcSZoran Jovanovic uint64_t Address, 538a4c4b5fcSZoran Jovanovic const void *Decoder); 539a4c4b5fcSZoran Jovanovic 540f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 541f9a02500SZoran Jovanovic uint64_t Address, 542f9a02500SZoran Jovanovic const void *Decoder); 543f9a02500SZoran Jovanovic 544169df4e2SSimon Dardis static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair, 54541688679SZoran Jovanovic uint64_t Address, 54641688679SZoran Jovanovic const void *Decoder); 54741688679SZoran Jovanovic 548852dd83bSSimon Atanasyan static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn, 549852dd83bSSimon Atanasyan uint64_t Address, const void *Decoder); 550852dd83bSSimon Atanasyan 55171928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler( 55271928e68SAkira Hatanaka const Target &T, 553a1bc0f56SLang Hames const MCSubtargetInfo &STI, 554a1bc0f56SLang Hames MCContext &Ctx) { 555a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, true); 55671928e68SAkira Hatanaka } 55771928e68SAkira Hatanaka 55871928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler( 55971928e68SAkira Hatanaka const Target &T, 560a1bc0f56SLang Hames const MCSubtargetInfo &STI, 561a1bc0f56SLang Hames MCContext &Ctx) { 562a1bc0f56SLang Hames return new MipsDisassembler(STI, Ctx, false); 56371928e68SAkira Hatanaka } 56471928e68SAkira Hatanaka 5654b0b2619STom Stellard extern "C" void LLVMInitializeMipsDisassembler() { 56671928e68SAkira Hatanaka // Register the disassembler. 567f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getTheMipsTarget(), 56871928e68SAkira Hatanaka createMipsDisassembler); 569f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getTheMipselTarget(), 57071928e68SAkira Hatanaka createMipselDisassembler); 571f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getTheMips64Target(), 572a19216c8SDaniel Sanders createMipsDisassembler); 573f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getTheMips64elTarget(), 574a19216c8SDaniel Sanders createMipselDisassembler); 57571928e68SAkira Hatanaka } 57671928e68SAkira Hatanaka 57771928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc" 57871928e68SAkira Hatanaka 5795c582b2fSDaniel Sanders static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) { 580a19216c8SDaniel Sanders const MipsDisassembler *Dis = static_cast<const MipsDisassembler*>(D); 5815c582b2fSDaniel Sanders const MCRegisterInfo *RegInfo = Dis->getContext().getRegisterInfo(); 5825c582b2fSDaniel Sanders return *(RegInfo->getRegClass(RC).begin() + RegNo); 5835c582b2fSDaniel Sanders } 5845c582b2fSDaniel Sanders 585b50ccf8eSDaniel Sanders template <typename InsnType> 586b50ccf8eSDaniel Sanders static DecodeStatus DecodeINSVE_DF(MCInst &MI, InsnType insn, uint64_t Address, 587b50ccf8eSDaniel Sanders const void *Decoder) { 58879220eaeSEugene Zelenko using DecodeFN = DecodeStatus (*)(MCInst &, unsigned, uint64_t, const void *); 58979220eaeSEugene Zelenko 590b50ccf8eSDaniel Sanders // The size of the n field depends on the element size 591b50ccf8eSDaniel Sanders // The register class also depends on this. 592b50ccf8eSDaniel Sanders InsnType tmp = fieldFromInstruction(insn, 17, 5); 593b50ccf8eSDaniel Sanders unsigned NSize = 0; 594b50ccf8eSDaniel Sanders DecodeFN RegDecoder = nullptr; 595b50ccf8eSDaniel Sanders if ((tmp & 0x18) == 0x00) { // INSVE_B 596b50ccf8eSDaniel Sanders NSize = 4; 597b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128BRegisterClass; 598b50ccf8eSDaniel Sanders } else if ((tmp & 0x1c) == 0x10) { // INSVE_H 599b50ccf8eSDaniel Sanders NSize = 3; 600b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128HRegisterClass; 601b50ccf8eSDaniel Sanders } else if ((tmp & 0x1e) == 0x18) { // INSVE_W 602b50ccf8eSDaniel Sanders NSize = 2; 603b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128WRegisterClass; 604b50ccf8eSDaniel Sanders } else if ((tmp & 0x1f) == 0x1c) { // INSVE_D 605b50ccf8eSDaniel Sanders NSize = 1; 606b50ccf8eSDaniel Sanders RegDecoder = DecodeMSA128DRegisterClass; 607b50ccf8eSDaniel Sanders } else 608b50ccf8eSDaniel Sanders llvm_unreachable("Invalid encoding"); 609b50ccf8eSDaniel Sanders 610b50ccf8eSDaniel Sanders assert(NSize != 0 && RegDecoder != nullptr); 611b50ccf8eSDaniel Sanders 612b50ccf8eSDaniel Sanders // $wd 613b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 6, 5); 614b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 615b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 616b50ccf8eSDaniel Sanders // $wd_in 617b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 618b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 619b50ccf8eSDaniel Sanders // $n 620b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 16, NSize); 621e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(tmp)); 622b50ccf8eSDaniel Sanders // $ws 623b50ccf8eSDaniel Sanders tmp = fieldFromInstruction(insn, 11, 5); 624b50ccf8eSDaniel Sanders if (RegDecoder(MI, tmp, Address, Decoder) == MCDisassembler::Fail) 625b50ccf8eSDaniel Sanders return MCDisassembler::Fail; 626b50ccf8eSDaniel Sanders // $n2 627e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(0)); 628b50ccf8eSDaniel Sanders 629b50ccf8eSDaniel Sanders return MCDisassembler::Success; 630b50ccf8eSDaniel Sanders } 631b50ccf8eSDaniel Sanders 6325c582b2fSDaniel Sanders template <typename InsnType> 633cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATIMMR6(MCInst &MI, InsnType insn, uint64_t Address, 634cf060794SSimon Dardis const void *Decoder) { 635b3fd189cSSimon Dardis InsnType Rs = fieldFromInstruction(insn, 16, 5); 636cf060794SSimon Dardis InsnType Imm = fieldFromInstruction(insn, 0, 16); 637cf060794SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, 638b3fd189cSSimon Dardis Rs))); 639cf060794SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, 640b3fd189cSSimon Dardis Rs))); 641cf060794SSimon Dardis MI.addOperand(MCOperand::createImm(Imm)); 642cf060794SSimon Dardis 643cf060794SSimon Dardis return MCDisassembler::Success; 644cf060794SSimon Dardis } 645cf060794SSimon Dardis 646cf060794SSimon Dardis template <typename InsnType> 647cf060794SSimon Dardis static DecodeStatus DecodeDAHIDATI(MCInst &MI, InsnType insn, uint64_t Address, 648cf060794SSimon Dardis const void *Decoder) { 649b3fd189cSSimon Dardis InsnType Rs = fieldFromInstruction(insn, 21, 5); 650cf060794SSimon Dardis InsnType Imm = fieldFromInstruction(insn, 0, 16); 651cf060794SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, 652b3fd189cSSimon Dardis Rs))); 653cf060794SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, 654b3fd189cSSimon Dardis Rs))); 655cf060794SSimon Dardis MI.addOperand(MCOperand::createImm(Imm)); 656cf060794SSimon Dardis 657cf060794SSimon Dardis return MCDisassembler::Success; 658cf060794SSimon Dardis } 659cf060794SSimon Dardis 660cf060794SSimon Dardis template <typename InsnType> 6615c582b2fSDaniel Sanders static DecodeStatus DecodeAddiGroupBranch(MCInst &MI, InsnType insn, 6625c582b2fSDaniel Sanders uint64_t Address, 6635c582b2fSDaniel Sanders const void *Decoder) { 6645c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 6655c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 6665c582b2fSDaniel Sanders // ISA's instead). 6675c582b2fSDaniel Sanders // 6685c582b2fSDaniel Sanders // We have: 6695c582b2fSDaniel Sanders // 0b001000 sssss ttttt iiiiiiiiiiiiiiii 6705c582b2fSDaniel Sanders // BOVC if rs >= rt 6715c582b2fSDaniel Sanders // BEQZALC if rs == 0 && rt != 0 6725c582b2fSDaniel Sanders // BEQC if rs < rt && rs != 0 6735c582b2fSDaniel Sanders 6745c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 6755c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 676672c710dSSagar Thakur int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 6775c582b2fSDaniel Sanders bool HasRs = false; 6785c582b2fSDaniel Sanders 6795c582b2fSDaniel Sanders if (Rs >= Rt) { 6805c582b2fSDaniel Sanders MI.setOpcode(Mips::BOVC); 6815c582b2fSDaniel Sanders HasRs = true; 6825c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 6835c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQC); 6845c582b2fSDaniel Sanders HasRs = true; 6855c582b2fSDaniel Sanders } else 6865c582b2fSDaniel Sanders MI.setOpcode(Mips::BEQZALC); 6875c582b2fSDaniel Sanders 6885c582b2fSDaniel Sanders if (HasRs) 689e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 6905c582b2fSDaniel Sanders Rs))); 6915c582b2fSDaniel Sanders 692e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 6935c582b2fSDaniel Sanders Rt))); 694e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 6955c582b2fSDaniel Sanders 6965c582b2fSDaniel Sanders return MCDisassembler::Success; 6975c582b2fSDaniel Sanders } 6985c582b2fSDaniel Sanders 6995c582b2fSDaniel Sanders template <typename InsnType> 700c962c493SHrvoje Varga static DecodeStatus DecodePOP35GroupBranchMMR6(MCInst &MI, InsnType insn, 701c962c493SHrvoje Varga uint64_t Address, 702c962c493SHrvoje Varga const void *Decoder) { 703c962c493SHrvoje Varga InsnType Rt = fieldFromInstruction(insn, 21, 5); 704c962c493SHrvoje Varga InsnType Rs = fieldFromInstruction(insn, 16, 5); 705f0ed16eaSHrvoje Varga int64_t Imm = 0; 706c962c493SHrvoje Varga 707c962c493SHrvoje Varga if (Rs >= Rt) { 708c962c493SHrvoje Varga MI.setOpcode(Mips::BOVC_MMR6); 709c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 710c962c493SHrvoje Varga Rt))); 711c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 712c962c493SHrvoje Varga Rs))); 713f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 714c962c493SHrvoje Varga } else if (Rs != 0 && Rs < Rt) { 715c962c493SHrvoje Varga MI.setOpcode(Mips::BEQC_MMR6); 716c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 717c962c493SHrvoje Varga Rs))); 718c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 719c962c493SHrvoje Varga Rt))); 720f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 721c962c493SHrvoje Varga } else { 722c962c493SHrvoje Varga MI.setOpcode(Mips::BEQZALC_MMR6); 723c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 724c962c493SHrvoje Varga Rt))); 725f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 726c962c493SHrvoje Varga } 727c962c493SHrvoje Varga 728c962c493SHrvoje Varga MI.addOperand(MCOperand::createImm(Imm)); 729c962c493SHrvoje Varga 730c962c493SHrvoje Varga return MCDisassembler::Success; 731c962c493SHrvoje Varga } 732c962c493SHrvoje Varga 733c962c493SHrvoje Varga template <typename InsnType> 7345c582b2fSDaniel Sanders static DecodeStatus DecodeDaddiGroupBranch(MCInst &MI, InsnType insn, 7355c582b2fSDaniel Sanders uint64_t Address, 7365c582b2fSDaniel Sanders const void *Decoder) { 7375c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 7385c582b2fSDaniel Sanders // (otherwise we would have matched the ADDI instruction from the earlier 7395c582b2fSDaniel Sanders // ISA's instead). 7405c582b2fSDaniel Sanders // 7415c582b2fSDaniel Sanders // We have: 7425c582b2fSDaniel Sanders // 0b011000 sssss ttttt iiiiiiiiiiiiiiii 7435c582b2fSDaniel Sanders // BNVC if rs >= rt 7445c582b2fSDaniel Sanders // BNEZALC if rs == 0 && rt != 0 7455c582b2fSDaniel Sanders // BNEC if rs < rt && rs != 0 7465c582b2fSDaniel Sanders 7475c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 7485c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 749672c710dSSagar Thakur int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 7505c582b2fSDaniel Sanders bool HasRs = false; 7515c582b2fSDaniel Sanders 7525c582b2fSDaniel Sanders if (Rs >= Rt) { 7535c582b2fSDaniel Sanders MI.setOpcode(Mips::BNVC); 7545c582b2fSDaniel Sanders HasRs = true; 7555c582b2fSDaniel Sanders } else if (Rs != 0 && Rs < Rt) { 7565c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEC); 7575c582b2fSDaniel Sanders HasRs = true; 7585c582b2fSDaniel Sanders } else 7595c582b2fSDaniel Sanders MI.setOpcode(Mips::BNEZALC); 7605c582b2fSDaniel Sanders 7615c582b2fSDaniel Sanders if (HasRs) 762e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 7635c582b2fSDaniel Sanders Rs))); 7645c582b2fSDaniel Sanders 765e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 7665c582b2fSDaniel Sanders Rt))); 767e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 7685c582b2fSDaniel Sanders 7695c582b2fSDaniel Sanders return MCDisassembler::Success; 7705c582b2fSDaniel Sanders } 7715c582b2fSDaniel Sanders 7725c582b2fSDaniel Sanders template <typename InsnType> 773c962c493SHrvoje Varga static DecodeStatus DecodePOP37GroupBranchMMR6(MCInst &MI, InsnType insn, 774c962c493SHrvoje Varga uint64_t Address, 775c962c493SHrvoje Varga const void *Decoder) { 776c962c493SHrvoje Varga InsnType Rt = fieldFromInstruction(insn, 21, 5); 777c962c493SHrvoje Varga InsnType Rs = fieldFromInstruction(insn, 16, 5); 778f0ed16eaSHrvoje Varga int64_t Imm = 0; 779c962c493SHrvoje Varga 780c962c493SHrvoje Varga if (Rs >= Rt) { 781c962c493SHrvoje Varga MI.setOpcode(Mips::BNVC_MMR6); 782c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 783c962c493SHrvoje Varga Rt))); 784c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 785c962c493SHrvoje Varga Rs))); 786f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 787c962c493SHrvoje Varga } else if (Rs != 0 && Rs < Rt) { 788c962c493SHrvoje Varga MI.setOpcode(Mips::BNEC_MMR6); 789c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 790c962c493SHrvoje Varga Rs))); 791c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 792c962c493SHrvoje Varga Rt))); 793f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 794c962c493SHrvoje Varga } else { 795c962c493SHrvoje Varga MI.setOpcode(Mips::BNEZALC_MMR6); 796c962c493SHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 797c962c493SHrvoje Varga Rt))); 798f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 799c962c493SHrvoje Varga } 800c962c493SHrvoje Varga 801c962c493SHrvoje Varga MI.addOperand(MCOperand::createImm(Imm)); 802c962c493SHrvoje Varga 803c962c493SHrvoje Varga return MCDisassembler::Success; 804c962c493SHrvoje Varga } 805c962c493SHrvoje Varga 806c962c493SHrvoje Varga template <typename InsnType> 807f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP65GroupBranchMMR6(MCInst &MI, InsnType insn, 808f0ed16eaSHrvoje Varga uint64_t Address, 809f0ed16eaSHrvoje Varga const void *Decoder) { 810f0ed16eaSHrvoje Varga // We have: 811f0ed16eaSHrvoje Varga // 0b110101 ttttt sssss iiiiiiiiiiiiiiii 812f0ed16eaSHrvoje Varga // Invalid if rt == 0 813f0ed16eaSHrvoje Varga // BGTZC_MMR6 if rs == 0 && rt != 0 814f0ed16eaSHrvoje Varga // BLTZC_MMR6 if rs == rt && rt != 0 815f0ed16eaSHrvoje Varga // BLTC_MMR6 if rs != rt && rs != 0 && rt != 0 816f0ed16eaSHrvoje Varga 817f0ed16eaSHrvoje Varga InsnType Rt = fieldFromInstruction(insn, 21, 5); 818f0ed16eaSHrvoje Varga InsnType Rs = fieldFromInstruction(insn, 16, 5); 819f0ed16eaSHrvoje Varga int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 820f0ed16eaSHrvoje Varga bool HasRs = false; 821f0ed16eaSHrvoje Varga 822f0ed16eaSHrvoje Varga if (Rt == 0) 823f0ed16eaSHrvoje Varga return MCDisassembler::Fail; 824f0ed16eaSHrvoje Varga else if (Rs == 0) 825f0ed16eaSHrvoje Varga MI.setOpcode(Mips::BGTZC_MMR6); 826f0ed16eaSHrvoje Varga else if (Rs == Rt) 827f0ed16eaSHrvoje Varga MI.setOpcode(Mips::BLTZC_MMR6); 828f0ed16eaSHrvoje Varga else { 829f0ed16eaSHrvoje Varga MI.setOpcode(Mips::BLTC_MMR6); 830f0ed16eaSHrvoje Varga HasRs = true; 831f0ed16eaSHrvoje Varga } 832f0ed16eaSHrvoje Varga 833f0ed16eaSHrvoje Varga if (HasRs) 834f0ed16eaSHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 835f0ed16eaSHrvoje Varga Rs))); 836f0ed16eaSHrvoje Varga 837f0ed16eaSHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 838f0ed16eaSHrvoje Varga Rt))); 839f0ed16eaSHrvoje Varga 840f0ed16eaSHrvoje Varga MI.addOperand(MCOperand::createImm(Imm)); 841f0ed16eaSHrvoje Varga 842f0ed16eaSHrvoje Varga return MCDisassembler::Success; 843f0ed16eaSHrvoje Varga } 844f0ed16eaSHrvoje Varga 845f0ed16eaSHrvoje Varga template <typename InsnType> 846f0ed16eaSHrvoje Varga static DecodeStatus DecodePOP75GroupBranchMMR6(MCInst &MI, InsnType insn, 847f0ed16eaSHrvoje Varga uint64_t Address, 848f0ed16eaSHrvoje Varga const void *Decoder) { 849f0ed16eaSHrvoje Varga // We have: 850f0ed16eaSHrvoje Varga // 0b111101 ttttt sssss iiiiiiiiiiiiiiii 851f0ed16eaSHrvoje Varga // Invalid if rt == 0 852f0ed16eaSHrvoje Varga // BLEZC_MMR6 if rs == 0 && rt != 0 853f0ed16eaSHrvoje Varga // BGEZC_MMR6 if rs == rt && rt != 0 854f0ed16eaSHrvoje Varga // BGEC_MMR6 if rs != rt && rs != 0 && rt != 0 855f0ed16eaSHrvoje Varga 856f0ed16eaSHrvoje Varga InsnType Rt = fieldFromInstruction(insn, 21, 5); 857f0ed16eaSHrvoje Varga InsnType Rs = fieldFromInstruction(insn, 16, 5); 858f0ed16eaSHrvoje Varga int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 859f0ed16eaSHrvoje Varga bool HasRs = false; 860f0ed16eaSHrvoje Varga 861f0ed16eaSHrvoje Varga if (Rt == 0) 862f0ed16eaSHrvoje Varga return MCDisassembler::Fail; 863f0ed16eaSHrvoje Varga else if (Rs == 0) 864f0ed16eaSHrvoje Varga MI.setOpcode(Mips::BLEZC_MMR6); 865f0ed16eaSHrvoje Varga else if (Rs == Rt) 866f0ed16eaSHrvoje Varga MI.setOpcode(Mips::BGEZC_MMR6); 867f0ed16eaSHrvoje Varga else { 868f0ed16eaSHrvoje Varga HasRs = true; 869f0ed16eaSHrvoje Varga MI.setOpcode(Mips::BGEC_MMR6); 870f0ed16eaSHrvoje Varga } 871f0ed16eaSHrvoje Varga 872f0ed16eaSHrvoje Varga if (HasRs) 873f0ed16eaSHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 874f0ed16eaSHrvoje Varga Rs))); 875f0ed16eaSHrvoje Varga 876f0ed16eaSHrvoje Varga MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 877f0ed16eaSHrvoje Varga Rt))); 878f0ed16eaSHrvoje Varga 879f0ed16eaSHrvoje Varga MI.addOperand(MCOperand::createImm(Imm)); 880f0ed16eaSHrvoje Varga 881f0ed16eaSHrvoje Varga return MCDisassembler::Success; 882f0ed16eaSHrvoje Varga } 883f0ed16eaSHrvoje Varga 884f0ed16eaSHrvoje Varga template <typename InsnType> 8855c582b2fSDaniel Sanders static DecodeStatus DecodeBlezlGroupBranch(MCInst &MI, InsnType insn, 8865c582b2fSDaniel Sanders uint64_t Address, 8875c582b2fSDaniel Sanders const void *Decoder) { 8885c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 8895c582b2fSDaniel Sanders // (otherwise we would have matched the BLEZL instruction from the earlier 8905c582b2fSDaniel Sanders // ISA's instead). 8915c582b2fSDaniel Sanders // 8925c582b2fSDaniel Sanders // We have: 8935c582b2fSDaniel Sanders // 0b010110 sssss ttttt iiiiiiiiiiiiiiii 8945c582b2fSDaniel Sanders // Invalid if rs == 0 8955c582b2fSDaniel Sanders // BLEZC if rs == 0 && rt != 0 8965c582b2fSDaniel Sanders // BGEZC if rs == rt && rt != 0 8975c582b2fSDaniel Sanders // BGEC if rs != rt && rs != 0 && rt != 0 8985c582b2fSDaniel Sanders 8995c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 9005c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 901672c710dSSagar Thakur int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 90228a0ca07SZoran Jovanovic bool HasRs = false; 9035c582b2fSDaniel Sanders 9045c582b2fSDaniel Sanders if (Rt == 0) 9055c582b2fSDaniel Sanders return MCDisassembler::Fail; 9065c582b2fSDaniel Sanders else if (Rs == 0) 9075c582b2fSDaniel Sanders MI.setOpcode(Mips::BLEZC); 9085c582b2fSDaniel Sanders else if (Rs == Rt) 9095c582b2fSDaniel Sanders MI.setOpcode(Mips::BGEZC); 91028a0ca07SZoran Jovanovic else { 91128a0ca07SZoran Jovanovic HasRs = true; 91228a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEC); 91328a0ca07SZoran Jovanovic } 91428a0ca07SZoran Jovanovic 91528a0ca07SZoran Jovanovic if (HasRs) 916e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 91728a0ca07SZoran Jovanovic Rs))); 9185c582b2fSDaniel Sanders 919e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 9205c582b2fSDaniel Sanders Rt))); 9215c582b2fSDaniel Sanders 922e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 9235c582b2fSDaniel Sanders 9245c582b2fSDaniel Sanders return MCDisassembler::Success; 9255c582b2fSDaniel Sanders } 9265c582b2fSDaniel Sanders 9275c582b2fSDaniel Sanders template <typename InsnType> 9285c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzlGroupBranch(MCInst &MI, InsnType insn, 9295c582b2fSDaniel Sanders uint64_t Address, 9305c582b2fSDaniel Sanders const void *Decoder) { 9315c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 9325c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZL instruction from the earlier 9335c582b2fSDaniel Sanders // ISA's instead). 9345c582b2fSDaniel Sanders // 9355c582b2fSDaniel Sanders // We have: 9365c582b2fSDaniel Sanders // 0b010111 sssss ttttt iiiiiiiiiiiiiiii 9375c582b2fSDaniel Sanders // Invalid if rs == 0 9385c582b2fSDaniel Sanders // BGTZC if rs == 0 && rt != 0 9395c582b2fSDaniel Sanders // BLTZC if rs == rt && rt != 0 9405c582b2fSDaniel Sanders // BLTC if rs != rt && rs != 0 && rt != 0 9415c582b2fSDaniel Sanders 9425c14b069SZoran Jovanovic bool HasRs = false; 9435c14b069SZoran Jovanovic 9445c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 9455c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 946672c710dSSagar Thakur int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 9475c582b2fSDaniel Sanders 9485c582b2fSDaniel Sanders if (Rt == 0) 9495c582b2fSDaniel Sanders return MCDisassembler::Fail; 9505c582b2fSDaniel Sanders else if (Rs == 0) 9515c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZC); 9525c582b2fSDaniel Sanders else if (Rs == Rt) 9535c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZC); 9545c14b069SZoran Jovanovic else { 9555c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTC); 9565c14b069SZoran Jovanovic HasRs = true; 9575c14b069SZoran Jovanovic } 9585c14b069SZoran Jovanovic 9595c14b069SZoran Jovanovic if (HasRs) 960e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 9615c14b069SZoran Jovanovic Rs))); 9625c582b2fSDaniel Sanders 963e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 9645c582b2fSDaniel Sanders Rt))); 9655c582b2fSDaniel Sanders 966e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 9675c582b2fSDaniel Sanders 9685c582b2fSDaniel Sanders return MCDisassembler::Success; 9695c582b2fSDaniel Sanders } 9705c582b2fSDaniel Sanders 9715c582b2fSDaniel Sanders template <typename InsnType> 9725c582b2fSDaniel Sanders static DecodeStatus DecodeBgtzGroupBranch(MCInst &MI, InsnType insn, 9735c582b2fSDaniel Sanders uint64_t Address, 9745c582b2fSDaniel Sanders const void *Decoder) { 9755c582b2fSDaniel Sanders // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 9765c582b2fSDaniel Sanders // (otherwise we would have matched the BGTZ instruction from the earlier 9775c582b2fSDaniel Sanders // ISA's instead). 9785c582b2fSDaniel Sanders // 9795c582b2fSDaniel Sanders // We have: 9805c582b2fSDaniel Sanders // 0b000111 sssss ttttt iiiiiiiiiiiiiiii 9815c582b2fSDaniel Sanders // BGTZ if rt == 0 9825c582b2fSDaniel Sanders // BGTZALC if rs == 0 && rt != 0 9835c582b2fSDaniel Sanders // BLTZALC if rs != 0 && rs == rt 9845c582b2fSDaniel Sanders // BLTUC if rs != 0 && rs != rt 9855c582b2fSDaniel Sanders 9865c582b2fSDaniel Sanders InsnType Rs = fieldFromInstruction(insn, 21, 5); 9875c582b2fSDaniel Sanders InsnType Rt = fieldFromInstruction(insn, 16, 5); 988672c710dSSagar Thakur int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 9895c582b2fSDaniel Sanders bool HasRs = false; 9905c582b2fSDaniel Sanders bool HasRt = false; 9915c582b2fSDaniel Sanders 9925c582b2fSDaniel Sanders if (Rt == 0) { 9935c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZ); 9945c582b2fSDaniel Sanders HasRs = true; 9955c582b2fSDaniel Sanders } else if (Rs == 0) { 9965c582b2fSDaniel Sanders MI.setOpcode(Mips::BGTZALC); 9975c582b2fSDaniel Sanders HasRt = true; 9985c582b2fSDaniel Sanders } else if (Rs == Rt) { 9995c582b2fSDaniel Sanders MI.setOpcode(Mips::BLTZALC); 10005c582b2fSDaniel Sanders HasRs = true; 10015c14b069SZoran Jovanovic } else { 10025c14b069SZoran Jovanovic MI.setOpcode(Mips::BLTUC); 10035c14b069SZoran Jovanovic HasRs = true; 10045c14b069SZoran Jovanovic HasRt = true; 10055c14b069SZoran Jovanovic } 10065c582b2fSDaniel Sanders 10075c582b2fSDaniel Sanders if (HasRs) 1008e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 10095c582b2fSDaniel Sanders Rs))); 10105c582b2fSDaniel Sanders 10115c582b2fSDaniel Sanders if (HasRt) 1012e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 10135c582b2fSDaniel Sanders Rt))); 10145c582b2fSDaniel Sanders 1015e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 10165c582b2fSDaniel Sanders 10175c582b2fSDaniel Sanders return MCDisassembler::Success; 10185c582b2fSDaniel Sanders } 10195c582b2fSDaniel Sanders 102028a0ca07SZoran Jovanovic template <typename InsnType> 102128a0ca07SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranch(MCInst &MI, InsnType insn, 102228a0ca07SZoran Jovanovic uint64_t Address, 102328a0ca07SZoran Jovanovic const void *Decoder) { 102428a0ca07SZoran Jovanovic // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled 102528a0ca07SZoran Jovanovic // (otherwise we would have matched the BLEZL instruction from the earlier 102628a0ca07SZoran Jovanovic // ISA's instead). 102728a0ca07SZoran Jovanovic // 102828a0ca07SZoran Jovanovic // We have: 102928a0ca07SZoran Jovanovic // 0b000110 sssss ttttt iiiiiiiiiiiiiiii 103028a0ca07SZoran Jovanovic // Invalid if rs == 0 103128a0ca07SZoran Jovanovic // BLEZALC if rs == 0 && rt != 0 103228a0ca07SZoran Jovanovic // BGEZALC if rs == rt && rt != 0 103328a0ca07SZoran Jovanovic // BGEUC if rs != rt && rs != 0 && rt != 0 103428a0ca07SZoran Jovanovic 103528a0ca07SZoran Jovanovic InsnType Rs = fieldFromInstruction(insn, 21, 5); 103628a0ca07SZoran Jovanovic InsnType Rt = fieldFromInstruction(insn, 16, 5); 1037672c710dSSagar Thakur int64_t Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 103828a0ca07SZoran Jovanovic bool HasRs = false; 103928a0ca07SZoran Jovanovic 104028a0ca07SZoran Jovanovic if (Rt == 0) 104128a0ca07SZoran Jovanovic return MCDisassembler::Fail; 104228a0ca07SZoran Jovanovic else if (Rs == 0) 104328a0ca07SZoran Jovanovic MI.setOpcode(Mips::BLEZALC); 104428a0ca07SZoran Jovanovic else if (Rs == Rt) 104528a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEZALC); 104628a0ca07SZoran Jovanovic else { 104728a0ca07SZoran Jovanovic HasRs = true; 104828a0ca07SZoran Jovanovic MI.setOpcode(Mips::BGEUC); 104928a0ca07SZoran Jovanovic } 105028a0ca07SZoran Jovanovic 105128a0ca07SZoran Jovanovic if (HasRs) 1052e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 105328a0ca07SZoran Jovanovic Rs))); 1054e9119e41SJim Grosbach MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 105528a0ca07SZoran Jovanovic Rt))); 105628a0ca07SZoran Jovanovic 1057e9119e41SJim Grosbach MI.addOperand(MCOperand::createImm(Imm)); 105828a0ca07SZoran Jovanovic 105928a0ca07SZoran Jovanovic return MCDisassembler::Success; 106028a0ca07SZoran Jovanovic } 106128a0ca07SZoran Jovanovic 106255e44673SSimon Dardis // Override the generated disassembler to produce DEXT all the time. This is 106355e44673SSimon Dardis // for feature / behaviour parity with binutils. 106455e44673SSimon Dardis template <typename InsnType> 106555e44673SSimon Dardis static DecodeStatus DecodeDEXT(MCInst &MI, InsnType Insn, uint64_t Address, 106655e44673SSimon Dardis const void *Decoder) { 106755e44673SSimon Dardis unsigned Msbd = fieldFromInstruction(Insn, 11, 5); 106855e44673SSimon Dardis unsigned Lsb = fieldFromInstruction(Insn, 6, 5); 106955e44673SSimon Dardis unsigned Size = 0; 107055e44673SSimon Dardis unsigned Pos = 0; 107155e44673SSimon Dardis 107255e44673SSimon Dardis switch (MI.getOpcode()) { 107355e44673SSimon Dardis case Mips::DEXT: 107455e44673SSimon Dardis Pos = Lsb; 107555e44673SSimon Dardis Size = Msbd + 1; 107655e44673SSimon Dardis break; 107755e44673SSimon Dardis case Mips::DEXTM: 107855e44673SSimon Dardis Pos = Lsb; 107955e44673SSimon Dardis Size = Msbd + 1 + 32; 108055e44673SSimon Dardis break; 108155e44673SSimon Dardis case Mips::DEXTU: 108255e44673SSimon Dardis Pos = Lsb + 32; 108355e44673SSimon Dardis Size = Msbd + 1; 108455e44673SSimon Dardis break; 108555e44673SSimon Dardis default: 108655e44673SSimon Dardis llvm_unreachable("Unknown DEXT instruction!"); 108755e44673SSimon Dardis } 108855e44673SSimon Dardis 1089d6dada17SAleksandar Beserminji MI.setOpcode(Mips::DEXT); 109055e44673SSimon Dardis 109155e44673SSimon Dardis InsnType Rs = fieldFromInstruction(Insn, 21, 5); 109255e44673SSimon Dardis InsnType Rt = fieldFromInstruction(Insn, 16, 5); 109355e44673SSimon Dardis 109455e44673SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt))); 109555e44673SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs))); 109655e44673SSimon Dardis MI.addOperand(MCOperand::createImm(Pos)); 109755e44673SSimon Dardis MI.addOperand(MCOperand::createImm(Size)); 109855e44673SSimon Dardis 109955e44673SSimon Dardis return MCDisassembler::Success; 110055e44673SSimon Dardis } 110155e44673SSimon Dardis 11026f83ae38SSimon Dardis // Override the generated disassembler to produce DINS all the time. This is 11036f83ae38SSimon Dardis // for feature / behaviour parity with binutils. 11046f83ae38SSimon Dardis template <typename InsnType> 11056f83ae38SSimon Dardis static DecodeStatus DecodeDINS(MCInst &MI, InsnType Insn, uint64_t Address, 11066f83ae38SSimon Dardis const void *Decoder) { 11076f83ae38SSimon Dardis unsigned Msbd = fieldFromInstruction(Insn, 11, 5); 11086f83ae38SSimon Dardis unsigned Lsb = fieldFromInstruction(Insn, 6, 5); 11096f83ae38SSimon Dardis unsigned Size = 0; 11106f83ae38SSimon Dardis unsigned Pos = 0; 11116f83ae38SSimon Dardis 11126f83ae38SSimon Dardis switch (MI.getOpcode()) { 11136f83ae38SSimon Dardis case Mips::DINS: 11146f83ae38SSimon Dardis Pos = Lsb; 11156f83ae38SSimon Dardis Size = Msbd + 1 - Pos; 11166f83ae38SSimon Dardis break; 11176f83ae38SSimon Dardis case Mips::DINSM: 11186f83ae38SSimon Dardis Pos = Lsb; 11196f83ae38SSimon Dardis Size = Msbd + 33 - Pos; 11206f83ae38SSimon Dardis break; 11216f83ae38SSimon Dardis case Mips::DINSU: 11226f83ae38SSimon Dardis Pos = Lsb + 32; 11236f83ae38SSimon Dardis // mbsd = pos + size - 33 11246f83ae38SSimon Dardis // mbsd - pos + 33 = size 11256f83ae38SSimon Dardis Size = Msbd + 33 - Pos; 11266f83ae38SSimon Dardis break; 11276f83ae38SSimon Dardis default: 11286f83ae38SSimon Dardis llvm_unreachable("Unknown DINS instruction!"); 11296f83ae38SSimon Dardis } 11306f83ae38SSimon Dardis 11316f83ae38SSimon Dardis InsnType Rs = fieldFromInstruction(Insn, 21, 5); 11326f83ae38SSimon Dardis InsnType Rt = fieldFromInstruction(Insn, 16, 5); 11336f83ae38SSimon Dardis 1134d6dada17SAleksandar Beserminji MI.setOpcode(Mips::DINS); 11356f83ae38SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rt))); 11366f83ae38SSimon Dardis MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR64RegClassID, Rs))); 11376f83ae38SSimon Dardis MI.addOperand(MCOperand::createImm(Pos)); 11386f83ae38SSimon Dardis MI.addOperand(MCOperand::createImm(Size)); 11396f83ae38SSimon Dardis 11406f83ae38SSimon Dardis return MCDisassembler::Success; 11416f83ae38SSimon Dardis } 11423408caf6SPetar Jovanovic 11433408caf6SPetar Jovanovic // Auto-generated decoder wouldn't add the third operand for CRC32*. 11443408caf6SPetar Jovanovic template <typename InsnType> 11453408caf6SPetar Jovanovic static DecodeStatus DecodeCRC(MCInst &MI, InsnType Insn, uint64_t Address, 11463408caf6SPetar Jovanovic const void *Decoder) { 11473408caf6SPetar Jovanovic InsnType Rs = fieldFromInstruction(Insn, 21, 5); 11483408caf6SPetar Jovanovic InsnType Rt = fieldFromInstruction(Insn, 16, 5); 11493408caf6SPetar Jovanovic MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 11503408caf6SPetar Jovanovic Rt))); 11513408caf6SPetar Jovanovic MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 11523408caf6SPetar Jovanovic Rs))); 11533408caf6SPetar Jovanovic MI.addOperand(MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, 11543408caf6SPetar Jovanovic Rt))); 11553408caf6SPetar Jovanovic return MCDisassembler::Success; 11563408caf6SPetar Jovanovic } 11573408caf6SPetar Jovanovic 1158ea22c4cfSJozef Kolek /// Read two bytes from the ArrayRef and return 16 bit halfword sorted 1159dcd84335SSimon Pilgrim /// according to the given endianness. 1160ea22c4cfSJozef Kolek static DecodeStatus readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address, 1161ea22c4cfSJozef Kolek uint64_t &Size, uint32_t &Insn, 1162ea22c4cfSJozef Kolek bool IsBigEndian) { 1163ea22c4cfSJozef Kolek // We want to read exactly 2 Bytes of data. 1164ea22c4cfSJozef Kolek if (Bytes.size() < 2) { 1165ea22c4cfSJozef Kolek Size = 0; 1166ea22c4cfSJozef Kolek return MCDisassembler::Fail; 1167ea22c4cfSJozef Kolek } 1168ea22c4cfSJozef Kolek 1169ea22c4cfSJozef Kolek if (IsBigEndian) { 1170ea22c4cfSJozef Kolek Insn = (Bytes[0] << 8) | Bytes[1]; 1171ea22c4cfSJozef Kolek } else { 1172ea22c4cfSJozef Kolek Insn = (Bytes[1] << 8) | Bytes[0]; 1173ea22c4cfSJozef Kolek } 1174ea22c4cfSJozef Kolek 1175ea22c4cfSJozef Kolek return MCDisassembler::Success; 1176ea22c4cfSJozef Kolek } 1177ea22c4cfSJozef Kolek 11787fc5b874SRafael Espindola /// Read four bytes from the ArrayRef and return 32 bit word sorted 1179dcd84335SSimon Pilgrim /// according to the given endianness. 11807fc5b874SRafael Espindola static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address, 11817fc5b874SRafael Espindola uint64_t &Size, uint32_t &Insn, 11827fc5b874SRafael Espindola bool IsBigEndian, bool IsMicroMips) { 118371928e68SAkira Hatanaka // We want to read exactly 4 Bytes of data. 11847fc5b874SRafael Espindola if (Bytes.size() < 4) { 11854aa6bea7SRafael Espindola Size = 0; 118671928e68SAkira Hatanaka return MCDisassembler::Fail; 118771928e68SAkira Hatanaka } 118871928e68SAkira Hatanaka 1189ea22c4cfSJozef Kolek // High 16 bits of a 32-bit microMIPS instruction (where the opcode is) 1190ea22c4cfSJozef Kolek // always precede the low 16 bits in the instruction stream (that is, they 1191ea22c4cfSJozef Kolek // are placed at lower addresses in the instruction stream). 1192ea22c4cfSJozef Kolek // 1193ea22c4cfSJozef Kolek // microMIPS byte ordering: 1194ea22c4cfSJozef Kolek // Big-endian: 0 | 1 | 2 | 3 1195ea22c4cfSJozef Kolek // Little-endian: 1 | 0 | 3 | 2 1196ea22c4cfSJozef Kolek 11974aa6bea7SRafael Espindola if (IsBigEndian) { 119871928e68SAkira Hatanaka // Encoded as a big-endian 32-bit word in the stream. 11994aa6bea7SRafael Espindola Insn = 12004aa6bea7SRafael Espindola (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | (Bytes[0] << 24); 12014aa6bea7SRafael Espindola } else { 1202dde3d582SVladimir Medic if (IsMicroMips) { 12034aa6bea7SRafael Espindola Insn = (Bytes[2] << 0) | (Bytes[3] << 8) | (Bytes[0] << 16) | 1204dde3d582SVladimir Medic (Bytes[1] << 24); 1205dde3d582SVladimir Medic } else { 12064aa6bea7SRafael Espindola Insn = (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) | 120771928e68SAkira Hatanaka (Bytes[3] << 24); 120871928e68SAkira Hatanaka } 1209dde3d582SVladimir Medic } 121071928e68SAkira Hatanaka 121171928e68SAkira Hatanaka return MCDisassembler::Success; 121271928e68SAkira Hatanaka } 121371928e68SAkira Hatanaka 12144aa6bea7SRafael Espindola DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size, 12157fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 121671928e68SAkira Hatanaka uint64_t Address, 12174aa6bea7SRafael Espindola raw_ostream &VStream, 12184aa6bea7SRafael Espindola raw_ostream &CStream) const { 121971928e68SAkira Hatanaka uint32_t Insn; 1220ea22c4cfSJozef Kolek DecodeStatus Result; 1221a5f52dc0SSimon Dardis Size = 0; 122271928e68SAkira Hatanaka 1223ea22c4cfSJozef Kolek if (IsMicroMips) { 1224ea22c4cfSJozef Kolek Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); 1225ebee6129SReid Kleckner if (Result == MCDisassembler::Fail) 1226ebee6129SReid Kleckner return MCDisassembler::Fail; 1227ea22c4cfSJozef Kolek 1228ada70918SZoran Jovanovic if (hasMips32r6()) { 1229d34e60caSNicola Zaghen LLVM_DEBUG( 1230d34e60caSNicola Zaghen dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n"); 1231ada70918SZoran Jovanovic // Calling the auto-generated decoder function for microMIPS32R6 1232d6dada17SAleksandar Beserminji // 16-bit instructions. 1233ada70918SZoran Jovanovic Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn, 1234ada70918SZoran Jovanovic Address, this, STI); 1235ada70918SZoran Jovanovic if (Result != MCDisassembler::Fail) { 1236ada70918SZoran Jovanovic Size = 2; 1237ada70918SZoran Jovanovic return Result; 1238ada70918SZoran Jovanovic } 1239ada70918SZoran Jovanovic } 1240ada70918SZoran Jovanovic 1241d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n"); 1242ada70918SZoran Jovanovic // Calling the auto-generated decoder function for microMIPS 16-bit 1243ada70918SZoran Jovanovic // instructions. 1244ea22c4cfSJozef Kolek Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address, 1245ea22c4cfSJozef Kolek this, STI); 1246ea22c4cfSJozef Kolek if (Result != MCDisassembler::Fail) { 1247ea22c4cfSJozef Kolek Size = 2; 1248ea22c4cfSJozef Kolek return Result; 1249ea22c4cfSJozef Kolek } 1250ea22c4cfSJozef Kolek 1251ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, true); 125271928e68SAkira Hatanaka if (Result == MCDisassembler::Fail) 125371928e68SAkira Hatanaka return MCDisassembler::Fail; 125471928e68SAkira Hatanaka 1255676d6012SJozef Kolek if (hasMips32r6()) { 1256d34e60caSNicola Zaghen LLVM_DEBUG( 1257d34e60caSNicola Zaghen dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n"); 1258676d6012SJozef Kolek // Calling the auto-generated decoder function. 1259366783e1SZoran Jovanovic Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address, 1260676d6012SJozef Kolek this, STI); 1261ada70918SZoran Jovanovic if (Result != MCDisassembler::Fail) { 1262ada70918SZoran Jovanovic Size = 4; 1263ada70918SZoran Jovanovic return Result; 1264ada70918SZoran Jovanovic } 1265ada70918SZoran Jovanovic } 1266ada70918SZoran Jovanovic 1267d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); 1268dde3d582SVladimir Medic // Calling the auto-generated decoder function. 12694aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, 1270dde3d582SVladimir Medic this, STI); 1271dde3d582SVladimir Medic if (Result != MCDisassembler::Fail) { 1272dde3d582SVladimir Medic Size = 4; 1273dde3d582SVladimir Medic return Result; 1274dde3d582SVladimir Medic } 12752cb74ac3SHrvoje Varga 127651a7ae2aSSimon Dardis if (isFP64()) { 1277d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying MicroMipsFP64 table (32-bit opcodes):\n"); 127851a7ae2aSSimon Dardis Result = decodeInstruction(DecoderTableMicroMipsFP6432, Instr, Insn, 12792cb74ac3SHrvoje Varga Address, this, STI); 12802cb74ac3SHrvoje Varga if (Result != MCDisassembler::Fail) { 12812cb74ac3SHrvoje Varga Size = 4; 12822cb74ac3SHrvoje Varga return Result; 12832cb74ac3SHrvoje Varga } 12842cb74ac3SHrvoje Varga } 12852cb74ac3SHrvoje Varga 1286a5f52dc0SSimon Dardis // This is an invalid instruction. Claim that the Size is 2 bytes. Since 1287a5f52dc0SSimon Dardis // microMIPS instructions have a minimum alignment of 2, the next 2 bytes 1288a5f52dc0SSimon Dardis // could form a valid instruction. The two bytes we rejected as an 1289a5f52dc0SSimon Dardis // instruction could have actually beeen an inline constant pool that is 1290a5f52dc0SSimon Dardis // unconditionally branched over. 1291ebee6129SReid Kleckner Size = 2; 1292dde3d582SVladimir Medic return MCDisassembler::Fail; 1293dde3d582SVladimir Medic } 1294dde3d582SVladimir Medic 1295a5f52dc0SSimon Dardis // Attempt to read the instruction so that we can attempt to decode it. If 1296a5f52dc0SSimon Dardis // the buffer is not 4 bytes long, let the higher level logic figure out 1297a5f52dc0SSimon Dardis // what to do with a size of zero and MCDisassembler::Fail. 1298ea22c4cfSJozef Kolek Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); 1299a5f52dc0SSimon Dardis if (Result == MCDisassembler::Fail) 1300ea22c4cfSJozef Kolek return MCDisassembler::Fail; 1301a5f52dc0SSimon Dardis 1302a5f52dc0SSimon Dardis // The only instruction size for standard encoded MIPS. 1303a5f52dc0SSimon Dardis Size = 4; 1304ea22c4cfSJozef Kolek 1305c171f65aSDaniel Sanders if (hasCOP3()) { 1306d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n"); 1307c171f65aSDaniel Sanders Result = 13084aa6bea7SRafael Espindola decodeInstruction(DecoderTableCOP3_32, Instr, Insn, Address, this, STI); 1309a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 1310c171f65aSDaniel Sanders return Result; 1311c171f65aSDaniel Sanders } 1312c171f65aSDaniel Sanders 1313c171f65aSDaniel Sanders if (hasMips32r6() && isGP64()) { 1314d34e60caSNicola Zaghen LLVM_DEBUG( 1315d34e60caSNicola Zaghen dbgs() << "Trying Mips32r6_64r6 (GPR64) table (32-bit opcodes):\n"); 131636901dd1SVasileios Kalintiris Result = decodeInstruction(DecoderTableMips32r6_64r6_GP6432, Instr, Insn, 131736901dd1SVasileios Kalintiris Address, this, STI); 1318a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 13190fa60416SDaniel Sanders return Result; 13200fa60416SDaniel Sanders } 13210fa60416SDaniel Sanders 13224fbf76f7SSimon Dardis if (hasMips32r6() && isPTR64()) { 1323d34e60caSNicola Zaghen LLVM_DEBUG( 1324d34e60caSNicola Zaghen dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n"); 13254fbf76f7SSimon Dardis Result = decodeInstruction(DecoderTableMips32r6_64r6_PTR6432, Instr, Insn, 13264fbf76f7SSimon Dardis Address, this, STI); 1327a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 13284fbf76f7SSimon Dardis return Result; 13294fbf76f7SSimon Dardis } 13304fbf76f7SSimon Dardis 1331c171f65aSDaniel Sanders if (hasMips32r6()) { 1332d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying Mips32r6_64r6 table (32-bit opcodes):\n"); 13334aa6bea7SRafael Espindola Result = decodeInstruction(DecoderTableMips32r6_64r632, Instr, Insn, 13345c582b2fSDaniel Sanders Address, this, STI); 1335a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 13365c582b2fSDaniel Sanders return Result; 13375c582b2fSDaniel Sanders } 13385c582b2fSDaniel Sanders 13394fbf76f7SSimon Dardis if (hasMips2() && isPTR64()) { 1340d34e60caSNicola Zaghen LLVM_DEBUG( 1341d34e60caSNicola Zaghen dbgs() << "Trying Mips32r6_64r6 (PTR64) table (32-bit opcodes):\n"); 13424fbf76f7SSimon Dardis Result = decodeInstruction(DecoderTableMips32_64_PTR6432, Instr, Insn, 13434fbf76f7SSimon Dardis Address, this, STI); 1344a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 13454fbf76f7SSimon Dardis return Result; 13464fbf76f7SSimon Dardis } 13474fbf76f7SSimon Dardis 13483adf9b8dSKai Nacke if (hasCnMips()) { 1349d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying CnMips table (32-bit opcodes):\n"); 13503adf9b8dSKai Nacke Result = decodeInstruction(DecoderTableCnMips32, Instr, Insn, 13513adf9b8dSKai Nacke Address, this, STI); 1352a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 13533adf9b8dSKai Nacke return Result; 13543adf9b8dSKai Nacke } 13553adf9b8dSKai Nacke 1356a19216c8SDaniel Sanders if (isGP64()) { 1357d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying Mips64 (GPR64) table (32-bit opcodes):\n"); 1358a19216c8SDaniel Sanders Result = decodeInstruction(DecoderTableMips6432, Instr, Insn, 1359a19216c8SDaniel Sanders Address, this, STI); 1360a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 1361a19216c8SDaniel Sanders return Result; 1362a19216c8SDaniel Sanders } 1363a19216c8SDaniel Sanders 136451a7ae2aSSimon Dardis if (isFP64()) { 1365d34e60caSNicola Zaghen LLVM_DEBUG( 1366d34e60caSNicola Zaghen dbgs() << "Trying MipsFP64 (64 bit FPU) table (32-bit opcodes):\n"); 136751a7ae2aSSimon Dardis Result = decodeInstruction(DecoderTableMipsFP6432, Instr, Insn, 136851a7ae2aSSimon Dardis Address, this, STI); 136951a7ae2aSSimon Dardis if (Result != MCDisassembler::Fail) 137051a7ae2aSSimon Dardis return Result; 137151a7ae2aSSimon Dardis } 137251a7ae2aSSimon Dardis 1373d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying Mips table (32-bit opcodes):\n"); 137471928e68SAkira Hatanaka // Calling the auto-generated decoder function. 13754aa6bea7SRafael Espindola Result = 13764aa6bea7SRafael Espindola decodeInstruction(DecoderTableMips32, Instr, Insn, Address, this, STI); 1377a5f52dc0SSimon Dardis if (Result != MCDisassembler::Fail) 137871928e68SAkira Hatanaka return Result; 137971928e68SAkira Hatanaka 138071928e68SAkira Hatanaka return MCDisassembler::Fail; 138171928e68SAkira Hatanaka } 138271928e68SAkira Hatanaka 1383ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst, 1384ec8a5490SReed Kotler unsigned RegNo, 1385ec8a5490SReed Kotler uint64_t Address, 1386ec8a5490SReed Kotler const void *Decoder) { 1387ec8a5490SReed Kotler return MCDisassembler::Fail; 1388ec8a5490SReed Kotler } 1389ec8a5490SReed Kotler 139013e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, 139171928e68SAkira Hatanaka unsigned RegNo, 139271928e68SAkira Hatanaka uint64_t Address, 139371928e68SAkira Hatanaka const void *Decoder) { 139471928e68SAkira Hatanaka if (RegNo > 31) 139571928e68SAkira Hatanaka return MCDisassembler::Fail; 139671928e68SAkira Hatanaka 139713e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo); 1398e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 139971928e68SAkira Hatanaka return MCDisassembler::Success; 140071928e68SAkira Hatanaka } 140171928e68SAkira Hatanaka 1402b0852e54SZoran Jovanovic static DecodeStatus DecodeGPRMM16RegisterClass(MCInst &Inst, 1403b0852e54SZoran Jovanovic unsigned RegNo, 1404b0852e54SZoran Jovanovic uint64_t Address, 1405b0852e54SZoran Jovanovic const void *Decoder) { 1406ea22c4cfSJozef Kolek if (RegNo > 7) 1407b0852e54SZoran Jovanovic return MCDisassembler::Fail; 1408ea22c4cfSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16RegClassID, RegNo); 1409e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1410ea22c4cfSJozef Kolek return MCDisassembler::Success; 1411b0852e54SZoran Jovanovic } 1412b0852e54SZoran Jovanovic 14131904fa21SJozef Kolek static DecodeStatus DecodeGPRMM16ZeroRegisterClass(MCInst &Inst, 14141904fa21SJozef Kolek unsigned RegNo, 14151904fa21SJozef Kolek uint64_t Address, 14161904fa21SJozef Kolek const void *Decoder) { 1417315e7ecaSJozef Kolek if (RegNo > 7) 14181904fa21SJozef Kolek return MCDisassembler::Fail; 1419315e7ecaSJozef Kolek unsigned Reg = getReg(Decoder, Mips::GPRMM16ZeroRegClassID, RegNo); 1420e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1421315e7ecaSJozef Kolek return MCDisassembler::Success; 14221904fa21SJozef Kolek } 14231904fa21SJozef Kolek 142441688679SZoran Jovanovic static DecodeStatus DecodeGPRMM16MovePRegisterClass(MCInst &Inst, 142541688679SZoran Jovanovic unsigned RegNo, 142641688679SZoran Jovanovic uint64_t Address, 142741688679SZoran Jovanovic const void *Decoder) { 142841688679SZoran Jovanovic if (RegNo > 7) 142941688679SZoran Jovanovic return MCDisassembler::Fail; 143041688679SZoran Jovanovic unsigned Reg = getReg(Decoder, Mips::GPRMM16MovePRegClassID, RegNo); 1431e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 143241688679SZoran Jovanovic return MCDisassembler::Success; 143341688679SZoran Jovanovic } 143441688679SZoran Jovanovic 143513e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, 143671928e68SAkira Hatanaka unsigned RegNo, 143771928e68SAkira Hatanaka uint64_t Address, 143871928e68SAkira Hatanaka const void *Decoder) { 143971928e68SAkira Hatanaka if (RegNo > 31) 144071928e68SAkira Hatanaka return MCDisassembler::Fail; 144113e6ccf3SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo); 1442e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 144371928e68SAkira Hatanaka return MCDisassembler::Success; 144471928e68SAkira Hatanaka } 144571928e68SAkira Hatanaka 14469bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst, 14479bfa2e2eSAkira Hatanaka unsigned RegNo, 14489bfa2e2eSAkira Hatanaka uint64_t Address, 14499bfa2e2eSAkira Hatanaka const void *Decoder) { 1450a19216c8SDaniel Sanders if (static_cast<const MipsDisassembler *>(Decoder)->isGP64()) 14519bfa2e2eSAkira Hatanaka return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder); 14529bfa2e2eSAkira Hatanaka 14539bfa2e2eSAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 14549bfa2e2eSAkira Hatanaka } 14559bfa2e2eSAkira Hatanaka 1456654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst, 1457ecabd1a5SAkira Hatanaka unsigned RegNo, 1458ecabd1a5SAkira Hatanaka uint64_t Address, 1459ecabd1a5SAkira Hatanaka const void *Decoder) { 146013e6ccf3SAkira Hatanaka return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder); 1461ecabd1a5SAkira Hatanaka } 1462ecabd1a5SAkira Hatanaka 146371928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst, 146471928e68SAkira Hatanaka unsigned RegNo, 146571928e68SAkira Hatanaka uint64_t Address, 146671928e68SAkira Hatanaka const void *Decoder) { 146771928e68SAkira Hatanaka if (RegNo > 31) 146871928e68SAkira Hatanaka return MCDisassembler::Fail; 146971928e68SAkira Hatanaka 14709bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo); 1471e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 147271928e68SAkira Hatanaka return MCDisassembler::Success; 147371928e68SAkira Hatanaka } 147471928e68SAkira Hatanaka 147571928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst, 147671928e68SAkira Hatanaka unsigned RegNo, 147771928e68SAkira Hatanaka uint64_t Address, 147871928e68SAkira Hatanaka const void *Decoder) { 147971928e68SAkira Hatanaka if (RegNo > 31) 148071928e68SAkira Hatanaka return MCDisassembler::Fail; 148171928e68SAkira Hatanaka 14829bf2b567SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo); 1483e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 148471928e68SAkira Hatanaka return MCDisassembler::Success; 148571928e68SAkira Hatanaka } 148671928e68SAkira Hatanaka 148771928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst, 148871928e68SAkira Hatanaka unsigned RegNo, 148971928e68SAkira Hatanaka uint64_t Address, 149071928e68SAkira Hatanaka const void *Decoder) { 1491253777fdSChad Rosier if (RegNo > 31) 1492253777fdSChad Rosier return MCDisassembler::Fail; 1493253777fdSChad Rosier unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo); 1494e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 149571928e68SAkira Hatanaka return MCDisassembler::Success; 149671928e68SAkira Hatanaka } 149771928e68SAkira Hatanaka 14981fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst, 14991fb1b8b8SAkira Hatanaka unsigned RegNo, 15001fb1b8b8SAkira Hatanaka uint64_t Address, 15011fb1b8b8SAkira Hatanaka const void *Decoder) { 15021fb1b8b8SAkira Hatanaka if (RegNo > 7) 15031fb1b8b8SAkira Hatanaka return MCDisassembler::Fail; 15041fb1b8b8SAkira Hatanaka unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo); 1505e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 15061fb1b8b8SAkira Hatanaka return MCDisassembler::Success; 15071fb1b8b8SAkira Hatanaka } 15081fb1b8b8SAkira Hatanaka 150936901dd1SVasileios Kalintiris static DecodeStatus DecodeFGRCCRegisterClass(MCInst &Inst, unsigned RegNo, 15100fa60416SDaniel Sanders uint64_t Address, 15110fa60416SDaniel Sanders const void *Decoder) { 15120fa60416SDaniel Sanders if (RegNo > 31) 15130fa60416SDaniel Sanders return MCDisassembler::Fail; 15140fa60416SDaniel Sanders 151536901dd1SVasileios Kalintiris unsigned Reg = getReg(Decoder, Mips::FGRCCRegClassID, RegNo); 1516e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 15170fa60416SDaniel Sanders return MCDisassembler::Success; 15180fa60416SDaniel Sanders } 15190fa60416SDaniel Sanders 152071928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst, 152171928e68SAkira Hatanaka unsigned Insn, 152271928e68SAkira Hatanaka uint64_t Address, 152371928e68SAkira Hatanaka const void *Decoder) { 152471928e68SAkira Hatanaka int Offset = SignExtend32<16>(Insn & 0xffff); 1525ecaef49fSJim Grosbach unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1526ecaef49fSJim Grosbach unsigned Base = fieldFromInstruction(Insn, 21, 5); 15279bf2b567SAkira Hatanaka 152813e6ccf3SAkira Hatanaka Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 152913e6ccf3SAkira Hatanaka Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 153071928e68SAkira Hatanaka 1531d7ecf49eSVladimir Medic if (Inst.getOpcode() == Mips::SC || 1532e4e83a7bSDaniel Sanders Inst.getOpcode() == Mips::SCD) 1533e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1534e4e83a7bSDaniel Sanders 1535e4e83a7bSDaniel Sanders Inst.addOperand(MCOperand::createReg(Reg)); 1536e4e83a7bSDaniel Sanders Inst.addOperand(MCOperand::createReg(Base)); 1537e4e83a7bSDaniel Sanders Inst.addOperand(MCOperand::createImm(Offset)); 1538e4e83a7bSDaniel Sanders 1539e4e83a7bSDaniel Sanders return MCDisassembler::Success; 154071928e68SAkira Hatanaka } 154171928e68SAkira Hatanaka 1542e4e83a7bSDaniel Sanders static DecodeStatus DecodeMemEVA(MCInst &Inst, 1543e4e83a7bSDaniel Sanders unsigned Insn, 1544e4e83a7bSDaniel Sanders uint64_t Address, 1545e4e83a7bSDaniel Sanders const void *Decoder) { 1546e4e83a7bSDaniel Sanders int Offset = SignExtend32<9>(Insn >> 7); 1547e4e83a7bSDaniel Sanders unsigned Reg = fieldFromInstruction(Insn, 16, 5); 1548e4e83a7bSDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 1549e4e83a7bSDaniel Sanders 1550e4e83a7bSDaniel Sanders Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1551e4e83a7bSDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1552e4e83a7bSDaniel Sanders 1553e4e83a7bSDaniel Sanders if (Inst.getOpcode() == Mips::SCE) 1554e4e83a7bSDaniel Sanders Inst.addOperand(MCOperand::createReg(Reg)); 1555e4e83a7bSDaniel Sanders 1556e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1557e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1558e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 155971928e68SAkira Hatanaka 156071928e68SAkira Hatanaka return MCDisassembler::Success; 156171928e68SAkira Hatanaka } 156271928e68SAkira Hatanaka 15633c88fbd3SHrvoje Varga static DecodeStatus DecodeLoadByte15(MCInst &Inst, 15643c88fbd3SHrvoje Varga unsigned Insn, 15653c88fbd3SHrvoje Varga uint64_t Address, 15663c88fbd3SHrvoje Varga const void *Decoder) { 15673c88fbd3SHrvoje Varga int Offset = SignExtend32<16>(Insn & 0xffff); 15683c88fbd3SHrvoje Varga unsigned Base = fieldFromInstruction(Insn, 16, 5); 15693c88fbd3SHrvoje Varga unsigned Reg = fieldFromInstruction(Insn, 21, 5); 15703c88fbd3SHrvoje Varga 15713c88fbd3SHrvoje Varga Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 15723c88fbd3SHrvoje Varga Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 15733c88fbd3SHrvoje Varga 15743c88fbd3SHrvoje Varga Inst.addOperand(MCOperand::createReg(Reg)); 15753c88fbd3SHrvoje Varga Inst.addOperand(MCOperand::createReg(Base)); 15763c88fbd3SHrvoje Varga Inst.addOperand(MCOperand::createImm(Offset)); 15773c88fbd3SHrvoje Varga 15783c88fbd3SHrvoje Varga return MCDisassembler::Success; 15793c88fbd3SHrvoje Varga } 15803c88fbd3SHrvoje Varga 158192db6b78SDaniel Sanders static DecodeStatus DecodeCacheOp(MCInst &Inst, 158292db6b78SDaniel Sanders unsigned Insn, 158392db6b78SDaniel Sanders uint64_t Address, 158492db6b78SDaniel Sanders const void *Decoder) { 158592db6b78SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 158692db6b78SDaniel Sanders unsigned Hint = fieldFromInstruction(Insn, 16, 5); 158792db6b78SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 158892db6b78SDaniel Sanders 158992db6b78SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 159092db6b78SDaniel Sanders 1591e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1592e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1593e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Hint)); 159492db6b78SDaniel Sanders 159592db6b78SDaniel Sanders return MCDisassembler::Success; 159692db6b78SDaniel Sanders } 159792db6b78SDaniel Sanders 1598ab6d1cceSJozef Kolek static DecodeStatus DecodeCacheOpMM(MCInst &Inst, 1599ab6d1cceSJozef Kolek unsigned Insn, 1600ab6d1cceSJozef Kolek uint64_t Address, 1601ab6d1cceSJozef Kolek const void *Decoder) { 1602ab6d1cceSJozef Kolek int Offset = SignExtend32<12>(Insn & 0xfff); 1603ab6d1cceSJozef Kolek unsigned Base = fieldFromInstruction(Insn, 16, 5); 1604ab6d1cceSJozef Kolek unsigned Hint = fieldFromInstruction(Insn, 21, 5); 1605ab6d1cceSJozef Kolek 1606ab6d1cceSJozef Kolek Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1607ab6d1cceSJozef Kolek 1608e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1609e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1610e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Hint)); 1611ab6d1cceSJozef Kolek 1612ab6d1cceSJozef Kolek return MCDisassembler::Success; 1613ab6d1cceSJozef Kolek } 1614ab6d1cceSJozef Kolek 1615d9790793SZoran Jovanovic static DecodeStatus DecodePrefeOpMM(MCInst &Inst, 1616d9790793SZoran Jovanovic unsigned Insn, 1617d9790793SZoran Jovanovic uint64_t Address, 1618d9790793SZoran Jovanovic const void *Decoder) { 1619d9790793SZoran Jovanovic int Offset = SignExtend32<9>(Insn & 0x1ff); 1620d9790793SZoran Jovanovic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1621d9790793SZoran Jovanovic unsigned Hint = fieldFromInstruction(Insn, 21, 5); 1622d9790793SZoran Jovanovic 1623d9790793SZoran Jovanovic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1624d9790793SZoran Jovanovic 1625d9790793SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Base)); 1626d9790793SZoran Jovanovic Inst.addOperand(MCOperand::createImm(Offset)); 1627d9790793SZoran Jovanovic Inst.addOperand(MCOperand::createImm(Hint)); 1628d9790793SZoran Jovanovic 1629d9790793SZoran Jovanovic return MCDisassembler::Success; 1630d9790793SZoran Jovanovic } 1631d9790793SZoran Jovanovic 1632e4e83a7bSDaniel Sanders static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, 1633df464ae2SVladimir Medic unsigned Insn, 1634df464ae2SVladimir Medic uint64_t Address, 1635df464ae2SVladimir Medic const void *Decoder) { 1636e4e83a7bSDaniel Sanders int Offset = SignExtend32<9>(Insn >> 7); 1637df464ae2SVladimir Medic unsigned Hint = fieldFromInstruction(Insn, 16, 5); 1638df464ae2SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 21, 5); 1639df464ae2SVladimir Medic 1640df464ae2SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1641df464ae2SVladimir Medic 1642e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1643e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1644e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Hint)); 1645df464ae2SVladimir Medic 1646df464ae2SVladimir Medic return MCDisassembler::Success; 1647df464ae2SVladimir Medic } 1648df464ae2SVladimir Medic 1649b4484d62SDaniel Sanders static DecodeStatus DecodeSyncI(MCInst &Inst, 1650b4484d62SDaniel Sanders unsigned Insn, 1651b4484d62SDaniel Sanders uint64_t Address, 1652b4484d62SDaniel Sanders const void *Decoder) { 1653b4484d62SDaniel Sanders int Offset = SignExtend32<16>(Insn & 0xffff); 1654b4484d62SDaniel Sanders unsigned Base = fieldFromInstruction(Insn, 21, 5); 1655b4484d62SDaniel Sanders 1656b4484d62SDaniel Sanders Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1657b4484d62SDaniel Sanders 1658e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1659e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1660b4484d62SDaniel Sanders 1661b4484d62SDaniel Sanders return MCDisassembler::Success; 1662b4484d62SDaniel Sanders } 1663b4484d62SDaniel Sanders 1664eac9301cSSimon Dardis static DecodeStatus DecodeSyncI_MM(MCInst &Inst, unsigned Insn, 1665eac9301cSSimon Dardis uint64_t Address, const void *Decoder) { 1666eac9301cSSimon Dardis int Offset = SignExtend32<16>(Insn & 0xffff); 1667eac9301cSSimon Dardis unsigned Base = fieldFromInstruction(Insn, 16, 5); 1668eac9301cSSimon Dardis 1669eac9301cSSimon Dardis Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1670eac9301cSSimon Dardis 1671eac9301cSSimon Dardis Inst.addOperand(MCOperand::createReg(Base)); 1672eac9301cSSimon Dardis Inst.addOperand(MCOperand::createImm(Offset)); 1673eac9301cSSimon Dardis 1674eac9301cSSimon Dardis return MCDisassembler::Success; 1675eac9301cSSimon Dardis } 1676eac9301cSSimon Dardis 167718148671SHrvoje Varga static DecodeStatus DecodeSynciR6(MCInst &Inst, 167818148671SHrvoje Varga unsigned Insn, 167918148671SHrvoje Varga uint64_t Address, 168018148671SHrvoje Varga const void *Decoder) { 168118148671SHrvoje Varga int Immediate = SignExtend32<16>(Insn & 0xffff); 168218148671SHrvoje Varga unsigned Base = fieldFromInstruction(Insn, 16, 5); 168318148671SHrvoje Varga 168418148671SHrvoje Varga Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 168518148671SHrvoje Varga 168618148671SHrvoje Varga Inst.addOperand(MCOperand::createReg(Base)); 168718148671SHrvoje Varga Inst.addOperand(MCOperand::createImm(Immediate)); 168818148671SHrvoje Varga 168918148671SHrvoje Varga return MCDisassembler::Success; 169018148671SHrvoje Varga } 169118148671SHrvoje Varga 1692fe0bf9f6SMatheus Almeida static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn, 1693fe0bf9f6SMatheus Almeida uint64_t Address, const void *Decoder) { 1694fe0bf9f6SMatheus Almeida int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10)); 1695fe0bf9f6SMatheus Almeida unsigned Reg = fieldFromInstruction(Insn, 6, 5); 1696fe0bf9f6SMatheus Almeida unsigned Base = fieldFromInstruction(Insn, 11, 5); 1697fe0bf9f6SMatheus Almeida 1698fe0bf9f6SMatheus Almeida Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg); 1699fe0bf9f6SMatheus Almeida Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1700fe0bf9f6SMatheus Almeida 1701e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1702e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 17036b59c449SMatheus Almeida 17046b59c449SMatheus Almeida // The immediate field of an LD/ST instruction is scaled which means it must 17056b59c449SMatheus Almeida // be multiplied (when decoding) by the size (in bytes) of the instructions' 17066b59c449SMatheus Almeida // data format. 17076b59c449SMatheus Almeida // .b - 1 byte 17086b59c449SMatheus Almeida // .h - 2 bytes 17096b59c449SMatheus Almeida // .w - 4 bytes 17106b59c449SMatheus Almeida // .d - 8 bytes 17116b59c449SMatheus Almeida switch(Inst.getOpcode()) 17126b59c449SMatheus Almeida { 17136b59c449SMatheus Almeida default: 1714926883e1SEugene Zelenko assert(false && "Unexpected instruction"); 17156b59c449SMatheus Almeida return MCDisassembler::Fail; 17166b59c449SMatheus Almeida break; 17176b59c449SMatheus Almeida case Mips::LD_B: 17186b59c449SMatheus Almeida case Mips::ST_B: 1719e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 17206b59c449SMatheus Almeida break; 17216b59c449SMatheus Almeida case Mips::LD_H: 17226b59c449SMatheus Almeida case Mips::ST_H: 1723e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset * 2)); 17246b59c449SMatheus Almeida break; 17256b59c449SMatheus Almeida case Mips::LD_W: 17266b59c449SMatheus Almeida case Mips::ST_W: 1727e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset * 4)); 17286b59c449SMatheus Almeida break; 17296b59c449SMatheus Almeida case Mips::LD_D: 17306b59c449SMatheus Almeida case Mips::ST_D: 1731e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset * 8)); 17326b59c449SMatheus Almeida break; 17336b59c449SMatheus Almeida } 1734fe0bf9f6SMatheus Almeida 1735fe0bf9f6SMatheus Almeida return MCDisassembler::Success; 1736fe0bf9f6SMatheus Almeida } 1737fe0bf9f6SMatheus Almeida 1738315e7ecaSJozef Kolek static DecodeStatus DecodeMemMMImm4(MCInst &Inst, 1739315e7ecaSJozef Kolek unsigned Insn, 1740315e7ecaSJozef Kolek uint64_t Address, 1741315e7ecaSJozef Kolek const void *Decoder) { 1742315e7ecaSJozef Kolek unsigned Offset = Insn & 0xf; 1743315e7ecaSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 7, 3); 1744315e7ecaSJozef Kolek unsigned Base = fieldFromInstruction(Insn, 4, 3); 1745315e7ecaSJozef Kolek 1746315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1747315e7ecaSJozef Kolek case Mips::LBU16_MM: 1748315e7ecaSJozef Kolek case Mips::LHU16_MM: 1749315e7ecaSJozef Kolek case Mips::LW16_MM: 1750315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Reg, Address, Decoder) 1751315e7ecaSJozef Kolek == MCDisassembler::Fail) 1752315e7ecaSJozef Kolek return MCDisassembler::Fail; 1753315e7ecaSJozef Kolek break; 1754315e7ecaSJozef Kolek case Mips::SB16_MM: 1755797c2aecSZlatko Buljan case Mips::SB16_MMR6: 1756315e7ecaSJozef Kolek case Mips::SH16_MM: 1757797c2aecSZlatko Buljan case Mips::SH16_MMR6: 1758315e7ecaSJozef Kolek case Mips::SW16_MM: 1759797c2aecSZlatko Buljan case Mips::SW16_MMR6: 1760315e7ecaSJozef Kolek if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder) 1761315e7ecaSJozef Kolek == MCDisassembler::Fail) 1762315e7ecaSJozef Kolek return MCDisassembler::Fail; 1763315e7ecaSJozef Kolek break; 1764315e7ecaSJozef Kolek } 1765315e7ecaSJozef Kolek 1766315e7ecaSJozef Kolek if (DecodeGPRMM16RegisterClass(Inst, Base, Address, Decoder) 1767315e7ecaSJozef Kolek == MCDisassembler::Fail) 1768315e7ecaSJozef Kolek return MCDisassembler::Fail; 1769315e7ecaSJozef Kolek 1770315e7ecaSJozef Kolek switch (Inst.getOpcode()) { 1771315e7ecaSJozef Kolek case Mips::LBU16_MM: 1772315e7ecaSJozef Kolek if (Offset == 0xf) 1773e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(-1)); 1774315e7ecaSJozef Kolek else 1775e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1776315e7ecaSJozef Kolek break; 1777315e7ecaSJozef Kolek case Mips::SB16_MM: 1778797c2aecSZlatko Buljan case Mips::SB16_MMR6: 1779e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1780315e7ecaSJozef Kolek break; 1781315e7ecaSJozef Kolek case Mips::LHU16_MM: 1782315e7ecaSJozef Kolek case Mips::SH16_MM: 1783797c2aecSZlatko Buljan case Mips::SH16_MMR6: 1784e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 1)); 1785315e7ecaSJozef Kolek break; 1786315e7ecaSJozef Kolek case Mips::LW16_MM: 1787315e7ecaSJozef Kolek case Mips::SW16_MM: 1788797c2aecSZlatko Buljan case Mips::SW16_MMR6: 1789e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 1790315e7ecaSJozef Kolek break; 1791315e7ecaSJozef Kolek } 1792315e7ecaSJozef Kolek 1793315e7ecaSJozef Kolek return MCDisassembler::Success; 1794315e7ecaSJozef Kolek } 1795315e7ecaSJozef Kolek 179612c6982bSJozef Kolek static DecodeStatus DecodeMemMMSPImm5Lsl2(MCInst &Inst, 179712c6982bSJozef Kolek unsigned Insn, 179812c6982bSJozef Kolek uint64_t Address, 179912c6982bSJozef Kolek const void *Decoder) { 180012c6982bSJozef Kolek unsigned Offset = Insn & 0x1F; 180112c6982bSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 5, 5); 180212c6982bSJozef Kolek 180312c6982bSJozef Kolek Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 180412c6982bSJozef Kolek 1805e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1806e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::SP)); 1807e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 180812c6982bSJozef Kolek 180912c6982bSJozef Kolek return MCDisassembler::Success; 181012c6982bSJozef Kolek } 181112c6982bSJozef Kolek 1812e10a02ecSJozef Kolek static DecodeStatus DecodeMemMMGPImm7Lsl2(MCInst &Inst, 1813e10a02ecSJozef Kolek unsigned Insn, 1814e10a02ecSJozef Kolek uint64_t Address, 1815e10a02ecSJozef Kolek const void *Decoder) { 1816e10a02ecSJozef Kolek unsigned Offset = Insn & 0x7F; 1817e10a02ecSJozef Kolek unsigned Reg = fieldFromInstruction(Insn, 7, 3); 1818e10a02ecSJozef Kolek 1819e10a02ecSJozef Kolek Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1820e10a02ecSJozef Kolek 1821e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1822e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::GP)); 1823e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 1824e10a02ecSJozef Kolek 1825e10a02ecSJozef Kolek return MCDisassembler::Success; 1826e10a02ecSJozef Kolek } 1827e10a02ecSJozef Kolek 1828d68d424aSJozef Kolek static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst, 1829d68d424aSJozef Kolek unsigned Insn, 1830d68d424aSJozef Kolek uint64_t Address, 1831d68d424aSJozef Kolek const void *Decoder) { 1832797c2aecSZlatko Buljan int Offset; 1833797c2aecSZlatko Buljan switch (Inst.getOpcode()) { 1834797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 1835797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 1836797c2aecSZlatko Buljan Offset = fieldFromInstruction(Insn, 4, 4); 1837797c2aecSZlatko Buljan break; 1838797c2aecSZlatko Buljan default: 1839797c2aecSZlatko Buljan Offset = SignExtend32<4>(Insn & 0xf); 1840797c2aecSZlatko Buljan break; 1841797c2aecSZlatko Buljan } 1842d68d424aSJozef Kolek 1843d68d424aSJozef Kolek if (DecodeRegListOperand16(Inst, Insn, Address, Decoder) 1844d68d424aSJozef Kolek == MCDisassembler::Fail) 1845d68d424aSJozef Kolek return MCDisassembler::Fail; 1846d68d424aSJozef Kolek 1847e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::SP)); 1848e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset << 2)); 1849d68d424aSJozef Kolek 1850d68d424aSJozef Kolek return MCDisassembler::Success; 1851d68d424aSJozef Kolek } 1852d68d424aSJozef Kolek 1853a6593ff6SZoran Jovanovic static DecodeStatus DecodeMemMMImm9(MCInst &Inst, 1854a6593ff6SZoran Jovanovic unsigned Insn, 1855a6593ff6SZoran Jovanovic uint64_t Address, 1856a6593ff6SZoran Jovanovic const void *Decoder) { 1857a6593ff6SZoran Jovanovic int Offset = SignExtend32<9>(Insn & 0x1ff); 1858a6593ff6SZoran Jovanovic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1859a6593ff6SZoran Jovanovic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1860a6593ff6SZoran Jovanovic 1861a6593ff6SZoran Jovanovic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1862a6593ff6SZoran Jovanovic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1863a6593ff6SZoran Jovanovic 1864777afc7fSSimon Dardis if (Inst.getOpcode() == Mips::SCE_MM || Inst.getOpcode() == Mips::SC_MMR6) 18653ef4dd7bSHrvoje Varga Inst.addOperand(MCOperand::createReg(Reg)); 18663ef4dd7bSHrvoje Varga 1867a6593ff6SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Reg)); 1868a6593ff6SZoran Jovanovic Inst.addOperand(MCOperand::createReg(Base)); 1869a6593ff6SZoran Jovanovic Inst.addOperand(MCOperand::createImm(Offset)); 1870a6593ff6SZoran Jovanovic 1871a6593ff6SZoran Jovanovic return MCDisassembler::Success; 1872a6593ff6SZoran Jovanovic } 1873a6593ff6SZoran Jovanovic 1874dde3d582SVladimir Medic static DecodeStatus DecodeMemMMImm12(MCInst &Inst, 1875dde3d582SVladimir Medic unsigned Insn, 1876dde3d582SVladimir Medic uint64_t Address, 1877dde3d582SVladimir Medic const void *Decoder) { 1878dde3d582SVladimir Medic int Offset = SignExtend32<12>(Insn & 0x0fff); 1879dde3d582SVladimir Medic unsigned Reg = fieldFromInstruction(Insn, 21, 5); 1880dde3d582SVladimir Medic unsigned Base = fieldFromInstruction(Insn, 16, 5); 1881dde3d582SVladimir Medic 1882dde3d582SVladimir Medic Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); 1883dde3d582SVladimir Medic Base = getReg(Decoder, Mips::GPR32RegClassID, Base); 1884dde3d582SVladimir Medic 1885a4c4b5fcSZoran Jovanovic switch (Inst.getOpcode()) { 1886a4c4b5fcSZoran Jovanovic case Mips::SWM32_MM: 1887a4c4b5fcSZoran Jovanovic case Mips::LWM32_MM: 1888a4c4b5fcSZoran Jovanovic if (DecodeRegListOperand(Inst, Insn, Address, Decoder) 1889a4c4b5fcSZoran Jovanovic == MCDisassembler::Fail) 1890a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 1891e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base)); 1892e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Offset)); 1893a4c4b5fcSZoran Jovanovic break; 1894a4c4b5fcSZoran Jovanovic case Mips::SC_MM: 1895e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 1896b03fd12cSJustin Bogner LLVM_FALLTHROUGH; 1897a4c4b5fcSZoran Jovanovic default: 1898e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Reg)); 18996a319923SSimon Dardis if (Inst.getOpcode() == Mips::LWP_MM || Inst.getOpcode() == Mips::SWP_MM) 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 2301*56e4ea2bSSimon Atanasyan static DecodeStatus DecodeJumpTargetXMM(MCInst &Inst, 2302*56e4ea2bSSimon Atanasyan unsigned Insn, 2303*56e4ea2bSSimon Atanasyan uint64_t Address, 2304*56e4ea2bSSimon Atanasyan const void *Decoder) { 2305*56e4ea2bSSimon Atanasyan unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2; 2306*56e4ea2bSSimon Atanasyan Inst.addOperand(MCOperand::createImm(JumpOffset)); 2307*56e4ea2bSSimon Atanasyan return MCDisassembler::Success; 2308*56e4ea2bSSimon Atanasyan } 2309*56e4ea2bSSimon Atanasyan 2310aa2b9278SJozef Kolek static DecodeStatus DecodeAddiur2Simm7(MCInst &Inst, 2311aa2b9278SJozef Kolek unsigned Value, 2312aa2b9278SJozef Kolek uint64_t Address, 2313aa2b9278SJozef Kolek const void *Decoder) { 2314aa2b9278SJozef Kolek if (Value == 0) 2315e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(1)); 2316aa2b9278SJozef Kolek else if (Value == 0x7) 2317e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(-1)); 2318aa2b9278SJozef Kolek else 2319e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Value << 2)); 2320aa2b9278SJozef Kolek return MCDisassembler::Success; 2321aa2b9278SJozef Kolek } 2322aa2b9278SJozef Kolek 232397297770SDaniel Sanders static DecodeStatus DecodeLi16Imm(MCInst &Inst, 2324aa2b9278SJozef Kolek unsigned Value, 2325aa2b9278SJozef Kolek uint64_t Address, 2326aa2b9278SJozef Kolek const void *Decoder) { 2327aa2b9278SJozef Kolek if (Value == 0x7F) 2328e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(-1)); 2329aa2b9278SJozef Kolek else 2330e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Value)); 2331aa2b9278SJozef Kolek return MCDisassembler::Success; 2332aa2b9278SJozef Kolek } 2333aa2b9278SJozef Kolek 23346b28f09dSZoran Jovanovic static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, 23356b28f09dSZoran Jovanovic unsigned Value, 23366b28f09dSZoran Jovanovic uint64_t Address, 23376b28f09dSZoran Jovanovic const void *Decoder) { 23386b28f09dSZoran Jovanovic Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value)); 23396b28f09dSZoran Jovanovic return MCDisassembler::Success; 23406b28f09dSZoran Jovanovic } 23416b28f09dSZoran Jovanovic 234219b7f76aSDaniel Sanders template <unsigned Bits, int Offset, int Scale> 234319b7f76aSDaniel Sanders static DecodeStatus DecodeUImmWithOffsetAndScale(MCInst &Inst, unsigned Value, 2344779c5937SMatheus Almeida uint64_t Address, 2345779c5937SMatheus Almeida const void *Decoder) { 2346ea4f653dSDaniel Sanders Value &= ((1 << Bits) - 1); 234719b7f76aSDaniel Sanders Value *= Scale; 2348ea4f653dSDaniel Sanders Inst.addOperand(MCOperand::createImm(Value + Offset)); 2349779c5937SMatheus Almeida return MCDisassembler::Success; 2350779c5937SMatheus Almeida } 2351779c5937SMatheus Almeida 235297297770SDaniel Sanders template <unsigned Bits, int Offset, int ScaleBy> 235397297770SDaniel Sanders static DecodeStatus DecodeSImmWithOffsetAndScale(MCInst &Inst, unsigned Value, 235478e89020SDaniel Sanders uint64_t Address, 235578e89020SDaniel Sanders const void *Decoder) { 235697297770SDaniel Sanders int32_t Imm = SignExtend32<Bits>(Value) * ScaleBy; 235778e89020SDaniel Sanders Inst.addOperand(MCOperand::createImm(Imm + Offset)); 235878e89020SDaniel Sanders return MCDisassembler::Success; 235978e89020SDaniel Sanders } 236078e89020SDaniel Sanders 236171928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst, 236271928e68SAkira Hatanaka unsigned Insn, 236371928e68SAkira Hatanaka uint64_t Address, 236471928e68SAkira Hatanaka const void *Decoder) { 236571928e68SAkira Hatanaka // First we need to grab the pos(lsb) from MCInst. 23666f83ae38SSimon Dardis // This function only handles the 32 bit variants of ins, as dins 23676f83ae38SSimon Dardis // variants are handled differently. 236871928e68SAkira Hatanaka int Pos = Inst.getOperand(2).getImm(); 23696f83ae38SSimon Dardis int Size = (int) Insn - Pos + 1; 2370e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size))); 237171928e68SAkira Hatanaka return MCDisassembler::Success; 237271928e68SAkira Hatanaka } 237371928e68SAkira Hatanaka 2374b59e1a41SDaniel Sanders static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn, 2375b59e1a41SDaniel Sanders uint64_t Address, const void *Decoder) { 2376e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4)); 2377b59e1a41SDaniel Sanders return MCDisassembler::Success; 2378b59e1a41SDaniel Sanders } 23792855142aSZoran Jovanovic 23802855142aSZoran Jovanovic static DecodeStatus DecodeSimm18Lsl3(MCInst &Inst, unsigned Insn, 23812855142aSZoran Jovanovic uint64_t Address, const void *Decoder) { 2382e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend32<18>(Insn) * 8)); 23832855142aSZoran Jovanovic return MCDisassembler::Success; 23842855142aSZoran Jovanovic } 2385a4c4b5fcSZoran Jovanovic 2386b682ddf3SVladimir Medic static DecodeStatus DecodeSimm9SP(MCInst &Inst, unsigned Insn, 2387b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 2388b682ddf3SVladimir Medic int32_t DecodedValue; 2389b682ddf3SVladimir Medic switch (Insn) { 2390b682ddf3SVladimir Medic case 0: DecodedValue = 256; break; 2391b682ddf3SVladimir Medic case 1: DecodedValue = 257; break; 2392b682ddf3SVladimir Medic case 510: DecodedValue = -258; break; 2393b682ddf3SVladimir Medic case 511: DecodedValue = -257; break; 2394b682ddf3SVladimir Medic default: DecodedValue = SignExtend32<9>(Insn); break; 2395b682ddf3SVladimir Medic } 2396e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(DecodedValue * 4)); 2397b682ddf3SVladimir Medic return MCDisassembler::Success; 2398b682ddf3SVladimir Medic } 2399b682ddf3SVladimir Medic 2400b682ddf3SVladimir Medic static DecodeStatus DecodeANDI16Imm(MCInst &Inst, unsigned Insn, 2401b682ddf3SVladimir Medic uint64_t Address, const void *Decoder) { 2402b682ddf3SVladimir Medic // Insn must be >= 0, since it is unsigned that condition is always true. 2403b682ddf3SVladimir Medic assert(Insn < 16); 2404b682ddf3SVladimir Medic int32_t DecodedValues[] = {128, 1, 2, 3, 4, 7, 8, 15, 16, 31, 32, 63, 64, 2405b682ddf3SVladimir Medic 255, 32768, 65535}; 2406e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(DecodedValues[Insn])); 2407b682ddf3SVladimir Medic return MCDisassembler::Success; 2408b682ddf3SVladimir Medic } 2409b682ddf3SVladimir Medic 2410a4c4b5fcSZoran Jovanovic static DecodeStatus DecodeRegListOperand(MCInst &Inst, 2411a4c4b5fcSZoran Jovanovic unsigned Insn, 2412a4c4b5fcSZoran Jovanovic uint64_t Address, 2413a4c4b5fcSZoran Jovanovic const void *Decoder) { 2414a4c4b5fcSZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5, 2415dc4b8c27SZoran Jovanovic Mips::S6, Mips::S7, Mips::FP}; 2416a4c4b5fcSZoran Jovanovic unsigned RegNum; 2417a4c4b5fcSZoran Jovanovic 2418a4c4b5fcSZoran Jovanovic unsigned RegLst = fieldFromInstruction(Insn, 21, 5); 2419df19a5e6SDaniel Sanders 2420a4c4b5fcSZoran Jovanovic // Empty register lists are not allowed. 2421a4c4b5fcSZoran Jovanovic if (RegLst == 0) 2422a4c4b5fcSZoran Jovanovic return MCDisassembler::Fail; 2423a4c4b5fcSZoran Jovanovic 2424a4c4b5fcSZoran Jovanovic RegNum = RegLst & 0xf; 2425df19a5e6SDaniel Sanders 2426df19a5e6SDaniel Sanders // RegLst values 10-15, and 26-31 are reserved. 2427df19a5e6SDaniel Sanders if (RegNum > 9) 2428df19a5e6SDaniel Sanders return MCDisassembler::Fail; 2429df19a5e6SDaniel Sanders 2430a4c4b5fcSZoran Jovanovic for (unsigned i = 0; i < RegNum; i++) 2431e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Regs[i])); 2432a4c4b5fcSZoran Jovanovic 2433a4c4b5fcSZoran Jovanovic if (RegLst & 0x10) 2434e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::RA)); 2435a4c4b5fcSZoran Jovanovic 2436a4c4b5fcSZoran Jovanovic return MCDisassembler::Success; 2437a4c4b5fcSZoran Jovanovic } 2438f9a02500SZoran Jovanovic 2439f9a02500SZoran Jovanovic static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn, 2440f9a02500SZoran Jovanovic uint64_t Address, 2441f9a02500SZoran Jovanovic const void *Decoder) { 2442f9a02500SZoran Jovanovic unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3}; 2443797c2aecSZlatko Buljan unsigned RegLst; 2444797c2aecSZlatko Buljan switch(Inst.getOpcode()) { 2445797c2aecSZlatko Buljan default: 2446797c2aecSZlatko Buljan RegLst = fieldFromInstruction(Insn, 4, 2); 2447797c2aecSZlatko Buljan break; 2448797c2aecSZlatko Buljan case Mips::LWM16_MMR6: 2449797c2aecSZlatko Buljan case Mips::SWM16_MMR6: 2450797c2aecSZlatko Buljan RegLst = fieldFromInstruction(Insn, 8, 2); 2451797c2aecSZlatko Buljan break; 2452797c2aecSZlatko Buljan } 2453d68d424aSJozef Kolek unsigned RegNum = RegLst & 0x3; 2454f9a02500SZoran Jovanovic 2455d68d424aSJozef Kolek for (unsigned i = 0; i <= RegNum; i++) 2456e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Regs[i])); 2457f9a02500SZoran Jovanovic 2458e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::RA)); 2459f9a02500SZoran Jovanovic 2460f9a02500SZoran Jovanovic return MCDisassembler::Success; 2461f9a02500SZoran Jovanovic } 24622c6d7320SJozef Kolek 2463852dd83bSSimon Atanasyan static DecodeStatus DecodeMovePOperands(MCInst &Inst, unsigned Insn, 2464852dd83bSSimon Atanasyan uint64_t Address, 2465852dd83bSSimon Atanasyan const void *Decoder) { 2466852dd83bSSimon Atanasyan unsigned RegPair = fieldFromInstruction(Insn, 7, 3); 2467852dd83bSSimon Atanasyan if (DecodeMovePRegPair(Inst, RegPair, Address, Decoder) == 2468852dd83bSSimon Atanasyan MCDisassembler::Fail) 2469852dd83bSSimon Atanasyan return MCDisassembler::Fail; 2470852dd83bSSimon Atanasyan 2471852dd83bSSimon Atanasyan unsigned RegRs; 2472852dd83bSSimon Atanasyan if (static_cast<const MipsDisassembler*>(Decoder)->hasMips32r6()) 2473852dd83bSSimon Atanasyan RegRs = fieldFromInstruction(Insn, 0, 2) | 2474852dd83bSSimon Atanasyan (fieldFromInstruction(Insn, 3, 1) << 2); 2475852dd83bSSimon Atanasyan else 2476852dd83bSSimon Atanasyan RegRs = fieldFromInstruction(Insn, 1, 3); 2477852dd83bSSimon Atanasyan if (DecodeGPRMM16MovePRegisterClass(Inst, RegRs, Address, Decoder) == 2478852dd83bSSimon Atanasyan MCDisassembler::Fail) 2479852dd83bSSimon Atanasyan return MCDisassembler::Fail; 2480852dd83bSSimon Atanasyan 2481852dd83bSSimon Atanasyan unsigned RegRt = fieldFromInstruction(Insn, 4, 3); 2482852dd83bSSimon Atanasyan if (DecodeGPRMM16MovePRegisterClass(Inst, RegRt, Address, Decoder) == 2483852dd83bSSimon Atanasyan MCDisassembler::Fail) 2484852dd83bSSimon Atanasyan return MCDisassembler::Fail; 2485852dd83bSSimon Atanasyan 2486852dd83bSSimon Atanasyan return MCDisassembler::Success; 2487852dd83bSSimon Atanasyan } 2488852dd83bSSimon Atanasyan 2489169df4e2SSimon Dardis static DecodeStatus DecodeMovePRegPair(MCInst &Inst, unsigned RegPair, 249041688679SZoran Jovanovic uint64_t Address, const void *Decoder) { 249141688679SZoran Jovanovic switch (RegPair) { 249241688679SZoran Jovanovic default: 249341688679SZoran Jovanovic return MCDisassembler::Fail; 249441688679SZoran Jovanovic case 0: 2495e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A1)); 2496e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A2)); 249741688679SZoran Jovanovic break; 249841688679SZoran Jovanovic case 1: 2499e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A1)); 2500e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A3)); 250141688679SZoran Jovanovic break; 250241688679SZoran Jovanovic case 2: 2503e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A2)); 2504e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A3)); 250541688679SZoran Jovanovic break; 250641688679SZoran Jovanovic case 3: 2507e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2508e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::S5)); 250941688679SZoran Jovanovic break; 251041688679SZoran Jovanovic case 4: 2511e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2512e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::S6)); 251341688679SZoran Jovanovic break; 251441688679SZoran Jovanovic case 5: 2515e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2516e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A1)); 251741688679SZoran Jovanovic break; 251841688679SZoran Jovanovic case 6: 2519e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2520e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A2)); 252141688679SZoran Jovanovic break; 252241688679SZoran Jovanovic case 7: 2523e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A0)); 2524e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Mips::A3)); 252541688679SZoran Jovanovic break; 252641688679SZoran Jovanovic } 252741688679SZoran Jovanovic 252841688679SZoran Jovanovic return MCDisassembler::Success; 252941688679SZoran Jovanovic } 253041688679SZoran Jovanovic 25312c6d7320SJozef Kolek static DecodeStatus DecodeSimm23Lsl2(MCInst &Inst, unsigned Insn, 25322c6d7320SJozef Kolek uint64_t Address, const void *Decoder) { 25336499b5f0SJustin Bogner Inst.addOperand(MCOperand::createImm(SignExtend32<25>(Insn << 2))); 25342c6d7320SJozef Kolek return MCDisassembler::Success; 25352c6d7320SJozef Kolek } 2536fdbd0a37SZoran Jovanovic 2537fdbd0a37SZoran Jovanovic template <typename InsnType> 2538fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBgtzGroupBranchMMR6(MCInst &MI, InsnType insn, 2539fdbd0a37SZoran Jovanovic uint64_t Address, 2540fdbd0a37SZoran Jovanovic const void *Decoder) { 2541fdbd0a37SZoran Jovanovic // We have: 2542fdbd0a37SZoran Jovanovic // 0b000111 ttttt sssss iiiiiiiiiiiiiiii 2543fdbd0a37SZoran Jovanovic // Invalid if rt == 0 2544fdbd0a37SZoran Jovanovic // BGTZALC_MMR6 if rs == 0 && rt != 0 2545fdbd0a37SZoran Jovanovic // BLTZALC_MMR6 if rs != 0 && rs == rt 2546fdbd0a37SZoran Jovanovic // BLTUC_MMR6 if rs != 0 && rs != rt 2547fdbd0a37SZoran Jovanovic 2548fdbd0a37SZoran Jovanovic InsnType Rt = fieldFromInstruction(insn, 21, 5); 2549fdbd0a37SZoran Jovanovic InsnType Rs = fieldFromInstruction(insn, 16, 5); 2550f0ed16eaSHrvoje Varga InsnType Imm = 0; 2551fdbd0a37SZoran Jovanovic bool HasRs = false; 2552fdbd0a37SZoran Jovanovic bool HasRt = false; 2553fdbd0a37SZoran Jovanovic 2554fdbd0a37SZoran Jovanovic if (Rt == 0) 2555fdbd0a37SZoran Jovanovic return MCDisassembler::Fail; 2556fdbd0a37SZoran Jovanovic else if (Rs == 0) { 2557fdbd0a37SZoran Jovanovic MI.setOpcode(Mips::BGTZALC_MMR6); 2558fdbd0a37SZoran Jovanovic HasRt = true; 2559f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 2560fdbd0a37SZoran Jovanovic } 2561fdbd0a37SZoran Jovanovic else if (Rs == Rt) { 2562fdbd0a37SZoran Jovanovic MI.setOpcode(Mips::BLTZALC_MMR6); 2563fdbd0a37SZoran Jovanovic HasRs = true; 2564f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 2565fdbd0a37SZoran Jovanovic } 2566fdbd0a37SZoran Jovanovic else { 2567fdbd0a37SZoran Jovanovic MI.setOpcode(Mips::BLTUC_MMR6); 2568fdbd0a37SZoran Jovanovic HasRs = true; 2569fdbd0a37SZoran Jovanovic HasRt = true; 2570f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 2571fdbd0a37SZoran Jovanovic } 2572fdbd0a37SZoran Jovanovic 2573fdbd0a37SZoran Jovanovic if (HasRs) 2574fdbd0a37SZoran Jovanovic MI.addOperand( 2575fdbd0a37SZoran Jovanovic MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); 2576fdbd0a37SZoran Jovanovic 2577fdbd0a37SZoran Jovanovic if (HasRt) 2578fdbd0a37SZoran Jovanovic MI.addOperand( 2579fdbd0a37SZoran Jovanovic MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); 2580fdbd0a37SZoran Jovanovic 2581fdbd0a37SZoran Jovanovic MI.addOperand(MCOperand::createImm(Imm)); 2582fdbd0a37SZoran Jovanovic 2583fdbd0a37SZoran Jovanovic return MCDisassembler::Success; 2584fdbd0a37SZoran Jovanovic } 2585fdbd0a37SZoran Jovanovic 2586fdbd0a37SZoran Jovanovic template <typename InsnType> 2587fdbd0a37SZoran Jovanovic static DecodeStatus DecodeBlezGroupBranchMMR6(MCInst &MI, InsnType insn, 2588fdbd0a37SZoran Jovanovic uint64_t Address, 2589fdbd0a37SZoran Jovanovic const void *Decoder) { 2590fdbd0a37SZoran Jovanovic // We have: 2591fdbd0a37SZoran Jovanovic // 0b000110 ttttt sssss iiiiiiiiiiiiiiii 2592f0ed16eaSHrvoje Varga // Invalid if rt == 0 2593fdbd0a37SZoran Jovanovic // BLEZALC_MMR6 if rs == 0 && rt != 0 2594fdbd0a37SZoran Jovanovic // BGEZALC_MMR6 if rs == rt && rt != 0 2595fdbd0a37SZoran Jovanovic // BGEUC_MMR6 if rs != rt && rs != 0 && rt != 0 2596fdbd0a37SZoran Jovanovic 2597fdbd0a37SZoran Jovanovic InsnType Rt = fieldFromInstruction(insn, 21, 5); 2598fdbd0a37SZoran Jovanovic InsnType Rs = fieldFromInstruction(insn, 16, 5); 2599f0ed16eaSHrvoje Varga InsnType Imm = 0; 2600fdbd0a37SZoran Jovanovic bool HasRs = false; 2601fdbd0a37SZoran Jovanovic 2602fdbd0a37SZoran Jovanovic if (Rt == 0) 2603fdbd0a37SZoran Jovanovic return MCDisassembler::Fail; 2604f0ed16eaSHrvoje Varga else if (Rs == 0) { 2605fdbd0a37SZoran Jovanovic MI.setOpcode(Mips::BLEZALC_MMR6); 2606f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 2607f0ed16eaSHrvoje Varga } 2608f0ed16eaSHrvoje Varga else if (Rs == Rt) { 2609fdbd0a37SZoran Jovanovic MI.setOpcode(Mips::BGEZALC_MMR6); 2610f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 2 + 4; 2611f0ed16eaSHrvoje Varga } 2612fdbd0a37SZoran Jovanovic else { 2613fdbd0a37SZoran Jovanovic HasRs = true; 2614fdbd0a37SZoran Jovanovic MI.setOpcode(Mips::BGEUC_MMR6); 2615f0ed16eaSHrvoje Varga Imm = SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4 + 4; 2616fdbd0a37SZoran Jovanovic } 2617fdbd0a37SZoran Jovanovic 2618fdbd0a37SZoran Jovanovic if (HasRs) 2619fdbd0a37SZoran Jovanovic MI.addOperand( 2620fdbd0a37SZoran Jovanovic MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rs))); 2621fdbd0a37SZoran Jovanovic MI.addOperand( 2622fdbd0a37SZoran Jovanovic MCOperand::createReg(getReg(Decoder, Mips::GPR32RegClassID, Rt))); 2623fdbd0a37SZoran Jovanovic 2624fdbd0a37SZoran Jovanovic MI.addOperand(MCOperand::createImm(Imm)); 2625fdbd0a37SZoran Jovanovic 2626fdbd0a37SZoran Jovanovic return MCDisassembler::Success; 2627fdbd0a37SZoran Jovanovic } 2628