MipsDisassembler.cpp revision 63d10fbc89c02758cd91e3b53749e55c2bd0cf65
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 "MipsSubtarget.h"
16#include "llvm/MC/EDInstInfo.h"
17#include "llvm/MC/MCDisassembler.h"
18#include "llvm/Support/MemoryObject.h"
19#include "llvm/Support/TargetRegistry.h"
20#include "llvm/MC/MCSubtargetInfo.h"
21#include "llvm/MC/MCInst.h"
22#include "llvm/MC/MCRegisterInfo.h"
23#include "llvm/Support/MathExtras.h"
24
25
26#include "MipsGenEDInfo.inc"
27
28using namespace llvm;
29
30typedef MCDisassembler::DecodeStatus DecodeStatus;
31
32namespace {
33
34/// MipsDisassembler - a disasembler class for Mips32.
35class MipsDisassembler : public MCDisassembler {
36public:
37  /// Constructor     - Initializes the disassembler.
38  ///
39  MipsDisassembler(const MCSubtargetInfo &STI, bool bigEndian) :
40    MCDisassembler(STI), isBigEndian(bigEndian) {
41  }
42
43  ~MipsDisassembler() {
44  }
45
46  /// getInstruction - See MCDisassembler.
47  DecodeStatus getInstruction(MCInst &instr,
48                              uint64_t &size,
49                              const MemoryObject &region,
50                              uint64_t address,
51                              raw_ostream &vStream,
52                              raw_ostream &cStream) const;
53
54  /// getEDInfo - See MCDisassembler.
55  const EDInstInfo *getEDInfo() const;
56
57private:
58  bool isBigEndian;
59};
60
61
62/// Mips64Disassembler - a disasembler class for Mips64.
63class Mips64Disassembler : public MCDisassembler {
64public:
65  /// Constructor     - Initializes the disassembler.
66  ///
67  Mips64Disassembler(const MCSubtargetInfo &STI, bool bigEndian) :
68    MCDisassembler(STI), isBigEndian(bigEndian) {
69  }
70
71  ~Mips64Disassembler() {
72  }
73
74  /// getInstruction - See MCDisassembler.
75  DecodeStatus getInstruction(MCInst &instr,
76                              uint64_t &size,
77                              const MemoryObject &region,
78                              uint64_t address,
79                              raw_ostream &vStream,
80                              raw_ostream &cStream) const;
81
82  /// getEDInfo - See MCDisassembler.
83  const EDInstInfo *getEDInfo() const;
84
85private:
86  bool isBigEndian;
87};
88
89} // end anonymous namespace
90
91const EDInstInfo *MipsDisassembler::getEDInfo() const {
92  return instInfoMips;
93}
94
95const EDInstInfo *Mips64Disassembler::getEDInfo() const {
96  return instInfoMips;
97}
98
99// Decoder tables for Mips register
100static const uint16_t CPURegsTable[] = {
101  Mips::ZERO, Mips::AT, Mips::V0, Mips::V1,
102  Mips::A0, Mips::A1, Mips::A2, Mips::A3,
103  Mips::T0, Mips::T1, Mips::T2, Mips::T3,
104  Mips::T4, Mips::T5, Mips::T6, Mips::T7,
105  Mips::S0, Mips::S1, Mips::S2, Mips::S3,
106  Mips::S4, Mips::S5, Mips::S6, Mips::S7,
107  Mips::T8, Mips::T9, Mips::K0, Mips::K1,
108  Mips::GP, Mips::SP, Mips::FP, Mips::RA
109};
110
111static const uint16_t FGR32RegsTable[] = {
112  Mips::F0, Mips::F1, Mips::F2, Mips::F3,
113  Mips::F4, Mips::F5, Mips::F6, Mips::F7,
114  Mips::F8, Mips::F9, Mips::F10, Mips::F11,
115  Mips::F12, Mips::F13, Mips::F14, Mips::F15,
116  Mips::F16, Mips::F17, Mips::F18, Mips::F18,
117  Mips::F20, Mips::F21, Mips::F22, Mips::F23,
118  Mips::F24, Mips::F25, Mips::F26, Mips::F27,
119  Mips::F28, Mips::F29, Mips::F30, Mips::F31
120};
121
122static const uint16_t CPU64RegsTable[] = {
123  Mips::ZERO_64, Mips::AT_64, Mips::V0_64, Mips::V1_64,
124  Mips::A0_64, Mips::A1_64, Mips::A2_64, Mips::A3_64,
125  Mips::T0_64, Mips::T1_64, Mips::T2_64, Mips::T3_64,
126  Mips::T4_64, Mips::T5_64, Mips::T6_64, Mips::T7_64,
127  Mips::S0_64, Mips::S1_64, Mips::S2_64, Mips::S3_64,
128  Mips::S4_64, Mips::S5_64, Mips::S6_64, Mips::S7_64,
129  Mips::T8_64, Mips::T9_64, Mips::K0_64, Mips::K1_64,
130  Mips::GP_64, Mips::SP_64, Mips::FP_64, Mips::RA_64
131};
132
133static const uint16_t FGR64RegsTable[] = {
134  Mips::D0_64,  Mips::D1_64,  Mips::D2_64,  Mips::D3_64,
135  Mips::D4_64,  Mips::D5_64,  Mips::D6_64,  Mips::D7_64,
136  Mips::D8_64,  Mips::D9_64,  Mips::D10_64, Mips::D11_64,
137  Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64,
138  Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_64,
139  Mips::D20_64, Mips::D21_64, Mips::D22_64, Mips::D23_64,
140  Mips::D24_64, Mips::D25_64, Mips::D26_64, Mips::D27_64,
141  Mips::D28_64, Mips::D29_64, Mips::D30_64, Mips::D31_64
142};
143
144static const uint16_t AFGR64RegsTable[] = {
145  Mips::D0,  Mips::D1,  Mips::D2,  Mips::D3,
146  Mips::D4,  Mips::D5,  Mips::D6,  Mips::D7,
147  Mips::D8,  Mips::D9,  Mips::D10, Mips::D11,
148  Mips::D12, Mips::D13, Mips::D14, Mips::D15
149};
150
151// Forward declare these because the autogenerated code will reference them.
152// Definitions are further down.
153static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
154                                                 unsigned RegNo,
155                                                 uint64_t Address,
156                                                 const void *Decoder);
157
158static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
159                                               unsigned RegNo,
160                                               uint64_t Address,
161                                               const void *Decoder);
162
163static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
164                                             unsigned RegNo,
165                                             uint64_t Address,
166                                             const void *Decoder);
167
168static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
169                                             unsigned RegNo,
170                                             uint64_t Address,
171                                             const void *Decoder);
172
173static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
174                                           unsigned RegNo,
175                                           uint64_t Address,
176                                           const void *Decoder);
177
178static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
179                                              unsigned Insn,
180                                              uint64_t Address,
181                                              const void *Decoder);
182
183static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
184                                              unsigned RegNo,
185                                              uint64_t Address,
186                                              const void *Decoder);
187
188static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
189                                                unsigned Insn,
190                                                uint64_t Address,
191                                                const void *Decoder);
192
193static DecodeStatus DecodeBranchTarget(MCInst &Inst,
194                                       unsigned Offset,
195                                       uint64_t Address,
196                                       const void *Decoder);
197
198static DecodeStatus DecodeBC1(MCInst &Inst,
199                              unsigned Insn,
200                              uint64_t Address,
201                              const void *Decoder);
202
203
204static DecodeStatus DecodeJumpTarget(MCInst &Inst,
205                                     unsigned Insn,
206                                     uint64_t Address,
207                                     const void *Decoder);
208
209static DecodeStatus DecodeMem(MCInst &Inst,
210                              unsigned Insn,
211                              uint64_t Address,
212                              const void *Decoder);
213
214static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
215                               uint64_t Address,
216                               const void *Decoder);
217
218static DecodeStatus DecodeSimm16(MCInst &Inst,
219                                 unsigned Insn,
220                                 uint64_t Address,
221                                 const void *Decoder);
222
223static DecodeStatus DecodeCondCode(MCInst &Inst,
224                                   unsigned Insn,
225                                   uint64_t Address,
226                                   const void *Decoder);
227
228static DecodeStatus DecodeInsSize(MCInst &Inst,
229                                  unsigned Insn,
230                                  uint64_t Address,
231                                  const void *Decoder);
232
233static DecodeStatus DecodeExtSize(MCInst &Inst,
234                                  unsigned Insn,
235                                  uint64_t Address,
236                                  const void *Decoder);
237
238namespace llvm {
239extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
240              TheMips64elTarget;
241}
242
243static MCDisassembler *createMipsDisassembler(
244                       const Target &T,
245                       const MCSubtargetInfo &STI) {
246  return new MipsDisassembler(STI,true);
247}
248
249static MCDisassembler *createMipselDisassembler(
250                       const Target &T,
251                       const MCSubtargetInfo &STI) {
252  return new MipsDisassembler(STI,false);
253}
254
255static MCDisassembler *createMips64Disassembler(
256                       const Target &T,
257                       const MCSubtargetInfo &STI) {
258  return new Mips64Disassembler(STI,true);
259}
260
261static MCDisassembler *createMips64elDisassembler(
262                       const Target &T,
263                       const MCSubtargetInfo &STI) {
264  return new Mips64Disassembler(STI, false);
265}
266
267extern "C" void LLVMInitializeMipsDisassembler() {
268  // Register the disassembler.
269  TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
270                                         createMipsDisassembler);
271  TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
272                                         createMipselDisassembler);
273  TargetRegistry::RegisterMCDisassembler(TheMips64Target,
274                                         createMips64Disassembler);
275  TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
276                                         createMips64elDisassembler);
277}
278
279
280#include "MipsGenDisassemblerTables.inc"
281
282  /// readInstruction - read four bytes from the MemoryObject
283  /// and return 32 bit word sorted according to the given endianess
284static DecodeStatus readInstruction32(const MemoryObject &region,
285                                      uint64_t address,
286                                      uint64_t &size,
287                                      uint32_t &insn,
288                                      bool isBigEndian) {
289  uint8_t Bytes[4];
290
291  // We want to read exactly 4 Bytes of data.
292  if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
293    size = 0;
294    return MCDisassembler::Fail;
295  }
296
297  if (isBigEndian) {
298    // Encoded as a big-endian 32-bit word in the stream.
299    insn = (Bytes[3] <<  0) |
300           (Bytes[2] <<  8) |
301           (Bytes[1] << 16) |
302           (Bytes[0] << 24);
303  }
304  else {
305    // Encoded as a small-endian 32-bit word in the stream.
306    insn = (Bytes[0] <<  0) |
307           (Bytes[1] <<  8) |
308           (Bytes[2] << 16) |
309           (Bytes[3] << 24);
310  }
311
312  return MCDisassembler::Success;
313}
314
315DecodeStatus
316MipsDisassembler::getInstruction(MCInst &instr,
317                                 uint64_t &Size,
318                                 const MemoryObject &Region,
319                                 uint64_t Address,
320                                 raw_ostream &vStream,
321                                 raw_ostream &cStream) const {
322  uint32_t Insn;
323
324  DecodeStatus Result = readInstruction32(Region, Address, Size,
325                                          Insn, isBigEndian);
326  if (Result == MCDisassembler::Fail)
327    return MCDisassembler::Fail;
328
329  // Calling the auto-generated decoder function.
330  Result = decodeMipsInstruction32(instr, Insn, Address, this, STI);
331  if (Result != MCDisassembler::Fail) {
332    Size = 4;
333    return Result;
334  }
335
336  return MCDisassembler::Fail;
337}
338
339DecodeStatus
340Mips64Disassembler::getInstruction(MCInst &instr,
341                                   uint64_t &Size,
342                                   const MemoryObject &Region,
343                                   uint64_t Address,
344                                   raw_ostream &vStream,
345                                   raw_ostream &cStream) const {
346  uint32_t Insn;
347
348  DecodeStatus Result = readInstruction32(Region, Address, Size,
349                                          Insn, isBigEndian);
350  if (Result == MCDisassembler::Fail)
351    return MCDisassembler::Fail;
352
353  // Calling the auto-generated decoder function.
354  Result = decodeMips64Instruction32(instr, Insn, Address, this, STI);
355  if (Result != MCDisassembler::Fail) {
356    Size = 4;
357    return Result;
358  }
359  // If we fail to decode in Mips64 decoder space we can try in Mips32
360  Result = decodeMipsInstruction32(instr, Insn, Address, this, STI);
361  if (Result != MCDisassembler::Fail) {
362    Size = 4;
363    return Result;
364  }
365
366  return MCDisassembler::Fail;
367}
368
369static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
370                                                 unsigned RegNo,
371                                                 uint64_t Address,
372                                                 const void *Decoder) {
373
374  if (RegNo > 31)
375    return MCDisassembler::Fail;
376
377  Inst.addOperand(MCOperand::CreateReg(CPU64RegsTable[RegNo]));
378  return MCDisassembler::Success;
379}
380
381static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
382                                               unsigned RegNo,
383                                               uint64_t Address,
384                                               const void *Decoder) {
385  if (RegNo > 31)
386    return MCDisassembler::Fail;
387
388  Inst.addOperand(MCOperand::CreateReg(CPURegsTable[RegNo]));
389  return MCDisassembler::Success;
390}
391
392static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
393                                             unsigned RegNo,
394                                             uint64_t Address,
395                                             const void *Decoder) {
396  if (RegNo > 31)
397    return MCDisassembler::Fail;
398
399  Inst.addOperand(MCOperand::CreateReg(FGR64RegsTable[RegNo]));
400  return MCDisassembler::Success;
401}
402
403static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
404                                             unsigned RegNo,
405                                             uint64_t Address,
406                                             const void *Decoder) {
407  if (RegNo > 31)
408    return MCDisassembler::Fail;
409
410  Inst.addOperand(MCOperand::CreateReg(FGR32RegsTable[RegNo]));
411  return MCDisassembler::Success;
412}
413
414static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
415                                           unsigned RegNo,
416                                           uint64_t Address,
417                                           const void *Decoder) {
418  Inst.addOperand(MCOperand::CreateReg(RegNo));
419  return MCDisassembler::Success;
420}
421
422static DecodeStatus DecodeMem(MCInst &Inst,
423                              unsigned Insn,
424                              uint64_t Address,
425                              const void *Decoder) {
426  int Offset = SignExtend32<16>(Insn & 0xffff);
427  int Reg = (int)fieldFromInstruction32(Insn, 16, 5);
428  int Base = (int)fieldFromInstruction32(Insn, 21, 5);
429
430  if(Inst.getOpcode() == Mips::SC){
431    Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Reg]));
432  }
433
434  Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Reg]));
435  Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Base]));
436  Inst.addOperand(MCOperand::CreateImm(Offset));
437
438  return MCDisassembler::Success;
439}
440
441static DecodeStatus DecodeFMem(MCInst &Inst,
442                               unsigned Insn,
443                               uint64_t Address,
444                               const void *Decoder) {
445  int Offset = SignExtend32<16>(Insn & 0xffff);
446  int Reg = (int)fieldFromInstruction32(Insn, 16, 5);
447  int Base = (int)fieldFromInstruction32(Insn, 21, 5);
448
449  Inst.addOperand(MCOperand::CreateReg(FGR64RegsTable[Reg]));
450  Inst.addOperand(MCOperand::CreateReg(CPURegsTable[Base]));
451  Inst.addOperand(MCOperand::CreateImm(Offset));
452
453  return MCDisassembler::Success;
454}
455
456
457static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
458                                              unsigned RegNo,
459                                              uint64_t Address,
460                                              const void *Decoder) {
461  // Currently only hardware register 29 is supported.
462  if (RegNo != 29)
463    return  MCDisassembler::Fail;
464  Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
465  return MCDisassembler::Success;
466}
467
468static DecodeStatus DecodeCondCode(MCInst &Inst,
469                                   unsigned Insn,
470                                   uint64_t Address,
471                                   const void *Decoder) {
472  int CondCode = Insn & 0xf;
473  Inst.addOperand(MCOperand::CreateImm(CondCode));
474  return MCDisassembler::Success;
475}
476
477static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
478                                              unsigned RegNo,
479                                              uint64_t Address,
480                                              const void *Decoder) {
481  if (RegNo > 31)
482    return MCDisassembler::Fail;
483
484  Inst.addOperand(MCOperand::CreateReg(AFGR64RegsTable[RegNo]));
485  return MCDisassembler::Success;
486}
487
488static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
489                                                unsigned RegNo,
490                                                uint64_t Address,
491                                                const void *Decoder) {
492  //Currently only hardware register 29 is supported
493  if (RegNo != 29)
494    return  MCDisassembler::Fail;
495  Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
496  return MCDisassembler::Success;
497}
498
499static DecodeStatus DecodeBranchTarget(MCInst &Inst,
500                                       unsigned Offset,
501                                       uint64_t Address,
502                                       const void *Decoder) {
503  unsigned BranchOffset = Offset & 0xffff;
504  BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
505  Inst.addOperand(MCOperand::CreateImm(BranchOffset));
506  return MCDisassembler::Success;
507}
508
509static DecodeStatus DecodeBC1(MCInst &Inst,
510                              unsigned Insn,
511                              uint64_t Address,
512                              const void *Decoder) {
513  unsigned BranchOffset = Insn & 0xffff;
514  BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
515  Inst.addOperand(MCOperand::CreateImm(BranchOffset));
516  return MCDisassembler::Success;
517}
518
519static DecodeStatus DecodeJumpTarget(MCInst &Inst,
520                                     unsigned Insn,
521                                     uint64_t Address,
522                                     const void *Decoder) {
523
524  unsigned JumpOffset = fieldFromInstruction32(Insn, 0, 26) << 2;
525  Inst.addOperand(MCOperand::CreateImm(JumpOffset));
526  return MCDisassembler::Success;
527}
528
529
530static DecodeStatus DecodeSimm16(MCInst &Inst,
531                                 unsigned Insn,
532                                 uint64_t Address,
533                                 const void *Decoder) {
534  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
535  return MCDisassembler::Success;
536}
537
538static DecodeStatus DecodeInsSize(MCInst &Inst,
539                                  unsigned Insn,
540                                  uint64_t Address,
541                                  const void *Decoder) {
542  // First we need to grab the pos(lsb) from MCInst.
543  int Pos = Inst.getOperand(2).getImm();
544  int Size = (int) Insn - Pos + 1;
545  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
546  return MCDisassembler::Success;
547}
548
549static DecodeStatus DecodeExtSize(MCInst &Inst,
550                                  unsigned Insn,
551                                  uint64_t Address,
552                                  const void *Decoder) {
553  int Size = (int) Insn  + 1;
554  Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
555  return MCDisassembler::Success;
556}
557