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