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