Add support for the Sparc implementation-defined "ASR" registers.
[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   unsigned rs2 = 0;
283   unsigned simm13 = 0;
284   if (isImm)
285     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
286   else
287     rs2 = fieldFromInstruction(insn, 0, 5);
288
289   DecodeStatus status;
290   if (isLoad) {
291     status = DecodeRD(MI, rd, Address, Decoder);
292     if (status != MCDisassembler::Success)
293       return status;
294   }
295
296   // Decode rs1.
297   status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
298   if (status != MCDisassembler::Success)
299     return status;
300
301   // Decode imm|rs2.
302   if (isImm)
303     MI.addOperand(MCOperand::createImm(simm13));
304   else {
305     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
306     if (status != MCDisassembler::Success)
307       return status;
308   }
309
310   if (!isLoad) {
311     status = DecodeRD(MI, rd, Address, Decoder);
312     if (status != MCDisassembler::Success)
313       return status;
314   }
315   return MCDisassembler::Success;
316 }
317
318 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
319                                   const void *Decoder) {
320   return DecodeMem(Inst, insn, Address, Decoder, true,
321                    DecodeIntRegsRegisterClass);
322 }
323
324 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
325                                  const void *Decoder) {
326   return DecodeMem(Inst, insn, Address, Decoder, true,
327                    DecodeFPRegsRegisterClass);
328 }
329
330 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
331                                   const void *Decoder) {
332   return DecodeMem(Inst, insn, Address, Decoder, true,
333                    DecodeDFPRegsRegisterClass);
334 }
335
336 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
337                                   const void *Decoder) {
338   return DecodeMem(Inst, insn, Address, Decoder, true,
339                    DecodeQFPRegsRegisterClass);
340 }
341
342 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
343                                    uint64_t Address, const void *Decoder) {
344   return DecodeMem(Inst, insn, Address, Decoder, false,
345                    DecodeIntRegsRegisterClass);
346 }
347
348 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address,
349                                   const void *Decoder) {
350   return DecodeMem(Inst, insn, Address, Decoder, false,
351                    DecodeFPRegsRegisterClass);
352 }
353
354 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
355                                    uint64_t Address, const void *Decoder) {
356   return DecodeMem(Inst, insn, Address, Decoder, false,
357                    DecodeDFPRegsRegisterClass);
358 }
359
360 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
361                                    uint64_t Address, const void *Decoder) {
362   return DecodeMem(Inst, insn, Address, Decoder, false,
363                    DecodeQFPRegsRegisterClass);
364 }
365
366 static bool tryAddingSymbolicOperand(int64_t Value,  bool isBranch,
367                                      uint64_t Address, uint64_t Offset,
368                                      uint64_t Width, MCInst &MI,
369                                      const void *Decoder) {
370   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
371   return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
372                                        Offset, Width);
373 }
374
375 static DecodeStatus DecodeCall(MCInst &MI, unsigned insn,
376                                uint64_t Address, const void *Decoder) {
377   unsigned tgt = fieldFromInstruction(insn, 0, 30);
378   tgt <<= 2;
379   if (!tryAddingSymbolicOperand(tgt+Address, false, Address,
380                                 0, 30, MI, Decoder))
381     MI.addOperand(MCOperand::createImm(tgt));
382   return MCDisassembler::Success;
383 }
384
385 static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn,
386                                  uint64_t Address, const void *Decoder) {
387   unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
388   MI.addOperand(MCOperand::createImm(tgt));
389   return MCDisassembler::Success;
390 }
391
392 static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address,
393                                const void *Decoder) {
394
395   unsigned rd = fieldFromInstruction(insn, 25, 5);
396   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
397   unsigned isImm = fieldFromInstruction(insn, 13, 1);
398   unsigned rs2 = 0;
399   unsigned simm13 = 0;
400   if (isImm)
401     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
402   else
403     rs2 = fieldFromInstruction(insn, 0, 5);
404
405   // Decode RD.
406   DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
407   if (status != MCDisassembler::Success)
408     return status;
409
410   // Decode RS1.
411   status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
412   if (status != MCDisassembler::Success)
413     return status;
414
415   // Decode RS1 | SIMM13.
416   if (isImm)
417     MI.addOperand(MCOperand::createImm(simm13));
418   else {
419     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
420     if (status != MCDisassembler::Success)
421       return status;
422   }
423   return MCDisassembler::Success;
424 }
425
426 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
427                                  const void *Decoder) {
428
429   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
430   unsigned isImm = fieldFromInstruction(insn, 13, 1);
431   unsigned rs2 = 0;
432   unsigned simm13 = 0;
433   if (isImm)
434     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
435   else
436     rs2 = fieldFromInstruction(insn, 0, 5);
437
438   // Decode RS1.
439   DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
440   if (status != MCDisassembler::Success)
441     return status;
442
443   // Decode RS2 | SIMM13.
444   if (isImm)
445     MI.addOperand(MCOperand::createImm(simm13));
446   else {
447     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
448     if (status != MCDisassembler::Success)
449       return status;
450   }
451   return MCDisassembler::Success;
452 }
453
454 static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address,
455                                const void *Decoder) {
456
457   unsigned rd = fieldFromInstruction(insn, 25, 5);
458   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
459   unsigned isImm = fieldFromInstruction(insn, 13, 1);
460   unsigned rs2 = 0;
461   unsigned simm13 = 0;
462   if (isImm)
463     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
464   else
465     rs2 = fieldFromInstruction(insn, 0, 5);
466
467   // Decode RD.
468   DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
469   if (status != MCDisassembler::Success)
470     return status;
471
472   // Decode RS1.
473   status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
474   if (status != MCDisassembler::Success)
475     return status;
476
477   // Decode RS1 | SIMM13.
478   if (isImm)
479     MI.addOperand(MCOperand::createImm(simm13));
480   else {
481     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
482     if (status != MCDisassembler::Success)
483       return status;
484   }
485   return MCDisassembler::Success;
486 }