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