MipsDisassembler.cpp revision d04a8d4b33ff316ca4cf961e06c9e312eff8e64f
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/EDInstInfo.h"
18#include "llvm/MC/MCDisassembler.h"
19#include "llvm/MC/MCFixedLenDisassembler.h"
20#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCSubtargetInfo.h"
22#include "llvm/Support/MathExtras.h"
23#include "llvm/Support/MemoryObject.h"
24#include "llvm/Support/TargetRegistry.h"
25
26// Not a normal header, this must come last.
27#include "MipsGenEDInfo.inc"
28
29using namespace llvm;
30
31typedef MCDisassembler::DecodeStatus DecodeStatus;
32
33namespace {
34
35/// MipsDisassemblerBase - a disasembler class for Mips.
36class MipsDisassemblerBase : public MCDisassembler {
37public:
38  /// Constructor     - Initializes the disassembler.
39  ///
40  MipsDisassemblerBase(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
41                       bool bigEndian) :
42    MCDisassembler(STI), RegInfo(Info), isBigEndian(bigEndian) {}
43
44  virtual ~MipsDisassemblerBase() {}
45
46  /// getEDInfo - See MCDisassembler.
47  const EDInstInfo *getEDInfo() const;
48
49  const MCRegisterInfo *getRegInfo() const { return RegInfo; }
50
51private:
52  const MCRegisterInfo *RegInfo;
53protected:
54  bool isBigEndian;
55};
56
57/// MipsDisassembler - a disasembler class for Mips32.
58class MipsDisassembler : public MipsDisassemblerBase {
59public:
60  /// Constructor     - Initializes the disassembler.
61  ///
62  MipsDisassembler(const MCSubtargetInfo &STI, const MCRegisterInfo *Info,
63                   bool bigEndian) :
64    MipsDisassemblerBase(STI, Info, bigEndian) {}
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
96const EDInstInfo *MipsDisassemblerBase::getEDInfo() const {
97  return instInfoMips;
98}
99
100// Forward declare these because the autogenerated code will reference them.
101// Definitions are further down.
102static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
103                                                 unsigned RegNo,
104                                                 uint64_t Address,
105                                                 const void *Decoder);
106
107static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
108                                               unsigned RegNo,
109                                               uint64_t Address,
110                                               const void *Decoder);
111
112static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
113                                               unsigned RegNo,
114                                               uint64_t Address,
115                                               const void *Decoder);
116
117static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
118                                             unsigned RegNo,
119                                             uint64_t Address,
120                                             const void *Decoder);
121
122static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
123                                             unsigned RegNo,
124                                             uint64_t Address,
125                                             const void *Decoder);
126
127static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
128                                           unsigned RegNo,
129                                           uint64_t Address,
130                                           const void *Decoder);
131
132static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
133                                              unsigned Insn,
134                                              uint64_t Address,
135                                              const void *Decoder);
136
137static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
138                                              unsigned RegNo,
139                                              uint64_t Address,
140                                              const void *Decoder);
141
142static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
143                                                unsigned Insn,
144                                                uint64_t Address,
145                                                const void *Decoder);
146
147static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst,
148                                              unsigned RegNo,
149                                              uint64_t Address,
150                                              const void *Decoder);
151
152static DecodeStatus DecodeBranchTarget(MCInst &Inst,
153                                       unsigned Offset,
154                                       uint64_t Address,
155                                       const void *Decoder);
156
157static DecodeStatus DecodeBC1(MCInst &Inst,
158                              unsigned Insn,
159                              uint64_t Address,
160                              const void *Decoder);
161
162
163static DecodeStatus DecodeJumpTarget(MCInst &Inst,
164                                     unsigned Insn,
165                                     uint64_t Address,
166                                     const void *Decoder);
167
168static DecodeStatus DecodeMem(MCInst &Inst,
169                              unsigned Insn,
170                              uint64_t Address,
171                              const void *Decoder);
172
173static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
174                               uint64_t Address,
175                               const void *Decoder);
176
177static DecodeStatus DecodeSimm16(MCInst &Inst,
178                                 unsigned Insn,
179                                 uint64_t Address,
180                                 const void *Decoder);
181
182static DecodeStatus DecodeCondCode(MCInst &Inst,
183                                   unsigned Insn,
184                                   uint64_t Address,
185                                   const void *Decoder);
186
187static DecodeStatus DecodeInsSize(MCInst &Inst,
188                                  unsigned Insn,
189                                  uint64_t Address,
190                                  const void *Decoder);
191
192static DecodeStatus DecodeExtSize(MCInst &Inst,
193                                  unsigned Insn,
194                                  uint64_t Address,
195                                  const void *Decoder);
196
197namespace llvm {
198extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
199              TheMips64elTarget;
200}
201
202static MCDisassembler *createMipsDisassembler(
203                       const Target &T,
204                       const MCSubtargetInfo &STI) {
205  return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
206}
207
208static MCDisassembler *createMipselDisassembler(
209                       const Target &T,
210                       const MCSubtargetInfo &STI) {
211  return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
212}
213
214static MCDisassembler *createMips64Disassembler(
215                       const Target &T,
216                       const MCSubtargetInfo &STI) {
217  return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
218}
219
220static MCDisassembler *createMips64elDisassembler(
221                       const Target &T,
222                       const MCSubtargetInfo &STI) {
223  return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
224}
225
226extern "C" void LLVMInitializeMipsDisassembler() {
227  // Register the disassembler.
228  TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
229                                         createMipsDisassembler);
230  TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
231                                         createMipselDisassembler);
232  TargetRegistry::RegisterMCDisassembler(TheMips64Target,
233                                         createMips64Disassembler);
234  TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
235                                         createMips64elDisassembler);
236}
237
238
239#include "MipsGenDisassemblerTables.inc"
240
241  /// readInstruction - read four bytes from the MemoryObject
242  /// and return 32 bit word sorted according to the given endianess
243static DecodeStatus readInstruction32(const MemoryObject &region,
244                                      uint64_t address,
245                                      uint64_t &size,
246                                      uint32_t &insn,
247                                      bool isBigEndian) {
248  uint8_t Bytes[4];
249
250  // We want to read exactly 4 Bytes of data.
251  if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
252    size = 0;
253    return MCDisassembler::Fail;
254  }
255
256  if (isBigEndian) {
257    // Encoded as a big-endian 32-bit word in the stream.
258    insn = (Bytes[3] <<  0) |
259           (Bytes[2] <<  8) |
260           (Bytes[1] << 16) |
261           (Bytes[0] << 24);
262  }
263  else {
264    // Encoded as a small-endian 32-bit word in the stream.
265    insn = (Bytes[0] <<  0) |
266           (Bytes[1] <<  8) |
267           (Bytes[2] << 16) |
268           (Bytes[3] << 24);
269  }
270
271  return MCDisassembler::Success;
272}
273
274DecodeStatus
275MipsDisassembler::getInstruction(MCInst &instr,
276                                 uint64_t &Size,
277                                 const MemoryObject &Region,
278                                 uint64_t Address,
279                                 raw_ostream &vStream,
280                                 raw_ostream &cStream) const {
281  uint32_t Insn;
282
283  DecodeStatus Result = readInstruction32(Region, Address, Size,
284                                          Insn, isBigEndian);
285  if (Result == MCDisassembler::Fail)
286    return MCDisassembler::Fail;
287
288  // Calling the auto-generated decoder function.
289  Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
290                             this, STI);
291  if (Result != MCDisassembler::Fail) {
292    Size = 4;
293    return Result;
294  }
295
296  return MCDisassembler::Fail;
297}
298
299DecodeStatus
300Mips64Disassembler::getInstruction(MCInst &instr,
301                                   uint64_t &Size,
302                                   const MemoryObject &Region,
303                                   uint64_t Address,
304                                   raw_ostream &vStream,
305                                   raw_ostream &cStream) const {
306  uint32_t Insn;
307
308  DecodeStatus Result = readInstruction32(Region, Address, Size,
309                                          Insn, isBigEndian);
310  if (Result == MCDisassembler::Fail)
311    return MCDisassembler::Fail;
312
313  // Calling the auto-generated decoder function.
314  Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
315                             this, STI);
316  if (Result != MCDisassembler::Fail) {
317    Size = 4;
318    return Result;
319  }
320  // If we fail to decode in Mips64 decoder space we can try in Mips32
321  Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
322                             this, STI);
323  if (Result != MCDisassembler::Fail) {
324    Size = 4;
325    return Result;
326  }
327
328  return MCDisassembler::Fail;
329}
330
331static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
332  const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
333  return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
334}
335
336static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
337                                                 unsigned RegNo,
338                                                 uint64_t Address,
339                                                 const void *Decoder) {
340
341  if (RegNo > 31)
342    return MCDisassembler::Fail;
343
344  unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
345  Inst.addOperand(MCOperand::CreateReg(Reg));
346  return MCDisassembler::Success;
347}
348
349static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
350                                               unsigned RegNo,
351                                               uint64_t Address,
352                                               const void *Decoder) {
353  if (RegNo > 31)
354    return MCDisassembler::Fail;
355  unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
356  Inst.addOperand(MCOperand::CreateReg(Reg));
357  return MCDisassembler::Success;
358}
359
360static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
361                                               unsigned RegNo,
362                                               uint64_t Address,
363                                               const void *Decoder) {
364  return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder);
365}
366
367static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
368                                             unsigned RegNo,
369                                             uint64_t Address,
370                                             const void *Decoder) {
371  if (RegNo > 31)
372    return MCDisassembler::Fail;
373
374  unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
375  Inst.addOperand(MCOperand::CreateReg(Reg));
376  return MCDisassembler::Success;
377}
378
379static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
380                                             unsigned RegNo,
381                                             uint64_t Address,
382                                             const void *Decoder) {
383  if (RegNo > 31)
384    return MCDisassembler::Fail;
385
386  unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
387  Inst.addOperand(MCOperand::CreateReg(Reg));
388  return MCDisassembler::Success;
389}
390
391static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
392                                           unsigned RegNo,
393                                           uint64_t Address,
394                                           const void *Decoder) {
395  Inst.addOperand(MCOperand::CreateReg(RegNo));
396  return MCDisassembler::Success;
397}
398
399static DecodeStatus DecodeMem(MCInst &Inst,
400                              unsigned Insn,
401                              uint64_t Address,
402                              const void *Decoder) {
403  int Offset = SignExtend32<16>(Insn & 0xffff);
404  unsigned Reg = fieldFromInstruction(Insn, 16, 5);
405  unsigned Base = fieldFromInstruction(Insn, 21, 5);
406
407  Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
408  Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
409
410  if(Inst.getOpcode() == Mips::SC){
411    Inst.addOperand(MCOperand::CreateReg(Reg));
412  }
413
414  Inst.addOperand(MCOperand::CreateReg(Reg));
415  Inst.addOperand(MCOperand::CreateReg(Base));
416  Inst.addOperand(MCOperand::CreateImm(Offset));
417
418  return MCDisassembler::Success;
419}
420
421static DecodeStatus DecodeFMem(MCInst &Inst,
422                               unsigned Insn,
423                               uint64_t Address,
424                               const void *Decoder) {
425  int Offset = SignExtend32<16>(Insn & 0xffff);
426  unsigned Reg = fieldFromInstruction(Insn, 16, 5);
427  unsigned Base = fieldFromInstruction(Insn, 21, 5);
428
429  Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
430  Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
431
432  Inst.addOperand(MCOperand::CreateReg(Reg));
433  Inst.addOperand(MCOperand::CreateReg(Base));
434  Inst.addOperand(MCOperand::CreateImm(Offset));
435
436  return MCDisassembler::Success;
437}
438
439
440static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
441                                              unsigned RegNo,
442                                              uint64_t Address,
443                                              const void *Decoder) {
444  // Currently only hardware register 29 is supported.
445  if (RegNo != 29)
446    return  MCDisassembler::Fail;
447  Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
448  return MCDisassembler::Success;
449}
450
451static DecodeStatus DecodeCondCode(MCInst &Inst,
452                                   unsigned Insn,
453                                   uint64_t Address,
454                                   const void *Decoder) {
455  int CondCode = Insn & 0xf;
456  Inst.addOperand(MCOperand::CreateImm(CondCode));
457  return MCDisassembler::Success;
458}
459
460static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
461                                              unsigned RegNo,
462                                              uint64_t Address,
463                                              const void *Decoder) {
464  if (RegNo > 30 || RegNo %2)
465    return MCDisassembler::Fail;
466
467  ;
468  unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
469  Inst.addOperand(MCOperand::CreateReg(Reg));
470  return MCDisassembler::Success;
471}
472
473static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
474                                                unsigned RegNo,
475                                                uint64_t Address,
476                                                const void *Decoder) {
477  //Currently only hardware register 29 is supported
478  if (RegNo != 29)
479    return  MCDisassembler::Fail;
480  Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
481  return MCDisassembler::Success;
482}
483
484static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst,
485                                              unsigned RegNo,
486                                              uint64_t Address,
487                                              const void *Decoder) {
488  if (RegNo >= 4)
489    return MCDisassembler::Fail;
490
491  unsigned Reg = getReg(Decoder, Mips::ACRegsRegClassID, RegNo);
492  Inst.addOperand(MCOperand::CreateReg(Reg));
493  return MCDisassembler::Success;
494}
495
496static DecodeStatus DecodeBranchTarget(MCInst &Inst,
497                                       unsigned Offset,
498                                       uint64_t Address,
499                                       const void *Decoder) {
500  unsigned BranchOffset = Offset & 0xffff;
501  BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
502  Inst.addOperand(MCOperand::CreateImm(BranchOffset));
503  return MCDisassembler::Success;
504}
505
506static DecodeStatus DecodeBC1(MCInst &Inst,
507                              unsigned Insn,
508                              uint64_t Address,
509                              const void *Decoder) {
510  unsigned BranchOffset = Insn & 0xffff;
511  BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
512  Inst.addOperand(MCOperand::CreateImm(BranchOffset));
513  return MCDisassembler::Success;
514}
515
516static DecodeStatus DecodeJumpTarget(MCInst &Inst,
517                                     unsigned Insn,
518                                     uint64_t Address,
519                                     const void *Decoder) {
520
521  unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
522  Inst.addOperand(MCOperand::CreateImm(JumpOffset));
523  return MCDisassembler::Success;
524}
525
526
527static DecodeStatus DecodeSimm16(MCInst &Inst,
528                                 unsigned Insn,
529                                 uint64_t Address,
530                                 const void *Decoder) {
531  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
532  return MCDisassembler::Success;
533}
534
535static DecodeStatus DecodeInsSize(MCInst &Inst,
536                                  unsigned Insn,
537                                  uint64_t Address,
538                                  const void *Decoder) {
539  // First we need to grab the pos(lsb) from MCInst.
540  int Pos = Inst.getOperand(2).getImm();
541  int Size = (int) Insn - Pos + 1;
542  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
543  return MCDisassembler::Success;
544}
545
546static DecodeStatus DecodeExtSize(MCInst &Inst,
547                                  unsigned Insn,
548                                  uint64_t Address,
549                                  const void *Decoder) {
550  int Size = (int) Insn  + 1;
551  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
552  return MCDisassembler::Success;
553}
554