171928e68SAkira Hatanaka //===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
271928e68SAkira Hatanaka //
371928e68SAkira Hatanaka //                     The LLVM Compiler Infrastructure
471928e68SAkira Hatanaka //
571928e68SAkira Hatanaka // This file is distributed under the University of Illinois Open Source
671928e68SAkira Hatanaka // License. See LICENSE.TXT for details.
771928e68SAkira Hatanaka //
871928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
971928e68SAkira Hatanaka //
1071928e68SAkira Hatanaka // This file is part of the Mips Disassembler.
1171928e68SAkira Hatanaka //
1271928e68SAkira Hatanaka //===----------------------------------------------------------------------===//
1371928e68SAkira Hatanaka 
1471928e68SAkira Hatanaka #include "Mips.h"
159bf2b567SAkira Hatanaka #include "MipsRegisterInfo.h"
16ed0881b2SChandler Carruth #include "MipsSubtarget.h"
1771928e68SAkira Hatanaka #include "llvm/MC/MCDisassembler.h"
18ecaef49fSJim Grosbach #include "llvm/MC/MCFixedLenDisassembler.h"
19ed0881b2SChandler Carruth #include "llvm/MC/MCInst.h"
20ed0881b2SChandler Carruth #include "llvm/MC/MCSubtargetInfo.h"
21ed0881b2SChandler Carruth #include "llvm/Support/MathExtras.h"
2271928e68SAkira Hatanaka #include "llvm/Support/MemoryObject.h"
2371928e68SAkira Hatanaka #include "llvm/Support/TargetRegistry.h"
2471928e68SAkira Hatanaka 
2571928e68SAkira Hatanaka using namespace llvm;
2671928e68SAkira Hatanaka 
2771928e68SAkira Hatanaka typedef MCDisassembler::DecodeStatus DecodeStatus;
2871928e68SAkira Hatanaka 
29cb3e98cfSBenjamin Kramer namespace {
30cb3e98cfSBenjamin Kramer 
319bf2b567SAkira Hatanaka /// MipsDisassemblerBase - a disasembler class for Mips.
329bf2b567SAkira Hatanaka class MipsDisassemblerBase : public MCDisassembler {
3371928e68SAkira Hatanaka public:
3471928e68SAkira Hatanaka   /// Constructor     - Initializes the disassembler.
3571928e68SAkira Hatanaka   ///
369bf2b567SAkira Hatanaka   MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
379bf2b567SAkira Hatanaka                        bool bigEndian) :
38*9bfa2e2eSAkira Hatanaka     MCDisassembler(STI), RegInfo(Info),
39*9bfa2e2eSAkira Hatanaka     IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {}
4071928e68SAkira Hatanaka 
419bf2b567SAkira Hatanaka   virtual ~MipsDisassemblerBase() {}
429bf2b567SAkira Hatanaka 
43dcfd5b52SBenjamin Kramer   const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
449bf2b567SAkira Hatanaka 
45*9bfa2e2eSAkira Hatanaka   bool isN64() const { return IsN64; }
46*9bfa2e2eSAkira Hatanaka 
479bf2b567SAkira Hatanaka private:
48dcfd5b52SBenjamin Kramer   OwningPtr<const MCRegisterInfo> RegInfo;
49*9bfa2e2eSAkira Hatanaka   bool IsN64;
509bf2b567SAkira Hatanaka protected:
519bf2b567SAkira Hatanaka   bool isBigEndian;
529bf2b567SAkira Hatanaka };
539bf2b567SAkira Hatanaka 
549bf2b567SAkira Hatanaka /// MipsDisassembler - a disasembler class for Mips32.
559bf2b567SAkira Hatanaka class MipsDisassembler : public MipsDisassemblerBase {
569bf2b567SAkira Hatanaka public:
579bf2b567SAkira Hatanaka   /// Constructor     - Initializes the disassembler.
589bf2b567SAkira Hatanaka   ///
599bf2b567SAkira Hatanaka   MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
609bf2b567SAkira Hatanaka                    bool bigEndian) :
619bf2b567SAkira Hatanaka     MipsDisassemblerBase(STI, Info, bigEndian) {}
6271928e68SAkira Hatanaka 
6371928e68SAkira Hatanaka   /// getInstruction - See MCDisassembler.
649bf2b567SAkira Hatanaka   virtual DecodeStatus getInstruction(MCInst &instr,
6571928e68SAkira Hatanaka                                       uint64_t &size,
6671928e68SAkira Hatanaka                                       const MemoryObject &region,
6771928e68SAkira Hatanaka                                       uint64_t address,
6871928e68SAkira Hatanaka                                       raw_ostream &vStream,
6971928e68SAkira Hatanaka                                       raw_ostream &cStream) const;
7071928e68SAkira Hatanaka };
7171928e68SAkira Hatanaka 
7271928e68SAkira Hatanaka 
7371928e68SAkira Hatanaka /// Mips64Disassembler - a disasembler class for Mips64.
749bf2b567SAkira Hatanaka class Mips64Disassembler : public MipsDisassemblerBase {
7571928e68SAkira Hatanaka public:
7671928e68SAkira Hatanaka   /// Constructor     - Initializes the disassembler.
7771928e68SAkira Hatanaka   ///
789bf2b567SAkira Hatanaka   Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
799bf2b567SAkira Hatanaka                      bool bigEndian) :
809bf2b567SAkira Hatanaka     MipsDisassemblerBase(STI, Info, bigEndian) {}
8171928e68SAkira Hatanaka 
8271928e68SAkira Hatanaka   /// getInstruction - See MCDisassembler.
839bf2b567SAkira Hatanaka   virtual DecodeStatus getInstruction(MCInst &instr,
8471928e68SAkira Hatanaka                                       uint64_t &size,
8571928e68SAkira Hatanaka                                       const MemoryObject &region,
8671928e68SAkira Hatanaka                                       uint64_t address,
8771928e68SAkira Hatanaka                                       raw_ostream &vStream,
8871928e68SAkira Hatanaka                                       raw_ostream &cStream) const;
8971928e68SAkira Hatanaka };
9071928e68SAkira Hatanaka 
91cb3e98cfSBenjamin Kramer } // end anonymous namespace
92cb3e98cfSBenjamin Kramer 
9371928e68SAkira Hatanaka // Forward declare these because the autogenerated code will reference them.
9471928e68SAkira Hatanaka // Definitions are further down.
9513e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
9671928e68SAkira Hatanaka                                              unsigned RegNo,
9771928e68SAkira Hatanaka                                              uint64_t Address,
9871928e68SAkira Hatanaka                                              const void *Decoder);
9971928e68SAkira Hatanaka 
100ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
101ec8a5490SReed Kotler                                                  unsigned RegNo,
102ec8a5490SReed Kotler                                                  uint64_t Address,
103ec8a5490SReed Kotler                                                  const void *Decoder);
104ec8a5490SReed Kotler 
10513e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
10671928e68SAkira Hatanaka                                              unsigned RegNo,
10771928e68SAkira Hatanaka                                              uint64_t Address,
10871928e68SAkira Hatanaka                                              const void *Decoder);
10971928e68SAkira Hatanaka 
110*9bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
111*9bfa2e2eSAkira Hatanaka                                            unsigned Insn,
112*9bfa2e2eSAkira Hatanaka                                            uint64_t Address,
113*9bfa2e2eSAkira Hatanaka                                            const void *Decoder);
114*9bfa2e2eSAkira Hatanaka 
115654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
116ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
117ecabd1a5SAkira Hatanaka                                             uint64_t Address,
118ecabd1a5SAkira Hatanaka                                             const void *Decoder);
119ecabd1a5SAkira Hatanaka 
12071928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
12171928e68SAkira Hatanaka                                              unsigned RegNo,
12271928e68SAkira Hatanaka                                              uint64_t Address,
12371928e68SAkira Hatanaka                                              const void *Decoder);
12471928e68SAkira Hatanaka 
12571928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
12671928e68SAkira Hatanaka                                              unsigned RegNo,
12771928e68SAkira Hatanaka                                              uint64_t Address,
12871928e68SAkira Hatanaka                                              const void *Decoder);
12971928e68SAkira Hatanaka 
13014e31a2fSAkira Hatanaka static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
13114e31a2fSAkira Hatanaka                                               unsigned RegNo,
13214e31a2fSAkira Hatanaka                                               uint64_t Address,
13314e31a2fSAkira Hatanaka                                               const void *Decoder);
13414e31a2fSAkira Hatanaka 
13571928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
13671928e68SAkira Hatanaka                                            unsigned RegNo,
13771928e68SAkira Hatanaka                                            uint64_t Address,
13871928e68SAkira Hatanaka                                            const void *Decoder);
13971928e68SAkira Hatanaka 
1401fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1411fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
1421fb1b8b8SAkira Hatanaka                                            uint64_t Address,
1431fb1b8b8SAkira Hatanaka                                            const void *Decoder);
1441fb1b8b8SAkira Hatanaka 
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 
17071928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
17171928e68SAkira Hatanaka                                        unsigned Offset,
17271928e68SAkira Hatanaka                                        uint64_t Address,
17371928e68SAkira Hatanaka                                        const void *Decoder);
17471928e68SAkira Hatanaka 
17571928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
17671928e68SAkira Hatanaka                                      unsigned Insn,
17771928e68SAkira Hatanaka                                      uint64_t Address,
17871928e68SAkira Hatanaka                                      const void *Decoder);
17971928e68SAkira Hatanaka 
18071928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
18171928e68SAkira Hatanaka                               unsigned Insn,
18271928e68SAkira Hatanaka                               uint64_t Address,
18371928e68SAkira Hatanaka                               const void *Decoder);
18471928e68SAkira Hatanaka 
18571928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
18671928e68SAkira Hatanaka                                uint64_t Address,
18771928e68SAkira Hatanaka                                const void *Decoder);
18871928e68SAkira Hatanaka 
18971928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
19071928e68SAkira Hatanaka                                  unsigned Insn,
19171928e68SAkira Hatanaka                                  uint64_t Address,
19271928e68SAkira Hatanaka                                  const void *Decoder);
19371928e68SAkira Hatanaka 
19471928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
19571928e68SAkira Hatanaka                                   unsigned Insn,
19671928e68SAkira Hatanaka                                   uint64_t Address,
19771928e68SAkira Hatanaka                                   const void *Decoder);
19871928e68SAkira Hatanaka 
19971928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
20071928e68SAkira Hatanaka                                   unsigned Insn,
20171928e68SAkira Hatanaka                                   uint64_t Address,
20271928e68SAkira Hatanaka                                   const void *Decoder);
20371928e68SAkira Hatanaka 
20471928e68SAkira Hatanaka namespace llvm {
20571928e68SAkira Hatanaka extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
20671928e68SAkira Hatanaka               TheMips64elTarget;
20771928e68SAkira Hatanaka }
20871928e68SAkira Hatanaka 
20971928e68SAkira Hatanaka static MCDisassembler *createMipsDisassembler(
21071928e68SAkira Hatanaka                        const Target &T,
21171928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2129bf2b567SAkira Hatanaka   return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
21371928e68SAkira Hatanaka }
21471928e68SAkira Hatanaka 
21571928e68SAkira Hatanaka static MCDisassembler *createMipselDisassembler(
21671928e68SAkira Hatanaka                        const Target &T,
21771928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2189bf2b567SAkira Hatanaka   return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
21971928e68SAkira Hatanaka }
22071928e68SAkira Hatanaka 
22171928e68SAkira Hatanaka static MCDisassembler *createMips64Disassembler(
22271928e68SAkira Hatanaka                        const Target &T,
22371928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2249bf2b567SAkira Hatanaka   return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
22571928e68SAkira Hatanaka }
22671928e68SAkira Hatanaka 
22771928e68SAkira Hatanaka static MCDisassembler *createMips64elDisassembler(
22871928e68SAkira Hatanaka                        const Target &T,
22971928e68SAkira Hatanaka                        const MCSubtargetInfo &STI) {
2309bf2b567SAkira Hatanaka   return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
23171928e68SAkira Hatanaka }
23271928e68SAkira Hatanaka 
23371928e68SAkira Hatanaka extern "C" void LLVMInitializeMipsDisassembler() {
23471928e68SAkira Hatanaka   // Register the disassembler.
23571928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
23671928e68SAkira Hatanaka                                          createMipsDisassembler);
23771928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
23871928e68SAkira Hatanaka                                          createMipselDisassembler);
23971928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
24071928e68SAkira Hatanaka                                          createMips64Disassembler);
24171928e68SAkira Hatanaka   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
24271928e68SAkira Hatanaka                                          createMips64elDisassembler);
24371928e68SAkira Hatanaka }
24471928e68SAkira Hatanaka 
24571928e68SAkira Hatanaka 
24671928e68SAkira Hatanaka #include "MipsGenDisassemblerTables.inc"
24771928e68SAkira Hatanaka 
24871928e68SAkira Hatanaka   /// readInstruction - read four bytes from the MemoryObject
24971928e68SAkira Hatanaka   /// and return 32 bit word sorted according to the given endianess
25071928e68SAkira Hatanaka static DecodeStatus readInstruction32(const MemoryObject &region,
25171928e68SAkira Hatanaka                                       uint64_t address,
25271928e68SAkira Hatanaka                                       uint64_t &size,
25371928e68SAkira Hatanaka                                       uint32_t &insn,
25471928e68SAkira Hatanaka                                       bool isBigEndian) {
25571928e68SAkira Hatanaka   uint8_t Bytes[4];
25671928e68SAkira Hatanaka 
25771928e68SAkira Hatanaka   // We want to read exactly 4 Bytes of data.
258534d3a46SBenjamin Kramer   if (region.readBytes(address, 4, Bytes) == -1) {
25971928e68SAkira Hatanaka     size = 0;
26071928e68SAkira Hatanaka     return MCDisassembler::Fail;
26171928e68SAkira Hatanaka   }
26271928e68SAkira Hatanaka 
26371928e68SAkira Hatanaka   if (isBigEndian) {
26471928e68SAkira Hatanaka     // Encoded as a big-endian 32-bit word in the stream.
26571928e68SAkira Hatanaka     insn = (Bytes[3] <<  0) |
26671928e68SAkira Hatanaka            (Bytes[2] <<  8) |
26771928e68SAkira Hatanaka            (Bytes[1] << 16) |
26871928e68SAkira Hatanaka            (Bytes[0] << 24);
26971928e68SAkira Hatanaka   }
27071928e68SAkira Hatanaka   else {
27171928e68SAkira Hatanaka     // Encoded as a small-endian 32-bit word in the stream.
27271928e68SAkira Hatanaka     insn = (Bytes[0] <<  0) |
27371928e68SAkira Hatanaka            (Bytes[1] <<  8) |
27471928e68SAkira Hatanaka            (Bytes[2] << 16) |
27571928e68SAkira Hatanaka            (Bytes[3] << 24);
27671928e68SAkira Hatanaka   }
27771928e68SAkira Hatanaka 
27871928e68SAkira Hatanaka   return MCDisassembler::Success;
27971928e68SAkira Hatanaka }
28071928e68SAkira Hatanaka 
28171928e68SAkira Hatanaka DecodeStatus
28271928e68SAkira Hatanaka MipsDisassembler::getInstruction(MCInst &instr,
28371928e68SAkira Hatanaka                                  uint64_t &Size,
28471928e68SAkira Hatanaka                                  const MemoryObject &Region,
28571928e68SAkira Hatanaka                                  uint64_t Address,
28671928e68SAkira Hatanaka                                  raw_ostream &vStream,
28771928e68SAkira Hatanaka                                  raw_ostream &cStream) const {
28871928e68SAkira Hatanaka   uint32_t Insn;
28971928e68SAkira Hatanaka 
29071928e68SAkira Hatanaka   DecodeStatus Result = readInstruction32(Region, Address, Size,
29171928e68SAkira Hatanaka                                           Insn, isBigEndian);
29271928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
29371928e68SAkira Hatanaka     return MCDisassembler::Fail;
29471928e68SAkira Hatanaka 
29571928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
296ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
297ecaef49fSJim Grosbach                              this, STI);
29871928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
29971928e68SAkira Hatanaka     Size = 4;
30071928e68SAkira Hatanaka     return Result;
30171928e68SAkira Hatanaka   }
30271928e68SAkira Hatanaka 
30371928e68SAkira Hatanaka   return MCDisassembler::Fail;
30471928e68SAkira Hatanaka }
30571928e68SAkira Hatanaka 
30671928e68SAkira Hatanaka DecodeStatus
30771928e68SAkira Hatanaka Mips64Disassembler::getInstruction(MCInst &instr,
30871928e68SAkira Hatanaka                                    uint64_t &Size,
30971928e68SAkira Hatanaka                                    const MemoryObject &Region,
31071928e68SAkira Hatanaka                                    uint64_t Address,
31171928e68SAkira Hatanaka                                    raw_ostream &vStream,
31271928e68SAkira Hatanaka                                    raw_ostream &cStream) const {
31371928e68SAkira Hatanaka   uint32_t Insn;
31471928e68SAkira Hatanaka 
31571928e68SAkira Hatanaka   DecodeStatus Result = readInstruction32(Region, Address, Size,
31671928e68SAkira Hatanaka                                           Insn, isBigEndian);
31771928e68SAkira Hatanaka   if (Result == MCDisassembler::Fail)
31871928e68SAkira Hatanaka     return MCDisassembler::Fail;
31971928e68SAkira Hatanaka 
32071928e68SAkira Hatanaka   // Calling the auto-generated decoder function.
321ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
322ecaef49fSJim Grosbach                              this, STI);
32371928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
32471928e68SAkira Hatanaka     Size = 4;
32571928e68SAkira Hatanaka     return Result;
32671928e68SAkira Hatanaka   }
32771928e68SAkira Hatanaka   // If we fail to decode in Mips64 decoder space we can try in Mips32
328ecaef49fSJim Grosbach   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
329ecaef49fSJim Grosbach                              this, STI);
33071928e68SAkira Hatanaka   if (Result != MCDisassembler::Fail) {
33171928e68SAkira Hatanaka     Size = 4;
33271928e68SAkira Hatanaka     return Result;
33371928e68SAkira Hatanaka   }
33471928e68SAkira Hatanaka 
33571928e68SAkira Hatanaka   return MCDisassembler::Fail;
33671928e68SAkira Hatanaka }
33771928e68SAkira Hatanaka 
3389bf2b567SAkira Hatanaka static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
3399bf2b567SAkira Hatanaka   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
3409bf2b567SAkira Hatanaka   return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
3419bf2b567SAkira Hatanaka }
3429bf2b567SAkira Hatanaka 
343ec8a5490SReed Kotler static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
344ec8a5490SReed Kotler                                                  unsigned RegNo,
345ec8a5490SReed Kotler                                                  uint64_t Address,
346ec8a5490SReed Kotler                                                  const void *Decoder) {
347ec8a5490SReed Kotler 
348ec8a5490SReed Kotler   return MCDisassembler::Fail;
349ec8a5490SReed Kotler 
350ec8a5490SReed Kotler }
351ec8a5490SReed Kotler 
35213e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
35371928e68SAkira Hatanaka                                              unsigned RegNo,
35471928e68SAkira Hatanaka                                              uint64_t Address,
35571928e68SAkira Hatanaka                                              const void *Decoder) {
35671928e68SAkira Hatanaka 
35771928e68SAkira Hatanaka   if (RegNo > 31)
35871928e68SAkira Hatanaka     return MCDisassembler::Fail;
35971928e68SAkira Hatanaka 
36013e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
3619bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
36271928e68SAkira Hatanaka   return MCDisassembler::Success;
36371928e68SAkira Hatanaka }
36471928e68SAkira Hatanaka 
36513e6ccf3SAkira Hatanaka static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
36671928e68SAkira Hatanaka                                              unsigned RegNo,
36771928e68SAkira Hatanaka                                              uint64_t Address,
36871928e68SAkira Hatanaka                                              const void *Decoder) {
36971928e68SAkira Hatanaka   if (RegNo > 31)
37071928e68SAkira Hatanaka     return MCDisassembler::Fail;
37113e6ccf3SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
3729bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
37371928e68SAkira Hatanaka   return MCDisassembler::Success;
37471928e68SAkira Hatanaka }
37571928e68SAkira Hatanaka 
376*9bfa2e2eSAkira Hatanaka static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
377*9bfa2e2eSAkira Hatanaka                                            unsigned RegNo,
378*9bfa2e2eSAkira Hatanaka                                            uint64_t Address,
379*9bfa2e2eSAkira Hatanaka                                            const void *Decoder) {
380*9bfa2e2eSAkira Hatanaka   if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
381*9bfa2e2eSAkira Hatanaka     return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
382*9bfa2e2eSAkira Hatanaka 
383*9bfa2e2eSAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
384*9bfa2e2eSAkira Hatanaka }
385*9bfa2e2eSAkira Hatanaka 
386654655f1SAkira Hatanaka static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
387ecabd1a5SAkira Hatanaka                                             unsigned RegNo,
388ecabd1a5SAkira Hatanaka                                             uint64_t Address,
389ecabd1a5SAkira Hatanaka                                             const void *Decoder) {
39013e6ccf3SAkira Hatanaka   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
391ecabd1a5SAkira Hatanaka }
392ecabd1a5SAkira Hatanaka 
39371928e68SAkira Hatanaka static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
39471928e68SAkira Hatanaka                                              unsigned RegNo,
39571928e68SAkira Hatanaka                                              uint64_t Address,
39671928e68SAkira Hatanaka                                              const void *Decoder) {
39771928e68SAkira Hatanaka   if (RegNo > 31)
39871928e68SAkira Hatanaka     return MCDisassembler::Fail;
39971928e68SAkira Hatanaka 
4009bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
4019bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
40271928e68SAkira Hatanaka   return MCDisassembler::Success;
40371928e68SAkira Hatanaka }
40471928e68SAkira Hatanaka 
40571928e68SAkira Hatanaka static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
40671928e68SAkira Hatanaka                                              unsigned RegNo,
40771928e68SAkira Hatanaka                                              uint64_t Address,
40871928e68SAkira Hatanaka                                              const void *Decoder) {
40971928e68SAkira Hatanaka   if (RegNo > 31)
41071928e68SAkira Hatanaka     return MCDisassembler::Fail;
41171928e68SAkira Hatanaka 
4129bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
4139bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
41471928e68SAkira Hatanaka   return MCDisassembler::Success;
41571928e68SAkira Hatanaka }
41671928e68SAkira Hatanaka 
41714e31a2fSAkira Hatanaka static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
41814e31a2fSAkira Hatanaka                                               unsigned RegNo,
41914e31a2fSAkira Hatanaka                                               uint64_t Address,
42014e31a2fSAkira Hatanaka                                               const void *Decoder) {
42114e31a2fSAkira Hatanaka   if (RegNo > 31)
42214e31a2fSAkira Hatanaka     return MCDisassembler::Fail;
42314e31a2fSAkira Hatanaka 
42414e31a2fSAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
42514e31a2fSAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
42614e31a2fSAkira Hatanaka   return MCDisassembler::Success;
42714e31a2fSAkira Hatanaka }
42814e31a2fSAkira Hatanaka 
42971928e68SAkira Hatanaka static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
43071928e68SAkira Hatanaka                                            unsigned RegNo,
43171928e68SAkira Hatanaka                                            uint64_t Address,
43271928e68SAkira Hatanaka                                            const void *Decoder) {
433253777fdSChad Rosier   if (RegNo > 31)
434253777fdSChad Rosier     return MCDisassembler::Fail;
435253777fdSChad Rosier   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
436253777fdSChad Rosier   Inst.addOperand(MCOperand::CreateReg(Reg));
43771928e68SAkira Hatanaka   return MCDisassembler::Success;
43871928e68SAkira Hatanaka }
43971928e68SAkira Hatanaka 
4401fb1b8b8SAkira Hatanaka static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
4411fb1b8b8SAkira Hatanaka                                            unsigned RegNo,
4421fb1b8b8SAkira Hatanaka                                            uint64_t Address,
4431fb1b8b8SAkira Hatanaka                                            const void *Decoder) {
4441fb1b8b8SAkira Hatanaka   if (RegNo > 7)
4451fb1b8b8SAkira Hatanaka     return MCDisassembler::Fail;
4461fb1b8b8SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
4471fb1b8b8SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
4481fb1b8b8SAkira Hatanaka   return MCDisassembler::Success;
4491fb1b8b8SAkira Hatanaka }
4501fb1b8b8SAkira Hatanaka 
45171928e68SAkira Hatanaka static DecodeStatus DecodeMem(MCInst &Inst,
45271928e68SAkira Hatanaka                               unsigned Insn,
45371928e68SAkira Hatanaka                               uint64_t Address,
45471928e68SAkira Hatanaka                               const void *Decoder) {
45571928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
456ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
457ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
4589bf2b567SAkira Hatanaka 
45913e6ccf3SAkira Hatanaka   Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
46013e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
46171928e68SAkira Hatanaka 
46271928e68SAkira Hatanaka   if(Inst.getOpcode() == Mips::SC){
4639bf2b567SAkira Hatanaka     Inst.addOperand(MCOperand::CreateReg(Reg));
46471928e68SAkira Hatanaka   }
46571928e68SAkira Hatanaka 
4669bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
4679bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
46871928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
46971928e68SAkira Hatanaka 
47071928e68SAkira Hatanaka   return MCDisassembler::Success;
47171928e68SAkira Hatanaka }
47271928e68SAkira Hatanaka 
47371928e68SAkira Hatanaka static DecodeStatus DecodeFMem(MCInst &Inst,
47471928e68SAkira Hatanaka                                unsigned Insn,
47571928e68SAkira Hatanaka                                uint64_t Address,
47671928e68SAkira Hatanaka                                const void *Decoder) {
47771928e68SAkira Hatanaka   int Offset = SignExtend32<16>(Insn & 0xffff);
478ecaef49fSJim Grosbach   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
479ecaef49fSJim Grosbach   unsigned Base = fieldFromInstruction(Insn, 21, 5);
48071928e68SAkira Hatanaka 
4819bf2b567SAkira Hatanaka   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
48213e6ccf3SAkira Hatanaka   Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
4839bf2b567SAkira Hatanaka 
4849bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
4859bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Base));
48671928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(Offset));
48771928e68SAkira Hatanaka 
48871928e68SAkira Hatanaka   return MCDisassembler::Success;
48971928e68SAkira Hatanaka }
49071928e68SAkira Hatanaka 
49171928e68SAkira Hatanaka 
49271928e68SAkira Hatanaka static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
49371928e68SAkira Hatanaka                                               unsigned RegNo,
49471928e68SAkira Hatanaka                                               uint64_t Address,
49571928e68SAkira Hatanaka                                               const void *Decoder) {
49671928e68SAkira Hatanaka   // Currently only hardware register 29 is supported.
49771928e68SAkira Hatanaka   if (RegNo != 29)
49871928e68SAkira Hatanaka     return  MCDisassembler::Fail;
49971928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
50071928e68SAkira Hatanaka   return MCDisassembler::Success;
50171928e68SAkira Hatanaka }
50271928e68SAkira Hatanaka 
50371928e68SAkira Hatanaka static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
50471928e68SAkira Hatanaka                                               unsigned RegNo,
50571928e68SAkira Hatanaka                                               uint64_t Address,
50671928e68SAkira Hatanaka                                               const void *Decoder) {
5079bf2b567SAkira Hatanaka   if (RegNo > 30 || RegNo %2)
50871928e68SAkira Hatanaka     return MCDisassembler::Fail;
50971928e68SAkira Hatanaka 
5109bf2b567SAkira Hatanaka   ;
5119bf2b567SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
5129bf2b567SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
51371928e68SAkira Hatanaka   return MCDisassembler::Success;
51471928e68SAkira Hatanaka }
51571928e68SAkira Hatanaka 
51600fcf2e1SAkira Hatanaka static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
517ecabd1a5SAkira Hatanaka                                                 unsigned RegNo,
518ecabd1a5SAkira Hatanaka                                                 uint64_t Address,
519ecabd1a5SAkira Hatanaka                                                 const void *Decoder) {
520ecabd1a5SAkira Hatanaka   if (RegNo >= 4)
521ecabd1a5SAkira Hatanaka     return MCDisassembler::Fail;
522ecabd1a5SAkira Hatanaka 
52300fcf2e1SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
524ecabd1a5SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
525ecabd1a5SAkira Hatanaka   return MCDisassembler::Success;
526ecabd1a5SAkira Hatanaka }
527ecabd1a5SAkira Hatanaka 
5288002a3f6SAkira Hatanaka static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
52959bfaf77SAkira Hatanaka                                                unsigned RegNo,
53059bfaf77SAkira Hatanaka                                                uint64_t Address,
53159bfaf77SAkira Hatanaka                                                const void *Decoder) {
53259bfaf77SAkira Hatanaka   if (RegNo >= 4)
53359bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
53459bfaf77SAkira Hatanaka 
5358002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
53659bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
53759bfaf77SAkira Hatanaka   return MCDisassembler::Success;
53859bfaf77SAkira Hatanaka }
53959bfaf77SAkira Hatanaka 
5408002a3f6SAkira Hatanaka static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
54159bfaf77SAkira Hatanaka                                                unsigned RegNo,
54259bfaf77SAkira Hatanaka                                                uint64_t Address,
54359bfaf77SAkira Hatanaka                                                const void *Decoder) {
54459bfaf77SAkira Hatanaka   if (RegNo >= 4)
54559bfaf77SAkira Hatanaka     return MCDisassembler::Fail;
54659bfaf77SAkira Hatanaka 
5478002a3f6SAkira Hatanaka   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
54859bfaf77SAkira Hatanaka   Inst.addOperand(MCOperand::CreateReg(Reg));
54959bfaf77SAkira Hatanaka   return MCDisassembler::Success;
55059bfaf77SAkira Hatanaka }
55159bfaf77SAkira Hatanaka 
55271928e68SAkira Hatanaka static DecodeStatus DecodeBranchTarget(MCInst &Inst,
55371928e68SAkira Hatanaka                                        unsigned Offset,
55471928e68SAkira Hatanaka                                        uint64_t Address,
55571928e68SAkira Hatanaka                                        const void *Decoder) {
55671928e68SAkira Hatanaka   unsigned BranchOffset = Offset & 0xffff;
55771928e68SAkira Hatanaka   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
55871928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
55971928e68SAkira Hatanaka   return MCDisassembler::Success;
56071928e68SAkira Hatanaka }
56171928e68SAkira Hatanaka 
56271928e68SAkira Hatanaka static DecodeStatus DecodeJumpTarget(MCInst &Inst,
56371928e68SAkira Hatanaka                                      unsigned Insn,
56471928e68SAkira Hatanaka                                      uint64_t Address,
56571928e68SAkira Hatanaka                                      const void *Decoder) {
56671928e68SAkira Hatanaka 
567ecaef49fSJim Grosbach   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
56871928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
56971928e68SAkira Hatanaka   return MCDisassembler::Success;
57071928e68SAkira Hatanaka }
57171928e68SAkira Hatanaka 
57271928e68SAkira Hatanaka 
57371928e68SAkira Hatanaka static DecodeStatus DecodeSimm16(MCInst &Inst,
57471928e68SAkira Hatanaka                                  unsigned Insn,
57571928e68SAkira Hatanaka                                  uint64_t Address,
57671928e68SAkira Hatanaka                                  const void *Decoder) {
57771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
57871928e68SAkira Hatanaka   return MCDisassembler::Success;
57971928e68SAkira Hatanaka }
58071928e68SAkira Hatanaka 
58171928e68SAkira Hatanaka static DecodeStatus DecodeInsSize(MCInst &Inst,
58271928e68SAkira Hatanaka                                   unsigned Insn,
58371928e68SAkira Hatanaka                                   uint64_t Address,
58471928e68SAkira Hatanaka                                   const void *Decoder) {
58571928e68SAkira Hatanaka   // First we need to grab the pos(lsb) from MCInst.
58671928e68SAkira Hatanaka   int Pos = Inst.getOperand(2).getImm();
58771928e68SAkira Hatanaka   int Size = (int) Insn - Pos + 1;
58871928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
58971928e68SAkira Hatanaka   return MCDisassembler::Success;
59071928e68SAkira Hatanaka }
59171928e68SAkira Hatanaka 
59271928e68SAkira Hatanaka static DecodeStatus DecodeExtSize(MCInst &Inst,
59371928e68SAkira Hatanaka                                   unsigned Insn,
59471928e68SAkira Hatanaka                                   uint64_t Address,
59571928e68SAkira Hatanaka                                   const void *Decoder) {
59671928e68SAkira Hatanaka   int Size = (int) Insn  + 1;
59771928e68SAkira Hatanaka   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
59871928e68SAkira Hatanaka   return MCDisassembler::Success;
59971928e68SAkira Hatanaka }
600