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