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