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