MipsDisassembler.cpp: Prune DecodeHWRegs64RegisterClass() to suppress a warning....
[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 DecodeACRegsRegisterClass(MCInst &Inst,
132                                               unsigned RegNo,
133                                               uint64_t Address,
134                                               const void *Decoder);
135
136 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
137                                        unsigned Offset,
138                                        uint64_t Address,
139                                        const void *Decoder);
140
141 static DecodeStatus DecodeBC1(MCInst &Inst,
142                               unsigned Insn,
143                               uint64_t Address,
144                               const void *Decoder);
145
146
147 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
148                                      unsigned Insn,
149                                      uint64_t Address,
150                                      const void *Decoder);
151
152 static DecodeStatus DecodeMem(MCInst &Inst,
153                               unsigned Insn,
154                               uint64_t Address,
155                               const void *Decoder);
156
157 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
158                                uint64_t Address,
159                                const void *Decoder);
160
161 static DecodeStatus DecodeSimm16(MCInst &Inst,
162                                  unsigned Insn,
163                                  uint64_t Address,
164                                  const void *Decoder);
165
166 static DecodeStatus DecodeCondCode(MCInst &Inst,
167                                    unsigned Insn,
168                                    uint64_t Address,
169                                    const void *Decoder);
170
171 static DecodeStatus DecodeInsSize(MCInst &Inst,
172                                   unsigned Insn,
173                                   uint64_t Address,
174                                   const void *Decoder);
175
176 static DecodeStatus DecodeExtSize(MCInst &Inst,
177                                   unsigned Insn,
178                                   uint64_t Address,
179                                   const void *Decoder);
180
181 namespace llvm {
182 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
183               TheMips64elTarget;
184 }
185
186 static MCDisassembler *createMipsDisassembler(
187                        const Target &T,
188                        const MCSubtargetInfo &STI) {
189   return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
190 }
191
192 static MCDisassembler *createMipselDisassembler(
193                        const Target &T,
194                        const MCSubtargetInfo &STI) {
195   return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
196 }
197
198 static MCDisassembler *createMips64Disassembler(
199                        const Target &T,
200                        const MCSubtargetInfo &STI) {
201   return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
202 }
203
204 static MCDisassembler *createMips64elDisassembler(
205                        const Target &T,
206                        const MCSubtargetInfo &STI) {
207   return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
208 }
209
210 extern "C" void LLVMInitializeMipsDisassembler() {
211   // Register the disassembler.
212   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
213                                          createMipsDisassembler);
214   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
215                                          createMipselDisassembler);
216   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
217                                          createMips64Disassembler);
218   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
219                                          createMips64elDisassembler);
220 }
221
222
223 #include "MipsGenDisassemblerTables.inc"
224
225   /// readInstruction - read four bytes from the MemoryObject
226   /// and return 32 bit word sorted according to the given endianess
227 static DecodeStatus readInstruction32(const MemoryObject &region,
228                                       uint64_t address,
229                                       uint64_t &size,
230                                       uint32_t &insn,
231                                       bool isBigEndian) {
232   uint8_t Bytes[4];
233
234   // We want to read exactly 4 Bytes of data.
235   if (region.readBytes(address, 4, (uint8_t*)Bytes, NULL) == -1) {
236     size = 0;
237     return MCDisassembler::Fail;
238   }
239
240   if (isBigEndian) {
241     // Encoded as a big-endian 32-bit word in the stream.
242     insn = (Bytes[3] <<  0) |
243            (Bytes[2] <<  8) |
244            (Bytes[1] << 16) |
245            (Bytes[0] << 24);
246   }
247   else {
248     // Encoded as a small-endian 32-bit word in the stream.
249     insn = (Bytes[0] <<  0) |
250            (Bytes[1] <<  8) |
251            (Bytes[2] << 16) |
252            (Bytes[3] << 24);
253   }
254
255   return MCDisassembler::Success;
256 }
257
258 DecodeStatus
259 MipsDisassembler::getInstruction(MCInst &instr,
260                                  uint64_t &Size,
261                                  const MemoryObject &Region,
262                                  uint64_t Address,
263                                  raw_ostream &vStream,
264                                  raw_ostream &cStream) const {
265   uint32_t Insn;
266
267   DecodeStatus Result = readInstruction32(Region, Address, Size,
268                                           Insn, isBigEndian);
269   if (Result == MCDisassembler::Fail)
270     return MCDisassembler::Fail;
271
272   // Calling the auto-generated decoder function.
273   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
274                              this, STI);
275   if (Result != MCDisassembler::Fail) {
276     Size = 4;
277     return Result;
278   }
279
280   return MCDisassembler::Fail;
281 }
282
283 DecodeStatus
284 Mips64Disassembler::getInstruction(MCInst &instr,
285                                    uint64_t &Size,
286                                    const MemoryObject &Region,
287                                    uint64_t Address,
288                                    raw_ostream &vStream,
289                                    raw_ostream &cStream) const {
290   uint32_t Insn;
291
292   DecodeStatus Result = readInstruction32(Region, Address, Size,
293                                           Insn, isBigEndian);
294   if (Result == MCDisassembler::Fail)
295     return MCDisassembler::Fail;
296
297   // Calling the auto-generated decoder function.
298   Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
299                              this, STI);
300   if (Result != MCDisassembler::Fail) {
301     Size = 4;
302     return Result;
303   }
304   // If we fail to decode in Mips64 decoder space we can try in Mips32
305   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
306                              this, STI);
307   if (Result != MCDisassembler::Fail) {
308     Size = 4;
309     return Result;
310   }
311
312   return MCDisassembler::Fail;
313 }
314
315 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
316   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
317   return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
318 }
319
320 static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
321                                                  unsigned RegNo,
322                                                  uint64_t Address,
323                                                  const void *Decoder) {
324
325   if (RegNo > 31)
326     return MCDisassembler::Fail;
327
328   unsigned Reg = getReg(Decoder, Mips::CPU64RegsRegClassID, RegNo);
329   Inst.addOperand(MCOperand::CreateReg(Reg));
330   return MCDisassembler::Success;
331 }
332
333 static DecodeStatus DecodeCPURegsRegisterClass(MCInst &Inst,
334                                                unsigned RegNo,
335                                                uint64_t Address,
336                                                const void *Decoder) {
337   if (RegNo > 31)
338     return MCDisassembler::Fail;
339   unsigned Reg = getReg(Decoder, Mips::CPURegsRegClassID, RegNo);
340   Inst.addOperand(MCOperand::CreateReg(Reg));
341   return MCDisassembler::Success;
342 }
343
344 static DecodeStatus DecodeDSPRegsRegisterClass(MCInst &Inst,
345                                                unsigned RegNo,
346                                                uint64_t Address,
347                                                const void *Decoder) {
348   return DecodeCPURegsRegisterClass(Inst, RegNo, Address, Decoder);
349 }
350
351 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
352                                              unsigned RegNo,
353                                              uint64_t Address,
354                                              const void *Decoder) {
355   if (RegNo > 31)
356     return MCDisassembler::Fail;
357
358   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
359   Inst.addOperand(MCOperand::CreateReg(Reg));
360   return MCDisassembler::Success;
361 }
362
363 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
364                                              unsigned RegNo,
365                                              uint64_t Address,
366                                              const void *Decoder) {
367   if (RegNo > 31)
368     return MCDisassembler::Fail;
369
370   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
371   Inst.addOperand(MCOperand::CreateReg(Reg));
372   return MCDisassembler::Success;
373 }
374
375 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
376                                            unsigned RegNo,
377                                            uint64_t Address,
378                                            const void *Decoder) {
379   Inst.addOperand(MCOperand::CreateReg(RegNo));
380   return MCDisassembler::Success;
381 }
382
383 static DecodeStatus DecodeMem(MCInst &Inst,
384                               unsigned Insn,
385                               uint64_t Address,
386                               const void *Decoder) {
387   int Offset = SignExtend32<16>(Insn & 0xffff);
388   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
389   unsigned Base = fieldFromInstruction(Insn, 21, 5);
390
391   Reg = getReg(Decoder, Mips::CPURegsRegClassID, Reg);
392   Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
393
394   if(Inst.getOpcode() == Mips::SC){
395     Inst.addOperand(MCOperand::CreateReg(Reg));
396   }
397
398   Inst.addOperand(MCOperand::CreateReg(Reg));
399   Inst.addOperand(MCOperand::CreateReg(Base));
400   Inst.addOperand(MCOperand::CreateImm(Offset));
401
402   return MCDisassembler::Success;
403 }
404
405 static DecodeStatus DecodeFMem(MCInst &Inst,
406                                unsigned Insn,
407                                uint64_t Address,
408                                const void *Decoder) {
409   int Offset = SignExtend32<16>(Insn & 0xffff);
410   unsigned Reg = fieldFromInstruction(Insn, 16, 5);
411   unsigned Base = fieldFromInstruction(Insn, 21, 5);
412
413   Reg = getReg(Decoder, Mips::FGR64RegClassID, Reg);
414   Base = getReg(Decoder, Mips::CPURegsRegClassID, Base);
415
416   Inst.addOperand(MCOperand::CreateReg(Reg));
417   Inst.addOperand(MCOperand::CreateReg(Base));
418   Inst.addOperand(MCOperand::CreateImm(Offset));
419
420   return MCDisassembler::Success;
421 }
422
423
424 static DecodeStatus DecodeHWRegsRegisterClass(MCInst &Inst,
425                                               unsigned RegNo,
426                                               uint64_t Address,
427                                               const void *Decoder) {
428   // Currently only hardware register 29 is supported.
429   if (RegNo != 29)
430     return  MCDisassembler::Fail;
431   Inst.addOperand(MCOperand::CreateReg(Mips::HWR29));
432   return MCDisassembler::Success;
433 }
434
435 static DecodeStatus DecodeCondCode(MCInst &Inst,
436                                    unsigned Insn,
437                                    uint64_t Address,
438                                    const void *Decoder) {
439   int CondCode = Insn & 0xf;
440   Inst.addOperand(MCOperand::CreateImm(CondCode));
441   return MCDisassembler::Success;
442 }
443
444 static DecodeStatus DecodeAFGR64RegisterClass(MCInst &Inst,
445                                               unsigned RegNo,
446                                               uint64_t Address,
447                                               const void *Decoder) {
448   if (RegNo > 30 || RegNo %2)
449     return MCDisassembler::Fail;
450
451   ;
452   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
453   Inst.addOperand(MCOperand::CreateReg(Reg));
454   return MCDisassembler::Success;
455 }
456
457 static DecodeStatus DecodeACRegsRegisterClass(MCInst &Inst,
458                                               unsigned RegNo,
459                                               uint64_t Address,
460                                               const void *Decoder) {
461   if (RegNo >= 4)
462     return MCDisassembler::Fail;
463
464   unsigned Reg = getReg(Decoder, Mips::ACRegsRegClassID, RegNo);
465   Inst.addOperand(MCOperand::CreateReg(Reg));
466   return MCDisassembler::Success;
467 }
468
469 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
470                                        unsigned Offset,
471                                        uint64_t Address,
472                                        const void *Decoder) {
473   unsigned BranchOffset = Offset & 0xffff;
474   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
475   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
476   return MCDisassembler::Success;
477 }
478
479 static DecodeStatus DecodeBC1(MCInst &Inst,
480                               unsigned Insn,
481                               uint64_t Address,
482                               const void *Decoder) {
483   unsigned BranchOffset = Insn & 0xffff;
484   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
485   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
486   return MCDisassembler::Success;
487 }
488
489 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
490                                      unsigned Insn,
491                                      uint64_t Address,
492                                      const void *Decoder) {
493
494   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
495   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
496   return MCDisassembler::Success;
497 }
498
499
500 static DecodeStatus DecodeSimm16(MCInst &Inst,
501                                  unsigned Insn,
502                                  uint64_t Address,
503                                  const void *Decoder) {
504   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
505   return MCDisassembler::Success;
506 }
507
508 static DecodeStatus DecodeInsSize(MCInst &Inst,
509                                   unsigned Insn,
510                                   uint64_t Address,
511                                   const void *Decoder) {
512   // First we need to grab the pos(lsb) from MCInst.
513   int Pos = Inst.getOperand(2).getImm();
514   int Size = (int) Insn - Pos + 1;
515   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
516   return MCDisassembler::Success;
517 }
518
519 static DecodeStatus DecodeExtSize(MCInst &Inst,
520                                   unsigned Insn,
521                                   uint64_t Address,
522                                   const void *Decoder) {
523   int Size = (int) Insn  + 1;
524   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
525   return MCDisassembler::Success;
526 }