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 /// MipsDisassembler - a disasembler class for Mips32.
34 class MipsDisassembler : public MCDisassembler {
35 public:
36   /// Constructor     - Initializes the disassembler.
37   ///
38   MipsDisassembler(const MCSubtargetInfo &STI, bool bigEndian) :
39     MCDisassembler(STI), isBigEndian(bigEndian) {
40   }
41
42   ~MipsDisassembler() {
43   }
44
45   /// getInstruction - See MCDisassembler.
46   DecodeStatus getInstruction(MCInst &instr,
47                               uint64_t &size,
48                               const MemoryObject &region,
49                               uint64_t address,
50                               raw_ostream &vStream,
51                               raw_ostream &cStream) const;
52
53   /// getEDInfo - See MCDisassembler.
54   const EDInstInfo *getEDInfo() const;
55
56 private:
57   bool isBigEndian;
58 };
59
60
61 /// Mips64Disassembler - a disasembler class for Mips64.
62 class Mips64Disassembler : public MCDisassembler {
63 public:
64   /// Constructor     - Initializes the disassembler.
65   ///
66   Mips64Disassembler(const MCSubtargetInfo &STI, bool bigEndian) :
67     MCDisassembler(STI), isBigEndian(bigEndian) {
68   }
69
70   ~Mips64Disassembler() {
71   }
72
73   /// getInstruction - See MCDisassembler.
74   DecodeStatus getInstruction(MCInst &instr,
75                               uint64_t &size,
76                               const MemoryObject &region,
77                               uint64_t address,
78                               raw_ostream &vStream,
79                               raw_ostream &cStream) const;
80
81   /// getEDInfo - See MCDisassembler.
82   const EDInstInfo *getEDInfo() const;
83
84 private:
85   bool isBigEndian;
86 };
87
88 } // end anonymous namespace
89
90 const EDInstInfo *MipsDisassembler::getEDInfo() const {
91   return instInfoMips;
92 }
93
94 const EDInstInfo *Mips64Disassembler::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,true);
194 }
195
196 static MCDisassembler *createMipselDisassembler(
197                        const Target &T,
198                        const MCSubtargetInfo &STI) {
199   return new MipsDisassembler(STI,false);
200 }
201
202 static MCDisassembler *createMips64Disassembler(
203                        const Target &T,
204                        const MCSubtargetInfo &STI) {
205   return new Mips64Disassembler(STI,true);
206 }
207
208 static MCDisassembler *createMips64elDisassembler(
209                        const Target &T,
210                        const MCSubtargetInfo &STI) {
211   return new Mips64Disassembler(STI, 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 #define GET_REGINFO_TARGET_DESC
317 #include "MipsGenRegisterInfo.inc"
318
319 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
320                                                  unsigned RegNo,
321                                                  uint64_t Address,
322                                                  const void *Decoder) {
323
324   if (RegNo > 31)
325     return MCDisassembler::Fail;
326
327   Inst.addOperand(MCOperand::CreateReg(*(Mips::CPU64RegsRegClass.begin() + RegNo)));
328   return MCDisassembler::Success;
329 }
330
331 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
332                                                unsigned RegNo,
333                                                uint64_t Address,
334                                                const void *Decoder) {
335   if (RegNo > 31)
336     return MCDisassembler::Fail;
337   Inst.addOperand(MCOperand::CreateReg(*(Mips::CPURegsRegClass.begin() + RegNo)));
338   return MCDisassembler::Success;
339 }
340
341 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
342                                              unsigned RegNo,
343                                              uint64_t Address,
344                                              const void *Decoder) {
345   if (RegNo > 31)
346     return MCDisassembler::Fail;
347
348   Inst.addOperand(MCOperand::CreateReg(*(Mips::FGR64RegClass.begin() + RegNo)));
349   return MCDisassembler::Success;
350 }
351
352 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
353                                              unsigned RegNo,
354                                              uint64_t Address,
355                                              const void *Decoder) {
356   if (RegNo > 31)
357     return MCDisassembler::Fail;
358
359   Inst.addOperand(MCOperand::CreateReg(*(Mips::FGR32RegClass.begin() + RegNo)));
360   return MCDisassembler::Success;
361 }
362
363 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
364                                            unsigned RegNo,
365                                            uint64_t Address,
366                                            const void *Decoder) {
367   Inst.addOperand(MCOperand::CreateReg(RegNo));
368   return MCDisassembler::Success;
369 }
370
371 static DecodeStatus DecodeMem(MCInst &Inst,
372                               unsigned Insn,
373                               uint64_t Address,
374                               const void *Decoder) {
375   int Offset = SignExtend32<16>(Insn & 0xffff);
376   int Reg = (int)fieldFromInstruction32(Insn, 16, 5);
377   int Base = (int)fieldFromInstruction32(Insn, 21, 5);
378
379   if(Inst.getOpcode() == Mips::SC){
380     Inst.addOperand(MCOperand::CreateReg(*(Mips::CPURegsRegClass.begin() + Reg)));
381   }
382
383   Inst.addOperand(MCOperand::CreateReg(*(Mips::CPURegsRegClass.begin() + Reg)));
384   Inst.addOperand(MCOperand::CreateReg(*(Mips::CPURegsRegClass.begin() + Base)));
385   Inst.addOperand(MCOperand::CreateImm(Offset));
386
387   return MCDisassembler::Success;
388 }
389
390 static DecodeStatus DecodeFMem(MCInst &Inst,
391                                unsigned Insn,
392                                uint64_t Address,
393                                const void *Decoder) {
394   int Offset = SignExtend32<16>(Insn & 0xffff);
395   int Reg = (int)fieldFromInstruction32(Insn, 16, 5);
396   int Base = (int)fieldFromInstruction32(Insn, 21, 5);
397
398   Inst.addOperand(MCOperand::CreateReg(*(Mips::FGR64RegClass.begin() + Reg)));
399   Inst.addOperand(MCOperand::CreateReg(*(Mips::CPURegsRegClass.begin() + Base)));
400   Inst.addOperand(MCOperand::CreateImm(Offset));
401
402   return MCDisassembler::Success;
403 }
404
405
406 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
407                                               unsigned RegNo,
408                                               uint64_t Address,
409                                               const void *Decoder) {
410   // Currently only hardware register 29 is supported.
411   if (RegNo != 29)
412     return  MCDisassembler::Fail;
413   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
414   return MCDisassembler::Success;
415 }
416
417 static DecodeStatus DecodeCondCode(MCInst &Inst,
418                                    unsigned Insn,
419                                    uint64_t Address,
420                                    const void *Decoder) {
421   int CondCode = Insn & 0xf;
422   Inst.addOperand(MCOperand::CreateImm(CondCode));
423   return MCDisassembler::Success;
424 }
425
426 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
427                                               unsigned RegNo,
428                                               uint64_t Address,
429                                               const void *Decoder) {
430   if (RegNo > 30 || RegNo %2)
431     return MCDisassembler::Fail;
432
433   RegNo /=2;
434   Inst.addOperand(MCOperand::CreateReg(*(Mips::AFGR64RegClass.begin() + RegNo)));
435   return MCDisassembler::Success;
436 }
437
438 static DecodeStatus DecodeHWRegs64RegisterClass(MCInst &Inst,
439                                                 unsigned RegNo,
440                                                 uint64_t Address,
441                                                 const void *Decoder) {
442   //Currently only hardware register 29 is supported
443   if (RegNo != 29)
444     return  MCDisassembler::Fail;
445   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29_64));
446   return MCDisassembler::Success;
447 }
448
449 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
450                                        unsigned Offset,
451                                        uint64_t Address,
452                                        const void *Decoder) {
453   unsigned BranchOffset = Offset & 0xffff;
454   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
455   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
456   return MCDisassembler::Success;
457 }
458
459 static DecodeStatus DecodeBC1(MCInst &Inst,
460                               unsigned Insn,
461                               uint64_t Address,
462                               const void *Decoder) {
463   unsigned BranchOffset = Insn & 0xffff;
464   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
465   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
466   return MCDisassembler::Success;
467 }
468
469 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
470                                      unsigned Insn,
471                                      uint64_t Address,
472                                      const void *Decoder) {
473
474   unsigned JumpOffset = fieldFromInstruction32(Insn, 0, 26) << 2;
475   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
476   return MCDisassembler::Success;
477 }
478
479
480 static DecodeStatus DecodeSimm16(MCInst &Inst,
481                                  unsigned Insn,
482                                  uint64_t Address,
483                                  const void *Decoder) {
484   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
485   return MCDisassembler::Success;
486 }
487
488 static DecodeStatus DecodeInsSize(MCInst &Inst,
489                                   unsigned Insn,
490                                   uint64_t Address,
491                                   const void *Decoder) {
492   // First we need to grab the pos(lsb) from MCInst.
493   int Pos = Inst.getOperand(2).getImm();
494   int Size = (int) Insn - Pos + 1;
495   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
496   return MCDisassembler::Success;
497 }
498
499 static DecodeStatus DecodeExtSize(MCInst &Inst,
500                                   unsigned Insn,
501                                   uint64_t Address,
502                                   const void *Decoder) {
503   int Size = (int) Insn  + 1;
504   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
505   return MCDisassembler::Success;
506 }