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