MipsDisassembler.cpp revision 5c042162beb3c2dd556e00aab84c4278a69cd5b1
1//===- MipsDisassembler.cpp - Disassembler for Mips -------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is part of the Mips Disassembler.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Mips.h"
15#include "MipsRegisterInfo.h"
16#include "MipsSubtarget.h"
17#include "llvm/MC/MCDisassembler.h"
18#include "llvm/MC/MCFixedLenDisassembler.h"
19#include "llvm/MC/MCInst.h"
20#include "llvm/MC/MCSubtargetInfo.h"
21#include "llvm/Support/MathExtras.h"
22#include "llvm/Support/MemoryObject.h"
23#include "llvm/Support/TargetRegistry.h"
24
25using namespace llvm;
26
27typedef MCDisassembler::DecodeStatus DecodeStatus;
28
29namespace {
30
31/// MipsDisassemblerBase - a disasembler class for Mips.
32class MipsDisassemblerBase : public MCDisassembler {
33public:
34  /// Constructor     - Initializes the disassembler.
35  ///
36  MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
37                       bool bigEndian) :
38    MCDisassembler(STI), RegInfo(Info),
39    IsN64(STI.getFeatureBits() & Mips::FeatureN64), isBigEndian(bigEndian) {}
40
41  virtual ~MipsDisassemblerBase() {}
42
43  const MCRegisterInfo *getRegInfo() const { return RegInfo.get(); }
44
45  bool isN64() const { return IsN64; }
46
47private:
48  OwningPtr<const MCRegisterInfo> RegInfo;
49  bool IsN64;
50protected:
51  bool isBigEndian;
52};
53
54/// MipsDisassembler - a disasembler class for Mips32.
55class MipsDisassembler : public MipsDisassemblerBase {
56  bool IsMicroMips;
57public:
58  /// Constructor     - Initializes the disassembler.
59  ///
60  MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
61                   bool bigEndian) :
62    MipsDisassemblerBase(STI, Info, bigEndian) {
63      IsMicroMips = STI.getFeatureBits() & Mips::FeatureMicroMips;
64    }
65
66  /// getInstruction - See MCDisassembler.
67  virtual DecodeStatus getInstruction(MCInst &instr,
68                                      uint64_t &size,
69                                      const MemoryObject &region,
70                                      uint64_t address,
71                                      raw_ostream &vStream,
72                                      raw_ostream &cStream) const;
73};
74
75
76/// Mips64Disassembler - a disasembler class for Mips64.
77class Mips64Disassembler : public MipsDisassemblerBase {
78public:
79  /// Constructor     - Initializes the disassembler.
80  ///
81  Mips64Disassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
82                     bool bigEndian) :
83    MipsDisassemblerBase(STI, Info, bigEndian) {}
84
85  /// getInstruction - See MCDisassembler.
86  virtual DecodeStatus getInstruction(MCInst &instr,
87                                      uint64_t &size,
88                                      const MemoryObject &region,
89                                      uint64_t address,
90                                      raw_ostream &vStream,
91                                      raw_ostream &cStream) const;
92};
93
94} // end anonymous namespace
95
96// Forward declare these because the autogenerated code will reference them.
97// Definitions are further down.
98static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
99                                             unsigned RegNo,
100                                             uint64_t Address,
101                                             const void *Decoder);
102
103static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
104                                                 unsigned RegNo,
105                                                 uint64_t Address,
106                                                 const void *Decoder);
107
108static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
109                                             unsigned RegNo,
110                                             uint64_t Address,
111                                             const void *Decoder);
112
113static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
114                                           unsigned Insn,
115                                           uint64_t Address,
116                                           const void *Decoder);
117
118static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
119                                            unsigned RegNo,
120                                            uint64_t Address,
121                                            const void *Decoder);
122
123static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
124                                             unsigned RegNo,
125                                             uint64_t Address,
126                                             const void *Decoder);
127
128static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
129                                             unsigned RegNo,
130                                             uint64_t Address,
131                                             const void *Decoder);
132
133static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
134                                              unsigned RegNo,
135                                              uint64_t Address,
136                                              const void *Decoder);
137
138static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
139                                           unsigned RegNo,
140                                           uint64_t Address,
141                                           const void *Decoder);
142
143static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
144                                           unsigned RegNo,
145                                           uint64_t Address,
146                                           const void *Decoder);
147
148static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
149                                              unsigned Insn,
150                                              uint64_t Address,
151                                              const void *Decoder);
152
153static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
154                                              unsigned RegNo,
155                                              uint64_t Address,
156                                              const void *Decoder);
157
158static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
159                                                unsigned RegNo,
160                                                uint64_t Address,
161                                                const void *Decoder);
162
163static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
164                                               unsigned RegNo,
165                                               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
249static DecodeStatus DecodeInsSize(MCInst &Inst,
250                                  unsigned Insn,
251                                  uint64_t Address,
252                                  const void *Decoder);
253
254static DecodeStatus DecodeExtSize(MCInst &Inst,
255                                  unsigned Insn,
256                                  uint64_t Address,
257                                  const void *Decoder);
258
259namespace llvm {
260extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
261              TheMips64elTarget;
262}
263
264static MCDisassembler *createMipsDisassembler(
265                       const Target &T,
266                       const MCSubtargetInfo &STI) {
267  return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
268}
269
270static MCDisassembler *createMipselDisassembler(
271                       const Target &T,
272                       const MCSubtargetInfo &STI) {
273  return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
274}
275
276static MCDisassembler *createMips64Disassembler(
277                       const Target &T,
278                       const MCSubtargetInfo &STI) {
279  return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
280}
281
282static MCDisassembler *createMips64elDisassembler(
283                       const Target &T,
284                       const MCSubtargetInfo &STI) {
285  return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
286}
287
288extern "C" void LLVMInitializeMipsDisassembler() {
289  // Register the disassembler.
290  TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
291                                         createMipsDisassembler);
292  TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
293                                         createMipselDisassembler);
294  TargetRegistry::RegisterMCDisassembler(TheMips64Target,
295                                         createMips64Disassembler);
296  TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
297                                         createMips64elDisassembler);
298}
299
300
301#include "MipsGenDisassemblerTables.inc"
302
303  /// readInstruction - read four bytes from the MemoryObject
304  /// and return 32 bit word sorted according to the given endianess
305static DecodeStatus readInstruction32(const MemoryObject &region,
306                                      uint64_t address,
307                                      uint64_t &size,
308                                      uint32_t &insn,
309                                      bool isBigEndian,
310                                      bool IsMicroMips) {
311  uint8_t Bytes[4];
312
313  // We want to read exactly 4 Bytes of data.
314  if (region.readBytes(address, 4, Bytes) == -1) {
315    size = 0;
316    return MCDisassembler::Fail;
317  }
318
319  if (isBigEndian) {
320    // Encoded as a big-endian 32-bit word in the stream.
321    insn = (Bytes[3] <<  0) |
322           (Bytes[2] <<  8) |
323           (Bytes[1] << 16) |
324           (Bytes[0] << 24);
325  }
326  else {
327    // Encoded as a small-endian 32-bit word in the stream.
328    // Little-endian byte ordering:
329    //   mips32r2:   4 | 3 | 2 | 1
330    //   microMIPS:  2 | 1 | 4 | 3
331    if (IsMicroMips) {
332      insn = (Bytes[2] <<  0) |
333             (Bytes[3] <<  8) |
334             (Bytes[0] << 16) |
335             (Bytes[1] << 24);
336    } else {
337      insn = (Bytes[0] <<  0) |
338             (Bytes[1] <<  8) |
339             (Bytes[2] << 16) |
340             (Bytes[3] << 24);
341    }
342  }
343
344  return MCDisassembler::Success;
345}
346
347DecodeStatus
348MipsDisassembler::getInstruction(MCInst &instr,
349                                 uint64_t &Size,
350                                 const MemoryObject &Region,
351                                 uint64_t Address,
352                                 raw_ostream &vStream,
353                                 raw_ostream &cStream) const {
354  uint32_t Insn;
355
356  DecodeStatus Result = readInstruction32(Region, Address, Size,
357                                          Insn, isBigEndian, IsMicroMips);
358  if (Result == MCDisassembler::Fail)
359    return MCDisassembler::Fail;
360
361  if (IsMicroMips) {
362    // Calling the auto-generated decoder function.
363    Result = decodeInstruction(DecoderTableMicroMips32, instr, Insn, Address,
364                               this, STI);
365    if (Result != MCDisassembler::Fail) {
366      Size = 4;
367      return Result;
368    }
369    return MCDisassembler::Fail;
370  }
371
372  // Calling the auto-generated decoder function.
373  Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
374                             this, STI);
375  if (Result != MCDisassembler::Fail) {
376    Size = 4;
377    return Result;
378  }
379
380  return MCDisassembler::Fail;
381}
382
383DecodeStatus
384Mips64Disassembler::getInstruction(MCInst &instr,
385                                   uint64_t &Size,
386                                   const MemoryObject &Region,
387                                   uint64_t Address,
388                                   raw_ostream &vStream,
389                                   raw_ostream &cStream) const {
390  uint32_t Insn;
391
392  DecodeStatus Result = readInstruction32(Region, Address, Size,
393                                          Insn, isBigEndian, false);
394  if (Result == MCDisassembler::Fail)
395    return MCDisassembler::Fail;
396
397  // Calling the auto-generated decoder function.
398  Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
399                             this, STI);
400  if (Result != MCDisassembler::Fail) {
401    Size = 4;
402    return Result;
403  }
404  // If we fail to decode in Mips64 decoder space we can try in Mips32
405  Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
406                             this, STI);
407  if (Result != MCDisassembler::Fail) {
408    Size = 4;
409    return Result;
410  }
411
412  return MCDisassembler::Fail;
413}
414
415static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
416  const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
417  return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
418}
419
420static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
421                                                 unsigned RegNo,
422                                                 uint64_t Address,
423                                                 const void *Decoder) {
424
425  return MCDisassembler::Fail;
426
427}
428
429static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
430                                             unsigned RegNo,
431                                             uint64_t Address,
432                                             const void *Decoder) {
433
434  if (RegNo > 31)
435    return MCDisassembler::Fail;
436
437  unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
438  Inst.addOperand(MCOperand::CreateReg(Reg));
439  return MCDisassembler::Success;
440}
441
442static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
443                                             unsigned RegNo,
444                                             uint64_t Address,
445                                             const void *Decoder) {
446  if (RegNo > 31)
447    return MCDisassembler::Fail;
448  unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
449  Inst.addOperand(MCOperand::CreateReg(Reg));
450  return MCDisassembler::Success;
451}
452
453static DecodeStatus DecodePtrRegisterClass(MCInst &Inst,
454                                           unsigned RegNo,
455                                           uint64_t Address,
456                                           const void *Decoder) {
457  if (static_cast<const MipsDisassembler *>(Decoder)->isN64())
458    return DecodeGPR64RegisterClass(Inst, RegNo, Address, Decoder);
459
460  return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
461}
462
463static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
464                                            unsigned RegNo,
465                                            uint64_t Address,
466                                            const void *Decoder) {
467  return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
468}
469
470static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
471                                             unsigned RegNo,
472                                             uint64_t Address,
473                                             const void *Decoder) {
474  if (RegNo > 31)
475    return MCDisassembler::Fail;
476
477  unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
478  Inst.addOperand(MCOperand::CreateReg(Reg));
479  return MCDisassembler::Success;
480}
481
482static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
483                                             unsigned RegNo,
484                                             uint64_t Address,
485                                             const void *Decoder) {
486  if (RegNo > 31)
487    return MCDisassembler::Fail;
488
489  unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
490  Inst.addOperand(MCOperand::CreateReg(Reg));
491  return MCDisassembler::Success;
492}
493
494static DecodeStatus DecodeFGRH32RegisterClass(MCInst &Inst,
495                                              unsigned RegNo,
496                                              uint64_t Address,
497                                              const void *Decoder) {
498  if (RegNo > 31)
499    return MCDisassembler::Fail;
500
501  unsigned Reg = getReg(Decoder, Mips::FGRH32RegClassID, RegNo);
502  Inst.addOperand(MCOperand::CreateReg(Reg));
503  return MCDisassembler::Success;
504}
505
506static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
507                                           unsigned RegNo,
508                                           uint64_t Address,
509                                           const void *Decoder) {
510  if (RegNo > 31)
511    return MCDisassembler::Fail;
512  unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
513  Inst.addOperand(MCOperand::CreateReg(Reg));
514  return MCDisassembler::Success;
515}
516
517static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
518                                           unsigned RegNo,
519                                           uint64_t Address,
520                                           const void *Decoder) {
521  if (RegNo > 7)
522    return MCDisassembler::Fail;
523  unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, RegNo);
524  Inst.addOperand(MCOperand::CreateReg(Reg));
525  return MCDisassembler::Success;
526}
527
528static DecodeStatus DecodeMem(MCInst &Inst,
529                              unsigned Insn,
530                              uint64_t Address,
531                              const void *Decoder) {
532  int Offset = SignExtend32<16>(Insn & 0xffff);
533  unsigned Reg = fieldFromInstruction(Insn, 16, 5);
534  unsigned Base = fieldFromInstruction(Insn, 21, 5);
535
536  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
537  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
538
539  if(Inst.getOpcode() == Mips::SC){
540    Inst.addOperand(MCOperand::CreateReg(Reg));
541  }
542
543  Inst.addOperand(MCOperand::CreateReg(Reg));
544  Inst.addOperand(MCOperand::CreateReg(Base));
545  Inst.addOperand(MCOperand::CreateImm(Offset));
546
547  return MCDisassembler::Success;
548}
549
550static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,
551                                    uint64_t Address, const void *Decoder) {
552  int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10));
553  unsigned Reg = fieldFromInstruction(Insn, 6, 5);
554  unsigned Base = fieldFromInstruction(Insn, 11, 5);
555
556  Reg = getReg(Decoder, Mips::MSA128BRegClassID, Reg);
557  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
558
559  Inst.addOperand(MCOperand::CreateReg(Reg));
560  Inst.addOperand(MCOperand::CreateReg(Base));
561  Inst.addOperand(MCOperand::CreateImm(Offset));
562
563  return MCDisassembler::Success;
564}
565
566static DecodeStatus DecodeMemMMImm12(MCInst &Inst,
567                                     unsigned Insn,
568                                     uint64_t Address,
569                                     const void *Decoder) {
570  int Offset = SignExtend32<12>(Insn & 0x0fff);
571  unsigned Reg = fieldFromInstruction(Insn, 21, 5);
572  unsigned Base = fieldFromInstruction(Insn, 16, 5);
573
574  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
575  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
576
577  Inst.addOperand(MCOperand::CreateReg(Reg));
578  Inst.addOperand(MCOperand::CreateReg(Base));
579  Inst.addOperand(MCOperand::CreateImm(Offset));
580
581  return MCDisassembler::Success;
582}
583
584static DecodeStatus DecodeMemMMImm16(MCInst &Inst,
585                                     unsigned Insn,
586                                     uint64_t Address,
587                                     const void *Decoder) {
588  int Offset = SignExtend32<16>(Insn & 0xffff);
589  unsigned Reg = fieldFromInstruction(Insn, 21, 5);
590  unsigned Base = fieldFromInstruction(Insn, 16, 5);
591
592  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);
593  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
594
595  Inst.addOperand(MCOperand::CreateReg(Reg));
596  Inst.addOperand(MCOperand::CreateReg(Base));
597  Inst.addOperand(MCOperand::CreateImm(Offset));
598
599  return MCDisassembler::Success;
600}
601
602static DecodeStatus DecodeFMem(MCInst &Inst,
603                               unsigned Insn,
604                               uint64_t Address,
605                               const void *Decoder) {
606  int Offset = SignExtend32<16>(Insn & 0xffff);
607  unsigned Reg = fieldFromInstruction(Insn, 16, 5);
608  unsigned Base = fieldFromInstruction(Insn, 21, 5);
609
610  Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
611  Base = getReg(Decoder, Mips::GPR32RegClassID, Base);
612
613  Inst.addOperand(MCOperand::CreateReg(Reg));
614  Inst.addOperand(MCOperand::CreateReg(Base));
615  Inst.addOperand(MCOperand::CreateImm(Offset));
616
617  return MCDisassembler::Success;
618}
619
620
621static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
622                                              unsigned RegNo,
623                                              uint64_t Address,
624                                              const void *Decoder) {
625  // Currently only hardware register 29 is supported.
626  if (RegNo != 29)
627    return  MCDisassembler::Fail;
628  Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
629  return MCDisassembler::Success;
630}
631
632static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
633                                              unsigned RegNo,
634                                              uint64_t Address,
635                                              const void *Decoder) {
636  if (RegNo > 30 || RegNo %2)
637    return MCDisassembler::Fail;
638
639  ;
640  unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
641  Inst.addOperand(MCOperand::CreateReg(Reg));
642  return MCDisassembler::Success;
643}
644
645static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
646                                                unsigned RegNo,
647                                                uint64_t Address,
648                                                const void *Decoder) {
649  if (RegNo >= 4)
650    return MCDisassembler::Fail;
651
652  unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
653  Inst.addOperand(MCOperand::CreateReg(Reg));
654  return MCDisassembler::Success;
655}
656
657static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
658                                               unsigned RegNo,
659                                               uint64_t Address,
660                                               const void *Decoder) {
661  if (RegNo >= 4)
662    return MCDisassembler::Fail;
663
664  unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
665  Inst.addOperand(MCOperand::CreateReg(Reg));
666  return MCDisassembler::Success;
667}
668
669static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
670                                               unsigned RegNo,
671                                               uint64_t Address,
672                                               const void *Decoder) {
673  if (RegNo >= 4)
674    return MCDisassembler::Fail;
675
676  unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
677  Inst.addOperand(MCOperand::CreateReg(Reg));
678  return MCDisassembler::Success;
679}
680
681static DecodeStatus DecodeMSA128BRegisterClass(MCInst &Inst,
682                                               unsigned RegNo,
683                                               uint64_t Address,
684                                               const void *Decoder) {
685  if (RegNo > 31)
686    return MCDisassembler::Fail;
687
688  unsigned Reg = getReg(Decoder, Mips::MSA128BRegClassID, RegNo);
689  Inst.addOperand(MCOperand::CreateReg(Reg));
690  return MCDisassembler::Success;
691}
692
693static DecodeStatus DecodeMSA128HRegisterClass(MCInst &Inst,
694                                               unsigned RegNo,
695                                               uint64_t Address,
696                                               const void *Decoder) {
697  if (RegNo > 31)
698    return MCDisassembler::Fail;
699
700  unsigned Reg = getReg(Decoder, Mips::MSA128HRegClassID, RegNo);
701  Inst.addOperand(MCOperand::CreateReg(Reg));
702  return MCDisassembler::Success;
703}
704
705static DecodeStatus DecodeMSA128WRegisterClass(MCInst &Inst,
706                                               unsigned RegNo,
707                                               uint64_t Address,
708                                               const void *Decoder) {
709  if (RegNo > 31)
710    return MCDisassembler::Fail;
711
712  unsigned Reg = getReg(Decoder, Mips::MSA128WRegClassID, RegNo);
713  Inst.addOperand(MCOperand::CreateReg(Reg));
714  return MCDisassembler::Success;
715}
716
717static DecodeStatus DecodeMSA128DRegisterClass(MCInst &Inst,
718                                               unsigned RegNo,
719                                               uint64_t Address,
720                                               const void *Decoder) {
721  if (RegNo > 31)
722    return MCDisassembler::Fail;
723
724  unsigned Reg = getReg(Decoder, Mips::MSA128DRegClassID, RegNo);
725  Inst.addOperand(MCOperand::CreateReg(Reg));
726  return MCDisassembler::Success;
727}
728
729static DecodeStatus DecodeMSACtrlRegisterClass(MCInst &Inst,
730                                               unsigned RegNo,
731                                               uint64_t Address,
732                                               const void *Decoder) {
733  if (RegNo > 7)
734    return MCDisassembler::Fail;
735
736  unsigned Reg = getReg(Decoder, Mips::MSACtrlRegClassID, RegNo);
737  Inst.addOperand(MCOperand::CreateReg(Reg));
738  return MCDisassembler::Success;
739}
740
741static DecodeStatus DecodeBranchTarget(MCInst &Inst,
742                                       unsigned Offset,
743                                       uint64_t Address,
744                                       const void *Decoder) {
745  unsigned BranchOffset = Offset & 0xffff;
746  BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
747  Inst.addOperand(MCOperand::CreateImm(BranchOffset));
748  return MCDisassembler::Success;
749}
750
751static DecodeStatus DecodeJumpTarget(MCInst &Inst,
752                                     unsigned Insn,
753                                     uint64_t Address,
754                                     const void *Decoder) {
755
756  unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
757  Inst.addOperand(MCOperand::CreateImm(JumpOffset));
758  return MCDisassembler::Success;
759}
760
761static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,
762                                         unsigned Offset,
763                                         uint64_t Address,
764                                         const void *Decoder) {
765  unsigned BranchOffset = Offset & 0xffff;
766  BranchOffset = SignExtend32<18>(BranchOffset << 1);
767  Inst.addOperand(MCOperand::CreateImm(BranchOffset));
768  return MCDisassembler::Success;
769}
770
771static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,
772                                       unsigned Insn,
773                                       uint64_t Address,
774                                       const void *Decoder) {
775  unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 1;
776  Inst.addOperand(MCOperand::CreateImm(JumpOffset));
777  return MCDisassembler::Success;
778}
779
780static DecodeStatus DecodeSimm16(MCInst &Inst,
781                                 unsigned Insn,
782                                 uint64_t Address,
783                                 const void *Decoder) {
784  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
785  return MCDisassembler::Success;
786}
787
788static DecodeStatus DecodeInsSize(MCInst &Inst,
789                                  unsigned Insn,
790                                  uint64_t Address,
791                                  const void *Decoder) {
792  // First we need to grab the pos(lsb) from MCInst.
793  int Pos = Inst.getOperand(2).getImm();
794  int Size = (int) Insn - Pos + 1;
795  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
796  return MCDisassembler::Success;
797}
798
799static DecodeStatus DecodeExtSize(MCInst &Inst,
800                                  unsigned Insn,
801                                  uint64_t Address,
802                                  const void *Decoder) {
803  int Size = (int) Insn  + 1;
804  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
805  return MCDisassembler::Success;
806}
807