3e56b9e9b8837dcd235949606fdef1d3934247bd
[oota-llvm.git] / lib / Target / Sparc / Disassembler / SparcDisassembler.cpp
1 //===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- 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 Sparc Disassembler.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "Sparc.h"
15 #include "SparcRegisterInfo.h"
16 #include "SparcSubtarget.h"
17 #include "llvm/MC/MCDisassembler.h"
18 #include "llvm/MC/MCFixedLenDisassembler.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCAsmInfo.h"
22 #include "llvm/Support/TargetRegistry.h"
23
24 using namespace llvm;
25
26 #define DEBUG_TYPE "sparc-disassembler"
27
28 typedef MCDisassembler::DecodeStatus DecodeStatus;
29
30 namespace {
31
32 /// A disassembler class for Sparc.
33 class SparcDisassembler : public MCDisassembler {
34 public:
35   SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
36       : MCDisassembler(STI, Ctx) {}
37   virtual ~SparcDisassembler() {}
38
39   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
40                               ArrayRef<uint8_t> Bytes, uint64_t Address,
41                               raw_ostream &VStream,
42                               raw_ostream &CStream) const override;
43 };
44 }
45
46 namespace llvm {
47 extern Target TheSparcTarget, TheSparcV9Target, TheSparcelTarget;
48 }
49
50 static MCDisassembler *createSparcDisassembler(const Target &T,
51                                                const MCSubtargetInfo &STI,
52                                                MCContext &Ctx) {
53   return new SparcDisassembler(STI, Ctx);
54 }
55
56
57 extern "C" void LLVMInitializeSparcDisassembler() {
58   // Register the disassembler.
59   TargetRegistry::RegisterMCDisassembler(TheSparcTarget,
60                                          createSparcDisassembler);
61   TargetRegistry::RegisterMCDisassembler(TheSparcV9Target,
62                                          createSparcDisassembler);
63   TargetRegistry::RegisterMCDisassembler(TheSparcelTarget,
64                                          createSparcDisassembler);
65 }
66
67 static const unsigned IntRegDecoderTable[] = {
68   SP::G0,  SP::G1,  SP::G2,  SP::G3,
69   SP::G4,  SP::G5,  SP::G6,  SP::G7,
70   SP::O0,  SP::O1,  SP::O2,  SP::O3,
71   SP::O4,  SP::O5,  SP::O6,  SP::O7,
72   SP::L0,  SP::L1,  SP::L2,  SP::L3,
73   SP::L4,  SP::L5,  SP::L6,  SP::L7,
74   SP::I0,  SP::I1,  SP::I2,  SP::I3,
75   SP::I4,  SP::I5,  SP::I6,  SP::I7 };
76
77 static const unsigned FPRegDecoderTable[] = {
78   SP::F0,   SP::F1,   SP::F2,   SP::F3,
79   SP::F4,   SP::F5,   SP::F6,   SP::F7,
80   SP::F8,   SP::F9,   SP::F10,  SP::F11,
81   SP::F12,  SP::F13,  SP::F14,  SP::F15,
82   SP::F16,  SP::F17,  SP::F18,  SP::F19,
83   SP::F20,  SP::F21,  SP::F22,  SP::F23,
84   SP::F24,  SP::F25,  SP::F26,  SP::F27,
85   SP::F28,  SP::F29,  SP::F30,  SP::F31 };
86
87 static const unsigned DFPRegDecoderTable[] = {
88   SP::D0,   SP::D16,  SP::D1,   SP::D17,
89   SP::D2,   SP::D18,  SP::D3,   SP::D19,
90   SP::D4,   SP::D20,  SP::D5,   SP::D21,
91   SP::D6,   SP::D22,  SP::D7,   SP::D23,
92   SP::D8,   SP::D24,  SP::D9,   SP::D25,
93   SP::D10,  SP::D26,  SP::D11,  SP::D27,
94   SP::D12,  SP::D28,  SP::D13,  SP::D29,
95   SP::D14,  SP::D30,  SP::D15,  SP::D31 };
96
97 static const unsigned QFPRegDecoderTable[] = {
98   SP::Q0,  SP::Q8,   ~0U,  ~0U,
99   SP::Q1,  SP::Q9,   ~0U,  ~0U,
100   SP::Q2,  SP::Q10,  ~0U,  ~0U,
101   SP::Q3,  SP::Q11,  ~0U,  ~0U,
102   SP::Q4,  SP::Q12,  ~0U,  ~0U,
103   SP::Q5,  SP::Q13,  ~0U,  ~0U,
104   SP::Q6,  SP::Q14,  ~0U,  ~0U,
105   SP::Q7,  SP::Q15,  ~0U,  ~0U } ;
106
107 static const unsigned FCCRegDecoderTable[] = {
108   SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 };
109
110 static const unsigned ASRRegDecoderTable[] = {
111   SP::Y,     SP::ASR1,  SP::ASR2,  SP::ASR3,
112   SP::ASR4,  SP::ASR5,  SP::ASR6,  SP::ASR7,
113   SP::ASR8,  SP::ASR9,  SP::ASR10, SP::ASR11,
114   SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
115   SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
116   SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
117   SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
118   SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
119
120 static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,
121                                                unsigned RegNo,
122                                                uint64_t Address,
123                                                const void *Decoder) {
124   if (RegNo > 31)
125     return MCDisassembler::Fail;
126   unsigned Reg = IntRegDecoderTable[RegNo];
127   Inst.addOperand(MCOperand::createReg(Reg));
128   return MCDisassembler::Success;
129 }
130
131 static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst,
132                                                unsigned RegNo,
133                                                uint64_t Address,
134                                                const void *Decoder) {
135   if (RegNo > 31)
136     return MCDisassembler::Fail;
137   unsigned Reg = IntRegDecoderTable[RegNo];
138   Inst.addOperand(MCOperand::createReg(Reg));
139   return MCDisassembler::Success;
140 }
141
142
143 static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst,
144                                               unsigned RegNo,
145                                               uint64_t Address,
146                                               const void *Decoder) {
147   if (RegNo > 31)
148     return MCDisassembler::Fail;
149   unsigned Reg = FPRegDecoderTable[RegNo];
150   Inst.addOperand(MCOperand::createReg(Reg));
151   return MCDisassembler::Success;
152 }
153
154
155 static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst,
156                                                unsigned RegNo,
157                                                uint64_t Address,
158                                                const void *Decoder) {
159   if (RegNo > 31)
160     return MCDisassembler::Fail;
161   unsigned Reg = DFPRegDecoderTable[RegNo];
162   Inst.addOperand(MCOperand::createReg(Reg));
163   return MCDisassembler::Success;
164 }
165
166
167 static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst,
168                                                unsigned RegNo,
169                                                uint64_t Address,
170                                                const void *Decoder) {
171   if (RegNo > 31)
172     return MCDisassembler::Fail;
173
174   unsigned Reg = QFPRegDecoderTable[RegNo];
175   if (Reg == ~0U)
176     return MCDisassembler::Fail;
177   Inst.addOperand(MCOperand::createReg(Reg));
178   return MCDisassembler::Success;
179 }
180
181 static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo,
182                                                uint64_t Address,
183                                                const void *Decoder) {
184   if (RegNo > 3)
185     return MCDisassembler::Fail;
186   Inst.addOperand(MCOperand::createReg(FCCRegDecoderTable[RegNo]));
187   return MCDisassembler::Success;
188 }
189
190 static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo,
191                                                uint64_t Address,
192                                                const void *Decoder) {
193   if (RegNo > 31)
194     return MCDisassembler::Fail;
195   Inst.addOperand(MCOperand::createReg(ASRRegDecoderTable[RegNo]));
196   return MCDisassembler::Success;
197 }
198
199
200 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
201                                   const void *Decoder);
202 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
203                                  const void *Decoder);
204 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
205                                   const void *Decoder);
206 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
207                                   const void *Decoder);
208 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
209                                    uint64_t Address, const void *Decoder);
210 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn,
211                                   uint64_t Address, const void *Decoder);
212 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
213                                    uint64_t Address, const void *Decoder);
214 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
215                                    uint64_t Address, const void *Decoder);
216 static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn,
217                                uint64_t Address, const void *Decoder);
218 static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn,
219                                  uint64_t Address, const void *Decoder);
220 static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address,
221                                const void *Decoder);
222 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
223                                  const void *Decoder);
224 static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address,
225                                const void *Decoder);
226
227 #include "SparcGenDisassemblerTables.inc"
228
229 /// Read four bytes from the ArrayRef and return 32 bit word.
230 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
231                                       uint64_t &Size, uint32_t &Insn,
232                                       bool IsLittleEndian) {
233   // We want to read exactly 4 Bytes of data.
234   if (Bytes.size() < 4) {
235     Size = 0;
236     return MCDisassembler::Fail;
237   }
238
239   Insn = IsLittleEndian
240              ? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
241                    (Bytes[3] << 24)
242              : (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) |
243                    (Bytes[0] << 24);
244
245   return MCDisassembler::Success;
246 }
247
248 DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
249                                                ArrayRef<uint8_t> Bytes,
250                                                uint64_t Address,
251                                                raw_ostream &VStream,
252                                                raw_ostream &CStream) const {
253   uint32_t Insn;
254   bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian();
255   DecodeStatus Result =
256       readInstruction32(Bytes, Address, Size, Insn, isLittleEndian);
257   if (Result == MCDisassembler::Fail)
258     return MCDisassembler::Fail;
259
260   // Calling the auto-generated decoder function.
261   Result =
262       decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI);
263
264   if (Result != MCDisassembler::Fail) {
265     Size = 4;
266     return Result;
267   }
268
269   return MCDisassembler::Fail;
270 }
271
272
273 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
274                                    const void *Decoder);
275
276 static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address,
277                               const void *Decoder,
278                               bool isLoad, DecodeFunc DecodeRD) {
279   unsigned rd = fieldFromInstruction(insn, 25, 5);
280   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
281   bool isImm = fieldFromInstruction(insn, 13, 1);
282   bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field)
283   unsigned asi = fieldFromInstruction(insn, 5, 8);
284   unsigned rs2 = 0;
285   unsigned simm13 = 0;
286   if (isImm)
287     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
288   else
289     rs2 = fieldFromInstruction(insn, 0, 5);
290
291   DecodeStatus status;
292   if (isLoad) {
293     status = DecodeRD(MI, rd, Address, Decoder);
294     if (status != MCDisassembler::Success)
295       return status;
296   }
297
298   // Decode rs1.
299   status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
300   if (status != MCDisassembler::Success)
301     return status;
302
303   // Decode imm|rs2.
304   if (isImm)
305     MI.addOperand(MCOperand::createImm(simm13));
306   else {
307     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
308     if (status != MCDisassembler::Success)
309       return status;
310   }
311
312   if (hasAsi)
313     MI.addOperand(MCOperand::createImm(asi));
314
315   if (!isLoad) {
316     status = DecodeRD(MI, rd, Address, Decoder);
317     if (status != MCDisassembler::Success)
318       return status;
319   }
320   return MCDisassembler::Success;
321 }
322
323 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
324                                   const void *Decoder) {
325   return DecodeMem(Inst, insn, Address, Decoder, true,
326                    DecodeIntRegsRegisterClass);
327 }
328
329 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
330                                  const void *Decoder) {
331   return DecodeMem(Inst, insn, Address, Decoder, true,
332                    DecodeFPRegsRegisterClass);
333 }
334
335 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
336                                   const void *Decoder) {
337   return DecodeMem(Inst, insn, Address, Decoder, true,
338                    DecodeDFPRegsRegisterClass);
339 }
340
341 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
342                                   const void *Decoder) {
343   return DecodeMem(Inst, insn, Address, Decoder, true,
344                    DecodeQFPRegsRegisterClass);
345 }
346
347 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
348                                    uint64_t Address, const void *Decoder) {
349   return DecodeMem(Inst, insn, Address, Decoder, false,
350                    DecodeIntRegsRegisterClass);
351 }
352
353 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address,
354                                   const void *Decoder) {
355   return DecodeMem(Inst, insn, Address, Decoder, false,
356                    DecodeFPRegsRegisterClass);
357 }
358
359 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
360                                    uint64_t Address, const void *Decoder) {
361   return DecodeMem(Inst, insn, Address, Decoder, false,
362                    DecodeDFPRegsRegisterClass);
363 }
364
365 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
366                                    uint64_t Address, const void *Decoder) {
367   return DecodeMem(Inst, insn, Address, Decoder, false,
368                    DecodeQFPRegsRegisterClass);
369 }
370
371 static bool tryAddingSymbolicOperand(int64_t Value,  bool isBranch,
372                                      uint64_t Address, uint64_t Offset,
373                                      uint64_t Width, MCInst &MI,
374                                      const void *Decoder) {
375   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
376   return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
377                                        Offset, Width);
378 }
379
380 static DecodeStatus DecodeCall(MCInst &MI, unsigned insn,
381                                uint64_t Address, const void *Decoder) {
382   unsigned tgt = fieldFromInstruction(insn, 0, 30);
383   tgt <<= 2;
384   if (!tryAddingSymbolicOperand(tgt+Address, false, Address,
385                                 0, 30, MI, Decoder))
386     MI.addOperand(MCOperand::createImm(tgt));
387   return MCDisassembler::Success;
388 }
389
390 static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn,
391                                  uint64_t Address, const void *Decoder) {
392   unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
393   MI.addOperand(MCOperand::createImm(tgt));
394   return MCDisassembler::Success;
395 }
396
397 static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address,
398                                const void *Decoder) {
399
400   unsigned rd = fieldFromInstruction(insn, 25, 5);
401   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
402   unsigned isImm = fieldFromInstruction(insn, 13, 1);
403   unsigned rs2 = 0;
404   unsigned simm13 = 0;
405   if (isImm)
406     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
407   else
408     rs2 = fieldFromInstruction(insn, 0, 5);
409
410   // Decode RD.
411   DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
412   if (status != MCDisassembler::Success)
413     return status;
414
415   // Decode RS1.
416   status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
417   if (status != MCDisassembler::Success)
418     return status;
419
420   // Decode RS1 | SIMM13.
421   if (isImm)
422     MI.addOperand(MCOperand::createImm(simm13));
423   else {
424     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
425     if (status != MCDisassembler::Success)
426       return status;
427   }
428   return MCDisassembler::Success;
429 }
430
431 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
432                                  const void *Decoder) {
433
434   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
435   unsigned isImm = fieldFromInstruction(insn, 13, 1);
436   unsigned rs2 = 0;
437   unsigned simm13 = 0;
438   if (isImm)
439     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
440   else
441     rs2 = fieldFromInstruction(insn, 0, 5);
442
443   // Decode RS1.
444   DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
445   if (status != MCDisassembler::Success)
446     return status;
447
448   // Decode RS2 | SIMM13.
449   if (isImm)
450     MI.addOperand(MCOperand::createImm(simm13));
451   else {
452     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
453     if (status != MCDisassembler::Success)
454       return status;
455   }
456   return MCDisassembler::Success;
457 }
458
459 static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address,
460                                const void *Decoder) {
461
462   unsigned rd = fieldFromInstruction(insn, 25, 5);
463   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
464   unsigned isImm = fieldFromInstruction(insn, 13, 1);
465   bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field)
466   unsigned asi = fieldFromInstruction(insn, 5, 8);
467   unsigned rs2 = 0;
468   unsigned simm13 = 0;
469   if (isImm)
470     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
471   else
472     rs2 = fieldFromInstruction(insn, 0, 5);
473
474   // Decode RD.
475   DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
476   if (status != MCDisassembler::Success)
477     return status;
478
479   // Decode RS1.
480   status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
481   if (status != MCDisassembler::Success)
482     return status;
483
484   // Decode RS1 | SIMM13.
485   if (isImm)
486     MI.addOperand(MCOperand::createImm(simm13));
487   else {
488     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
489     if (status != MCDisassembler::Success)
490       return status;
491   }
492
493   if (hasAsi)
494     MI.addOperand(MCOperand::createImm(asi));
495
496   return MCDisassembler::Success;
497 }