[mips] Rename DSPRegs.
[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 DecodeDSPRRegisterClass(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 DecodeACC64DSPRegisterClass(MCInst &Inst,
142                                                 unsigned RegNo,
143                                                 uint64_t Address,
144                                                 const void *Decoder);
145
146 static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
147                                                unsigned RegNo,
148                                                uint64_t Address,
149                                                const void *Decoder);
150
151 static DecodeStatus DecodeLO32DSPRegisterClass(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 DecodeJumpTarget(MCInst &Inst,
162                                      unsigned Insn,
163                                      uint64_t Address,
164                                      const void *Decoder);
165
166 static DecodeStatus DecodeMem(MCInst &Inst,
167                               unsigned Insn,
168                               uint64_t Address,
169                               const void *Decoder);
170
171 static DecodeStatus DecodeFMem(MCInst &Inst, unsigned Insn,
172                                uint64_t Address,
173                                const void *Decoder);
174
175 static DecodeStatus DecodeSimm16(MCInst &Inst,
176                                  unsigned Insn,
177                                  uint64_t Address,
178                                  const void *Decoder);
179
180 static DecodeStatus DecodeInsSize(MCInst &Inst,
181                                   unsigned Insn,
182                                   uint64_t Address,
183                                   const void *Decoder);
184
185 static DecodeStatus DecodeExtSize(MCInst &Inst,
186                                   unsigned Insn,
187                                   uint64_t Address,
188                                   const void *Decoder);
189
190 namespace llvm {
191 extern Target TheMipselTarget, TheMipsTarget, TheMips64Target,
192               TheMips64elTarget;
193 }
194
195 static MCDisassembler *createMipsDisassembler(
196                        const Target &T,
197                        const MCSubtargetInfo &STI) {
198   return new MipsDisassembler(STI, T.createMCRegInfo(""), true);
199 }
200
201 static MCDisassembler *createMipselDisassembler(
202                        const Target &T,
203                        const MCSubtargetInfo &STI) {
204   return new MipsDisassembler(STI, T.createMCRegInfo(""), false);
205 }
206
207 static MCDisassembler *createMips64Disassembler(
208                        const Target &T,
209                        const MCSubtargetInfo &STI) {
210   return new Mips64Disassembler(STI, T.createMCRegInfo(""), true);
211 }
212
213 static MCDisassembler *createMips64elDisassembler(
214                        const Target &T,
215                        const MCSubtargetInfo &STI) {
216   return new Mips64Disassembler(STI, T.createMCRegInfo(""), false);
217 }
218
219 extern "C" void LLVMInitializeMipsDisassembler() {
220   // Register the disassembler.
221   TargetRegistry::RegisterMCDisassembler(TheMipsTarget,
222                                          createMipsDisassembler);
223   TargetRegistry::RegisterMCDisassembler(TheMipselTarget,
224                                          createMipselDisassembler);
225   TargetRegistry::RegisterMCDisassembler(TheMips64Target,
226                                          createMips64Disassembler);
227   TargetRegistry::RegisterMCDisassembler(TheMips64elTarget,
228                                          createMips64elDisassembler);
229 }
230
231
232 #include "MipsGenDisassemblerTables.inc"
233
234   /// readInstruction - read four bytes from the MemoryObject
235   /// and return 32 bit word sorted according to the given endianess
236 static DecodeStatus readInstruction32(const MemoryObject &region,
237                                       uint64_t address,
238                                       uint64_t &size,
239                                       uint32_t &insn,
240                                       bool isBigEndian) {
241   uint8_t Bytes[4];
242
243   // We want to read exactly 4 Bytes of data.
244   if (region.readBytes(address, 4, Bytes) == -1) {
245     size = 0;
246     return MCDisassembler::Fail;
247   }
248
249   if (isBigEndian) {
250     // Encoded as a big-endian 32-bit word in the stream.
251     insn = (Bytes[3] <<  0) |
252            (Bytes[2] <<  8) |
253            (Bytes[1] << 16) |
254            (Bytes[0] << 24);
255   }
256   else {
257     // Encoded as a small-endian 32-bit word in the stream.
258     insn = (Bytes[0] <<  0) |
259            (Bytes[1] <<  8) |
260            (Bytes[2] << 16) |
261            (Bytes[3] << 24);
262   }
263
264   return MCDisassembler::Success;
265 }
266
267 DecodeStatus
268 MipsDisassembler::getInstruction(MCInst &instr,
269                                  uint64_t &Size,
270                                  const MemoryObject &Region,
271                                  uint64_t Address,
272                                  raw_ostream &vStream,
273                                  raw_ostream &cStream) const {
274   uint32_t Insn;
275
276   DecodeStatus Result = readInstruction32(Region, Address, Size,
277                                           Insn, isBigEndian);
278   if (Result == MCDisassembler::Fail)
279     return MCDisassembler::Fail;
280
281   // Calling the auto-generated decoder function.
282   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
283                              this, STI);
284   if (Result != MCDisassembler::Fail) {
285     Size = 4;
286     return Result;
287   }
288
289   return MCDisassembler::Fail;
290 }
291
292 DecodeStatus
293 Mips64Disassembler::getInstruction(MCInst &instr,
294                                    uint64_t &Size,
295                                    const MemoryObject &Region,
296                                    uint64_t Address,
297                                    raw_ostream &vStream,
298                                    raw_ostream &cStream) const {
299   uint32_t Insn;
300
301   DecodeStatus Result = readInstruction32(Region, Address, Size,
302                                           Insn, isBigEndian);
303   if (Result == MCDisassembler::Fail)
304     return MCDisassembler::Fail;
305
306   // Calling the auto-generated decoder function.
307   Result = decodeInstruction(DecoderTableMips6432, instr, Insn, Address,
308                              this, STI);
309   if (Result != MCDisassembler::Fail) {
310     Size = 4;
311     return Result;
312   }
313   // If we fail to decode in Mips64 decoder space we can try in Mips32
314   Result = decodeInstruction(DecoderTableMips32, instr, Insn, Address,
315                              this, STI);
316   if (Result != MCDisassembler::Fail) {
317     Size = 4;
318     return Result;
319   }
320
321   return MCDisassembler::Fail;
322 }
323
324 static unsigned getReg(const void *D, unsigned RC, unsigned RegNo) {
325   const MipsDisassemblerBase *Dis = static_cast<const MipsDisassemblerBase*>(D);
326   return *(Dis->getRegInfo()->getRegClass(RC).begin() + RegNo);
327 }
328
329 static DecodeStatus DecodeCPU16RegsRegisterClass(MCInst &Inst,
330                                                  unsigned RegNo,
331                                                  uint64_t Address,
332                                                  const void *Decoder) {
333
334   return MCDisassembler::Fail;
335
336 }
337
338 static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst,
339                                              unsigned RegNo,
340                                              uint64_t Address,
341                                              const void *Decoder) {
342
343   if (RegNo > 31)
344     return MCDisassembler::Fail;
345
346   unsigned Reg = getReg(Decoder, Mips::GPR64RegClassID, RegNo);
347   Inst.addOperand(MCOperand::CreateReg(Reg));
348   return MCDisassembler::Success;
349 }
350
351 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst,
352                                              unsigned RegNo,
353                                              uint64_t Address,
354                                              const void *Decoder) {
355   if (RegNo > 31)
356     return MCDisassembler::Fail;
357   unsigned Reg = getReg(Decoder, Mips::GPR32RegClassID, RegNo);
358   Inst.addOperand(MCOperand::CreateReg(Reg));
359   return MCDisassembler::Success;
360 }
361
362 static DecodeStatus DecodeDSPRRegisterClass(MCInst &Inst,
363                                             unsigned RegNo,
364                                             uint64_t Address,
365                                             const void *Decoder) {
366   return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
367 }
368
369 static DecodeStatus DecodeFGR64RegisterClass(MCInst &Inst,
370                                              unsigned RegNo,
371                                              uint64_t Address,
372                                              const void *Decoder) {
373   if (RegNo > 31)
374     return MCDisassembler::Fail;
375
376   unsigned Reg = getReg(Decoder, Mips::FGR64RegClassID, RegNo);
377   Inst.addOperand(MCOperand::CreateReg(Reg));
378   return MCDisassembler::Success;
379 }
380
381 static DecodeStatus DecodeFGR32RegisterClass(MCInst &Inst,
382                                              unsigned RegNo,
383                                              uint64_t Address,
384                                              const void *Decoder) {
385   if (RegNo > 31)
386     return MCDisassembler::Fail;
387
388   unsigned Reg = getReg(Decoder, Mips::FGR32RegClassID, RegNo);
389   Inst.addOperand(MCOperand::CreateReg(Reg));
390   return MCDisassembler::Success;
391 }
392
393 static DecodeStatus DecodeCCRRegisterClass(MCInst &Inst,
394                                            unsigned RegNo,
395                                            uint64_t Address,
396                                            const void *Decoder) {
397   if (RegNo > 31)
398     return MCDisassembler::Fail;
399   unsigned Reg = getReg(Decoder, Mips::CCRRegClassID, RegNo);
400   Inst.addOperand(MCOperand::CreateReg(Reg));
401   return MCDisassembler::Success;
402 }
403
404 static DecodeStatus DecodeFCCRegisterClass(MCInst &Inst,
405                                            unsigned RegNo,
406                                            uint64_t Address,
407                                            const void *Decoder) {
408   if (RegNo > 7)
409     return MCDisassembler::Fail;
410   unsigned Reg = getReg(Decoder, Mips::FCCRegClassID, 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::GPR32RegClassID, Reg);
424   Base = getReg(Decoder, Mips::GPR32RegClassID, 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::GPR32RegClassID, 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 DecodeAFGR64RegisterClass(MCInst &Inst,
468                                               unsigned RegNo,
469                                               uint64_t Address,
470                                               const void *Decoder) {
471   if (RegNo > 30 || RegNo %2)
472     return MCDisassembler::Fail;
473
474   ;
475   unsigned Reg = getReg(Decoder, Mips::AFGR64RegClassID, RegNo /2);
476   Inst.addOperand(MCOperand::CreateReg(Reg));
477   return MCDisassembler::Success;
478 }
479
480 static DecodeStatus DecodeACC64DSPRegisterClass(MCInst &Inst,
481                                                 unsigned RegNo,
482                                                 uint64_t Address,
483                                                 const void *Decoder) {
484   if (RegNo >= 4)
485     return MCDisassembler::Fail;
486
487   unsigned Reg = getReg(Decoder, Mips::ACC64DSPRegClassID, RegNo);
488   Inst.addOperand(MCOperand::CreateReg(Reg));
489   return MCDisassembler::Success;
490 }
491
492 static DecodeStatus DecodeHI32DSPRegisterClass(MCInst &Inst,
493                                                unsigned RegNo,
494                                                uint64_t Address,
495                                                const void *Decoder) {
496   if (RegNo >= 4)
497     return MCDisassembler::Fail;
498
499   unsigned Reg = getReg(Decoder, Mips::HI32DSPRegClassID, RegNo);
500   Inst.addOperand(MCOperand::CreateReg(Reg));
501   return MCDisassembler::Success;
502 }
503
504 static DecodeStatus DecodeLO32DSPRegisterClass(MCInst &Inst,
505                                                unsigned RegNo,
506                                                uint64_t Address,
507                                                const void *Decoder) {
508   if (RegNo >= 4)
509     return MCDisassembler::Fail;
510
511   unsigned Reg = getReg(Decoder, Mips::LO32DSPRegClassID, RegNo);
512   Inst.addOperand(MCOperand::CreateReg(Reg));
513   return MCDisassembler::Success;
514 }
515
516 static DecodeStatus DecodeBranchTarget(MCInst &Inst,
517                                        unsigned Offset,
518                                        uint64_t Address,
519                                        const void *Decoder) {
520   unsigned BranchOffset = Offset & 0xffff;
521   BranchOffset = SignExtend32<18>(BranchOffset << 2) + 4;
522   Inst.addOperand(MCOperand::CreateImm(BranchOffset));
523   return MCDisassembler::Success;
524 }
525
526 static DecodeStatus DecodeJumpTarget(MCInst &Inst,
527                                      unsigned Insn,
528                                      uint64_t Address,
529                                      const void *Decoder) {
530
531   unsigned JumpOffset = fieldFromInstruction(Insn, 0, 26) << 2;
532   Inst.addOperand(MCOperand::CreateImm(JumpOffset));
533   return MCDisassembler::Success;
534 }
535
536
537 static DecodeStatus DecodeSimm16(MCInst &Inst,
538                                  unsigned Insn,
539                                  uint64_t Address,
540                                  const void *Decoder) {
541   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Insn)));
542   return MCDisassembler::Success;
543 }
544
545 static DecodeStatus DecodeInsSize(MCInst &Inst,
546                                   unsigned Insn,
547                                   uint64_t Address,
548                                   const void *Decoder) {
549   // First we need to grab the pos(lsb) from MCInst.
550   int Pos = Inst.getOperand(2).getImm();
551   int Size = (int) Insn - Pos + 1;
552   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
553   return MCDisassembler::Success;
554 }
555
556 static DecodeStatus DecodeExtSize(MCInst &Inst,
557                                   unsigned Insn,
558                                   uint64_t Address,
559                                   const void *Decoder) {
560   int Size = (int) Insn  + 1;
561   Inst.addOperand(MCOperand::CreateImm(SignExtend32<16>(Size)));
562   return MCDisassembler::Success;
563 }