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