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