MipsDisassembler.cpp revision 95adf91f29980e374bf094e15bc3f2764ef9baf4
11d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich//===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
21d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich//
31d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich//                     The LLVM Compiler Infrastructure
41d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich//
51d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// This file is distributed under the University of Illinois Open Source
61d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// License. See LICENSE.TXT for details.
71d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich//
81d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich//===----------------------------------------------------------------------===//
91d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich//
101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// This file is part of the Mips Disassembler.
111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich//
121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich//===----------------------------------------------------------------------===//
131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "Mips.h"
151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "MipsRegisterInfo.h"
161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "MipsSubtarget.h"
171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "llvm/MC/MCDisassembler.h"
181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "llvm/MC/MCFixedLenDisassembler.h"
191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "llvm/MC/MCInst.h"
201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "llvm/MC/MCSubtargetInfo.h"
211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "llvm/Support/MathExtras.h"
221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "llvm/Support/MemoryObject.h"
231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich#include "llvm/Support/TargetRegistry.h"
241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichusing namespace llvm;
261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichtypedef MCDisassembler::DecodeStatus DecodeStatus;
281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichnamespace {
301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/// MipsDisassemblerBase - a disasembler class for Mips.
321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichclass MipsDisassemblerBase : public MCDisassembler {
331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichpublic:
341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  /// Constructor     - Initializes the disassembler.
351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  ///
361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                       bool bigEndian) :
381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich    MCDisassembler(STI), RegInfo(Info),
391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich    IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {}
401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  virtual ~MipsDisassemblerBase() {}
421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  bool isN64() const { return IsN64; }
461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichprivate:
481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  OwningPtr<const MCRegisterInfo> RegInfo;
491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  bool IsN64;
501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichprotected:
511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  bool isBigEndian;
521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich};
531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/// MipsDisassembler - a disasembler class for Mips32.
551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichclass MipsDisassembler : public MipsDisassemblerBase {
561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  bool IsMicroMips;
571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichpublic:
581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  /// Constructor     - Initializes the disassembler.
591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  ///
601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                   bool bigEndian) :
621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich    MipsDisassemblerBase(STI, Info, bigEndian) {
631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich      IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich    }
651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
661d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  /// getInstruction - See MCDisassembler.
671d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  virtual DecodeStatus getInstruction(MCInst &instr,
681d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                      uint64_t &size,
691d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                      const MemoryObject &region,
701d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                      uint64_t address,
711d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                      raw_ostream &vStream,
721d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                      raw_ostream &cStream) const;
731d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich};
741d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
751d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
761d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich/// Mips64Disassembler - a disasembler class for Mips64.
771d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichclass Mips64Disassembler : public MipsDisassemblerBase {
781d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichpublic:
791d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  /// Constructor     - Initializes the disassembler.
801d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  ///
811d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
821d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                     bool bigEndian) :
831d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich    MipsDisassemblerBase(STI, Info, bigEndian) {}
841d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
851d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  /// getInstruction - See MCDisassembler.
861d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich  virtual DecodeStatus getInstruction(MCInst &instr,
871d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                      uint64_t &size,
881d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                      const MemoryObject &region,
891d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                      uint64_t address,
901d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                      raw_ostream &vStream,
911d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                      raw_ostream &cStream) const;
921d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich};
931d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
941d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich} // end anonymous namespace
951d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
961d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// Forward declare these because the autogenerated code will reference them.
971d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich// Definitions are further down.
981d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
991d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                             unsigned RegNo,
1001d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                             uint64_t Address,
1011d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                             const void *Decoder);
1021d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1031d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
1041d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                                 unsigned RegNo,
1051d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                                 uint64_t Address,
1061d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                                 const void *Decoder);
1071d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1081d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
1091d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                             unsigned RegNo,
1101d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                             uint64_t Address,
1111d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                             const void *Decoder);
1121d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1131d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
1141d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                           unsigned Insn,
1151d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                           uint64_t Address,
1161d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                           const void *Decoder);
1171d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1181d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
1191d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                            unsigned RegNo,
1201d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                            uint64_t Address,
1211d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                            const void *Decoder);
1221d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1231d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
1241d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                             unsigned RegNo,
1251d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                             uint64_t Address,
1261d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                             const void *Decoder);
1271d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1281d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
1291d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                             unsigned RegNo,
1301d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                             uint64_t Address,
1311d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                             const void *Decoder);
1321d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1331d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
1341d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                              unsigned RegNo,
1351d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                              uint64_t Address,
1361d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                              const void *Decoder);
1371d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1381d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
1391d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                           unsigned RegNo,
1401d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                           uint64_t Address,
1411d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                           const void *Decoder);
1421d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1431d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
1441d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                           unsigned RegNo,
1451d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                           uint64_t Address,
1461d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                           const void *Decoder);
1471d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1481d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
1491d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                              unsigned Insn,
1501d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                              uint64_t Address,
1511d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                              const void *Decoder);
1521d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1531d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
1541d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                              unsigned RegNo,
1551d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                              uint64_t Address,
1561d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                              const void *Decoder);
1571d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1581d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
1591d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                                unsigned RegNo,
1601d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                                uint64_t Address,
1611d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                                const void *Decoder);
1621d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich
1631d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevichstatic DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
1641d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                               unsigned RegNo,
1651d1011a3c5049a7f9eef99d22f3704e4367579ccNick Kralevich                                               uint64_t Address,
166                                               const void *Decoder);
167
168static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
169                                               unsigned RegNo,
170                                               uint64_t Address,
171                                               const void *Decoder);
172
173static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
174                                               unsigned RegNo,
175                                               uint64_t Address,
176                                               const void *Decoder);
177
178static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
179                                               unsigned RegNo,
180                                               uint64_t Address,
181                                               const void *Decoder);
182
183static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
184                                               unsigned RegNo,
185                                               uint64_t Address,
186                                               const void *Decoder);
187
188static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
189                                               unsigned RegNo,
190                                               uint64_t Address,
191                                               const void *Decoder);
192
193static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
194                                               unsigned RegNo,
195                                               uint64_t Address,
196                                               const void *Decoder);
197
198static DecodeStatus DecodeBranchTarget(MCInst &Inst,
199                                       unsigned Offset,
200                                       uint64_t Address,
201                                       const void *Decoder);
202
203static DecodeStatus DecodeJumpTarget(MCInst &Inst,
204                                     unsigned Insn,
205                                     uint64_t Address,
206                                     const void *Decoder);
207
208// DecodeBranchTargetMM - Decode microMIPS branch offset, which is
209// shifted left by 1 bit.
210static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
211                                         unsigned Offset,
212                                         uint64_t Address,
213                                         const void *Decoder);
214
215// DecodeJumpTargetMM - Decode microMIPS jump target, which is
216// shifted left by 1 bit.
217static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
218                                       unsigned Insn,
219                                       uint64_t Address,
220                                       const void *Decoder);
221
222static DecodeStatus DecodeMem(MCInst &Inst,
223                              unsigned Insn,
224                              uint64_t Address,
225                              const void *Decoder);
226
227static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
228                                    uint64_t Address, const void *Decoder);
229
230static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
231                                     unsigned Insn,
232                                     uint64_t Address,
233                                     const void *Decoder);
234
235static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
236                                     unsigned Insn,
237                                     uint64_t Address,
238                                     const void *Decoder);
239
240static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
241                               uint64_t Address,
242                               const void *Decoder);
243
244static DecodeStatus DecodeSimm16(MCInst &Inst,
245                                 unsigned Insn,
246                                 uint64_t Address,
247                                 const void *Decoder);
248
249// Decode the immediate field of an LSA instruction which
250// is off by one.
251static DecodeStatus DecodeLSAImm(MCInst &Inst,
252                                 unsigned Insn,
253                                 uint64_t Address,
254                                 const void *Decoder);
255
256static DecodeStatus DecodeInsSize(MCInst &Inst,
257                                  unsigned Insn,
258                                  uint64_t Address,
259                                  const void *Decoder);
260
261static DecodeStatus DecodeExtSize(MCInst &Inst,
262                                  unsigned Insn,
263                                  uint64_t Address,
264                                  const void *Decoder);
265
266namespace llvm {
267extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
268              TheMips64elTarget;
269}
270
271static MCDisassembler *createMipsDisassembler(
272                       const Target &T,
273                       const MCSubtargetInfo &STI) {
274  return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
275}
276
277static MCDisassembler *createMipselDisassembler(
278                       const Target &T,
279                       const MCSubtargetInfo &STI) {
280  return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
281}
282
283static MCDisassembler *createMips64Disassembler(
284                       const Target &T,
285                       const MCSubtargetInfo &STI) {
286  return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
287}
288
289static MCDisassembler *createMips64elDisassembler(
290                       const Target &T,
291                       const MCSubtargetInfo &STI) {
292  return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
293}
294
295extern "C" void LLVMInitializeMipsDisassembler() {
296  // Register the disassembler.
297  TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
298                                         createMipsDisassembler);
299  TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
300                                         createMipselDisassembler);
301  TargetRegistry::RegisterMCDisassembler(TheMips64Target,
302                                         createMips64Disassembler);
303  TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
304                                         createMips64elDisassembler);
305}
306
307
308#include "MipsGenDisassemblerTables.inc"
309
310  /// readInstruction - read four bytes from the MemoryObject
311  /// and return 32 bit word sorted according to the given endianess
312static DecodeStatus readInstruction32(const MemoryObject &region,
313                                      uint64_t address,
314                                      uint64_t &size,
315                                      uint32_t &insn,
316                                      bool isBigEndian,
317                                      bool IsMicroMips) {
318  uint8_t Bytes[4];
319
320  // We want to read exactly 4 Bytes of data.
321  if (region.readBytes(address, 4, Bytes) == -1) {
322    size = 0;
323    return MCDisassembler::Fail;
324  }
325
326  if (isBigEndian) {
327    // Encoded as a big-endian 32-bit word in the stream.
328    insn = (Bytes[3] <<  0) |
329           (Bytes[2] <<  8) |
330           (Bytes[1] << 16) |
331           (Bytes[0] << 24);
332  }
333  else {
334    // Encoded as a small-endian 32-bit word in the stream.
335    // Little-endian byte ordering:
336    //   mips32r2:   4 | 3 | 2 | 1
337    //   microMIPS:  2 | 1 | 4 | 3
338    if (IsMicroMips) {
339      insn = (Bytes[2] <<  0) |
340             (Bytes[3] <<  8) |
341             (Bytes[0] << 16) |
342             (Bytes[1] << 24);
343    } else {
344      insn = (Bytes[0] <<  0) |
345             (Bytes[1] <<  8) |
346             (Bytes[2] << 16) |
347             (Bytes[3] << 24);
348    }
349  }
350
351  return MCDisassembler::Success;
352}
353
354DecodeStatus
355MipsDisassembler::getInstruction(MCInst &instr,
356                                 uint64_t &Size,
357                                 const MemoryObject &Region,
358                                 uint64_t Address,
359                                 raw_ostream &vStream,
360                                 raw_ostream &cStream) const {
361  uint32_t Insn;
362
363  DecodeStatus Result = readInstruction32(Region, Address, Size,
364                                          Insn, isBigEndian, IsMicroMips);
365  if (Result == MCDisassembler::Fail)
366    return MCDisassembler::Fail;
367
368  if (IsMicroMips) {
369    // Calling the auto-generated decoder function.
370    Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address,
371                               this, STI);
372    if (Result != MCDisassembler::Fail) {
373      Size = 4;
374      return Result;
375    }
376    return MCDisassembler::Fail;
377  }
378
379  // Calling the auto-generated decoder function.
380  Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
381                             this, STI);
382  if (Result != MCDisassembler::Fail) {
383    Size = 4;
384    return Result;
385  }
386
387  return MCDisassembler::Fail;
388}
389
390DecodeStatus
391Mips64Disassembler::getInstruction(MCInst &instr,
392                                   uint64_t &Size,
393                                   const MemoryObject &Region,
394                                   uint64_t Address,
395                                   raw_ostream &vStream,
396                                   raw_ostream &cStream) const {
397  uint32_t Insn;
398
399  DecodeStatus Result = readInstruction32(Region, Address, Size,
400                                          Insn, isBigEndian, false);
401  if (Result == MCDisassembler::Fail)
402    return MCDisassembler::Fail;
403
404  // Calling the auto-generated decoder function.
405  Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
406                             this, STI);
407  if (Result != MCDisassembler::Fail) {
408    Size = 4;
409    return Result;
410  }
411  // If we fail to decode in Mips64 decoder space we can try in Mips32
412  Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
413                             this, STI);
414  if (Result != MCDisassembler::Fail) {
415    Size = 4;
416    return Result;
417  }
418
419  return MCDisassembler::Fail;
420}
421
422static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
423  const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
424  return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
425}
426
427static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
428                                                 unsigned RegNo,
429                                                 uint64_t Address,
430                                                 const void *Decoder) {
431
432  return MCDisassembler::Fail;
433
434}
435
436static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
437                                             unsigned RegNo,
438                                             uint64_t Address,
439                                             const void *Decoder) {
440
441  if (RegNo > 31)
442    return MCDisassembler::Fail;
443
444  unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
445  Inst.addOperand(MCOperand::CreateReg(Reg));
446  return MCDisassembler::Success;
447}
448
449static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
450                                             unsigned RegNo,
451                                             uint64_t Address,
452                                             const void *Decoder) {
453  if (RegNo > 31)
454    return MCDisassembler::Fail;
455  unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
456  Inst.addOperand(MCOperand::CreateReg(Reg));
457  return MCDisassembler::Success;
458}
459
460static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
461                                           unsigned RegNo,
462                                           uint64_t Address,
463                                           const void *Decoder) {
464  if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
465    return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
466
467  return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
468}
469
470static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
471                                            unsigned RegNo,
472                                            uint64_t Address,
473                                            const void *Decoder) {
474  return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
475}
476
477static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
478                                             unsigned RegNo,
479                                             uint64_t Address,
480                                             const void *Decoder) {
481  if (RegNo > 31)
482    return MCDisassembler::Fail;
483
484  unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
485  Inst.addOperand(MCOperand::CreateReg(Reg));
486  return MCDisassembler::Success;
487}
488
489static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
490                                             unsigned RegNo,
491                                             uint64_t Address,
492                                             const void *Decoder) {
493  if (RegNo > 31)
494    return MCDisassembler::Fail;
495
496  unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
497  Inst.addOperand(MCOperand::CreateReg(Reg));
498  return MCDisassembler::Success;
499}
500
501static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
502                                              unsigned RegNo,
503                                              uint64_t Address,
504                                              const void *Decoder) {
505  if (RegNo > 31)
506    return MCDisassembler::Fail;
507
508  unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
509  Inst.addOperand(MCOperand::CreateReg(Reg));
510  return MCDisassembler::Success;
511}
512
513static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
514                                           unsigned RegNo,
515                                           uint64_t Address,
516                                           const void *Decoder) {
517  if (RegNo > 31)
518    return MCDisassembler::Fail;
519  unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
520  Inst.addOperand(MCOperand::CreateReg(Reg));
521  return MCDisassembler::Success;
522}
523
524static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
525                                           unsigned RegNo,
526                                           uint64_t Address,
527                                           const void *Decoder) {
528  if (RegNo > 7)
529    return MCDisassembler::Fail;
530  unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
531  Inst.addOperand(MCOperand::CreateReg(Reg));
532  return MCDisassembler::Success;
533}
534
535static DecodeStatus DecodeMem(MCInst &Inst,
536                              unsigned Insn,
537                              uint64_t Address,
538                              const void *Decoder) {
539  int Offset = SignExtend32<16>(Insn & 0xffff);
540  unsigned Reg = fieldFromInstruction(Insn, 16, 5);
541  unsigned Base = fieldFromInstruction(Insn, 21, 5);
542
543  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
544  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
545
546  if(Inst.getOpcode() == Mips::SC){
547    Inst.addOperand(MCOperand::CreateReg(Reg));
548  }
549
550  Inst.addOperand(MCOperand::CreateReg(Reg));
551  Inst.addOperand(MCOperand::CreateReg(Base));
552  Inst.addOperand(MCOperand::CreateImm(Offset));
553
554  return MCDisassembler::Success;
555}
556
557static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
558                                    uint64_t Address, const void *Decoder) {
559  int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
560  unsigned Reg = fieldFromInstruction(Insn, 6, 5);
561  unsigned Base = fieldFromInstruction(Insn, 11, 5);
562
563  Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
564  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
565
566  Inst.addOperand(MCOperand::CreateReg(Reg));
567  Inst.addOperand(MCOperand::CreateReg(Base));
568  Inst.addOperand(MCOperand::CreateImm(Offset));
569
570  return MCDisassembler::Success;
571}
572
573static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
574                                     unsigned Insn,
575                                     uint64_t Address,
576                                     const void *Decoder) {
577  int Offset = SignExtend32<12>(Insn & 0x0fff);
578  unsigned Reg = fieldFromInstruction(Insn, 21, 5);
579  unsigned Base = fieldFromInstruction(Insn, 16, 5);
580
581  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
582  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
583
584  Inst.addOperand(MCOperand::CreateReg(Reg));
585  Inst.addOperand(MCOperand::CreateReg(Base));
586  Inst.addOperand(MCOperand::CreateImm(Offset));
587
588  return MCDisassembler::Success;
589}
590
591static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
592                                     unsigned Insn,
593                                     uint64_t Address,
594                                     const void *Decoder) {
595  int Offset = SignExtend32<16>(Insn & 0xffff);
596  unsigned Reg = fieldFromInstruction(Insn, 21, 5);
597  unsigned Base = fieldFromInstruction(Insn, 16, 5);
598
599  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
600  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
601
602  Inst.addOperand(MCOperand::CreateReg(Reg));
603  Inst.addOperand(MCOperand::CreateReg(Base));
604  Inst.addOperand(MCOperand::CreateImm(Offset));
605
606  return MCDisassembler::Success;
607}
608
609static DecodeStatus DecodeFMem(MCInst &Inst,
610                               unsigned Insn,
611                               uint64_t Address,
612                               const void *Decoder) {
613  int Offset = SignExtend32<16>(Insn & 0xffff);
614  unsigned Reg = fieldFromInstruction(Insn, 16, 5);
615  unsigned Base = fieldFromInstruction(Insn, 21, 5);
616
617  Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
618  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
619
620  Inst.addOperand(MCOperand::CreateReg(Reg));
621  Inst.addOperand(MCOperand::CreateReg(Base));
622  Inst.addOperand(MCOperand::CreateImm(Offset));
623
624  return MCDisassembler::Success;
625}
626
627
628static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
629                                              unsigned RegNo,
630                                              uint64_t Address,
631                                              const void *Decoder) {
632  // Currently only hardware register 29 is supported.
633  if (RegNo != 29)
634    return  MCDisassembler::Fail;
635  Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
636  return MCDisassembler::Success;
637}
638
639static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
640                                              unsigned RegNo,
641                                              uint64_t Address,
642                                              const void *Decoder) {
643  if (RegNo > 30 || RegNo %2)
644    return MCDisassembler::Fail;
645
646  ;
647  unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
648  Inst.addOperand(MCOperand::CreateReg(Reg));
649  return MCDisassembler::Success;
650}
651
652static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
653                                                unsigned RegNo,
654                                                uint64_t Address,
655                                                const void *Decoder) {
656  if (RegNo >= 4)
657    return MCDisassembler::Fail;
658
659  unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
660  Inst.addOperand(MCOperand::CreateReg(Reg));
661  return MCDisassembler::Success;
662}
663
664static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
665                                               unsigned RegNo,
666                                               uint64_t Address,
667                                               const void *Decoder) {
668  if (RegNo >= 4)
669    return MCDisassembler::Fail;
670
671  unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
672  Inst.addOperand(MCOperand::CreateReg(Reg));
673  return MCDisassembler::Success;
674}
675
676static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
677                                               unsigned RegNo,
678                                               uint64_t Address,
679                                               const void *Decoder) {
680  if (RegNo >= 4)
681    return MCDisassembler::Fail;
682
683  unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
684  Inst.addOperand(MCOperand::CreateReg(Reg));
685  return MCDisassembler::Success;
686}
687
688static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
689                                               unsigned RegNo,
690                                               uint64_t Address,
691                                               const void *Decoder) {
692  if (RegNo > 31)
693    return MCDisassembler::Fail;
694
695  unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
696  Inst.addOperand(MCOperand::CreateReg(Reg));
697  return MCDisassembler::Success;
698}
699
700static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
701                                               unsigned RegNo,
702                                               uint64_t Address,
703                                               const void *Decoder) {
704  if (RegNo > 31)
705    return MCDisassembler::Fail;
706
707  unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
708  Inst.addOperand(MCOperand::CreateReg(Reg));
709  return MCDisassembler::Success;
710}
711
712static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
713                                               unsigned RegNo,
714                                               uint64_t Address,
715                                               const void *Decoder) {
716  if (RegNo > 31)
717    return MCDisassembler::Fail;
718
719  unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
720  Inst.addOperand(MCOperand::CreateReg(Reg));
721  return MCDisassembler::Success;
722}
723
724static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
725                                               unsigned RegNo,
726                                               uint64_t Address,
727                                               const void *Decoder) {
728  if (RegNo > 31)
729    return MCDisassembler::Fail;
730
731  unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
732  Inst.addOperand(MCOperand::CreateReg(Reg));
733  return MCDisassembler::Success;
734}
735
736static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
737                                               unsigned RegNo,
738                                               uint64_t Address,
739                                               const void *Decoder) {
740  if (RegNo > 7)
741    return MCDisassembler::Fail;
742
743  unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
744  Inst.addOperand(MCOperand::CreateReg(Reg));
745  return MCDisassembler::Success;
746}
747
748static DecodeStatus DecodeBranchTarget(MCInst &Inst,
749                                       unsigned Offset,
750                                       uint64_t Address,
751                                       const void *Decoder) {
752  unsigned BranchOffset = Offset & 0xffff;
753  BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
754  Inst.addOperand(MCOperand::CreateImm(BranchOffset));
755  return MCDisassembler::Success;
756}
757
758static DecodeStatus DecodeJumpTarget(MCInst &Inst,
759                                     unsigned Insn,
760                                     uint64_t Address,
761                                     const void *Decoder) {
762
763  unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
764  Inst.addOperand(MCOperand::CreateImm(JumpOffset));
765  return MCDisassembler::Success;
766}
767
768static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
769                                         unsigned Offset,
770                                         uint64_t Address,
771                                         const void *Decoder) {
772  unsigned BranchOffset = Offset & 0xffff;
773  BranchOffset = SignExtend32<18>(BranchOffset << 1);
774  Inst.addOperand(MCOperand::CreateImm(BranchOffset));
775  return MCDisassembler::Success;
776}
777
778static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
779                                       unsigned Insn,
780                                       uint64_t Address,
781                                       const void *Decoder) {
782  unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
783  Inst.addOperand(MCOperand::CreateImm(JumpOffset));
784  return MCDisassembler::Success;
785}
786
787static DecodeStatus DecodeSimm16(MCInst &Inst,
788                                 unsigned Insn,
789                                 uint64_t Address,
790                                 const void *Decoder) {
791  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
792  return MCDisassembler::Success;
793}
794
795static DecodeStatus DecodeLSAImm(MCInst &Inst,
796                                 unsigned Insn,
797                                 uint64_t Address,
798                                 const void *Decoder) {
799  // We add one to the immediate field as it was encoded as 'imm - 1'.
800  Inst.addOperand(MCOperand::CreateImm(Insn + 1));
801  return MCDisassembler::Success;
802}
803
804static DecodeStatus DecodeInsSize(MCInst &Inst,
805                                  unsigned Insn,
806                                  uint64_t Address,
807                                  const void *Decoder) {
808  // First we need to grab the pos(lsb) from MCInst.
809  int Pos = Inst.getOperand(2).getImm();
810  int Size = (int) Insn - Pos + 1;
811  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
812  return MCDisassembler::Success;
813}
814
815static DecodeStatus DecodeExtSize(MCInst &Inst,
816                                  unsigned Insn,
817                                  uint64_t Address,
818                                  const void *Decoder) {
819  int Size = (int) Insn  + 1;
820  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
821  return MCDisassembler::Success;
822}
823