[Sparc] Implement i64 load/store support for 32-bit sparc.
[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 const uint16_t IntPairDecoderTable[] = {
121   SP::G0_G1, SP::G2_G3, SP::G4_G5, SP::G6_G7,
122   SP::O0_O1, SP::O2_O3, SP::O4_O5, SP::O6_O7,
123   SP::L0_L1, SP::L2_L3, SP::L4_L5, SP::L6_L7,
124   SP::I0_I1, SP::I2_I3, SP::I4_I5, SP::I6_I7,
125 };
126
127 static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst,
128                                                unsigned RegNo,
129                                                uint64_t Address,
130                                                const void *Decoder) {
131   if (RegNo > 31)
132     return MCDisassembler::Fail;
133   unsigned Reg = IntRegDecoderTable[RegNo];
134   Inst.addOperand(MCOperand::createReg(Reg));
135   return MCDisassembler::Success;
136 }
137
138 static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst,
139                                                unsigned RegNo,
140                                                uint64_t Address,
141                                                const void *Decoder) {
142   if (RegNo > 31)
143     return MCDisassembler::Fail;
144   unsigned Reg = IntRegDecoderTable[RegNo];
145   Inst.addOperand(MCOperand::createReg(Reg));
146   return MCDisassembler::Success;
147 }
148
149
150 static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst,
151                                               unsigned RegNo,
152                                               uint64_t Address,
153                                               const void *Decoder) {
154   if (RegNo > 31)
155     return MCDisassembler::Fail;
156   unsigned Reg = FPRegDecoderTable[RegNo];
157   Inst.addOperand(MCOperand::createReg(Reg));
158   return MCDisassembler::Success;
159 }
160
161
162 static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst,
163                                                unsigned RegNo,
164                                                uint64_t Address,
165                                                const void *Decoder) {
166   if (RegNo > 31)
167     return MCDisassembler::Fail;
168   unsigned Reg = DFPRegDecoderTable[RegNo];
169   Inst.addOperand(MCOperand::createReg(Reg));
170   return MCDisassembler::Success;
171 }
172
173
174 static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst,
175                                                unsigned RegNo,
176                                                uint64_t Address,
177                                                const void *Decoder) {
178   if (RegNo > 31)
179     return MCDisassembler::Fail;
180
181   unsigned Reg = QFPRegDecoderTable[RegNo];
182   if (Reg == ~0U)
183     return MCDisassembler::Fail;
184   Inst.addOperand(MCOperand::createReg(Reg));
185   return MCDisassembler::Success;
186 }
187
188 static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo,
189                                                uint64_t Address,
190                                                const void *Decoder) {
191   if (RegNo > 3)
192     return MCDisassembler::Fail;
193   Inst.addOperand(MCOperand::createReg(FCCRegDecoderTable[RegNo]));
194   return MCDisassembler::Success;
195 }
196
197 static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo,
198                                                uint64_t Address,
199                                                const void *Decoder) {
200   if (RegNo > 31)
201     return MCDisassembler::Fail;
202   Inst.addOperand(MCOperand::createReg(ASRRegDecoderTable[RegNo]));
203   return MCDisassembler::Success;
204 }
205
206 static DecodeStatus DecodeIntPairRegisterClass(MCInst &Inst, unsigned RegNo,
207                                    uint64_t Address, const void *Decoder) {
208   DecodeStatus S = MCDisassembler::Success;
209
210   if (RegNo > 31)
211     return MCDisassembler::Fail;
212
213   if ((RegNo & 1))
214     S = MCDisassembler::SoftFail;
215
216   unsigned RegisterPair = IntPairDecoderTable[RegNo/2];
217   Inst.addOperand(MCOperand::createReg(RegisterPair));
218   return S;
219 }
220
221 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
222                                   const void *Decoder);
223 static DecodeStatus DecodeLoadIntPair(MCInst &Inst, unsigned insn, uint64_t Address,
224                                   const void *Decoder);
225 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
226                                  const void *Decoder);
227 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
228                                   const void *Decoder);
229 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
230                                   const void *Decoder);
231 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
232                                    uint64_t Address, const void *Decoder);
233 static DecodeStatus DecodeStoreIntPair(MCInst &Inst, unsigned insn,
234                                    uint64_t Address, const void *Decoder);
235 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn,
236                                   uint64_t Address, const void *Decoder);
237 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
238                                    uint64_t Address, const void *Decoder);
239 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
240                                    uint64_t Address, const void *Decoder);
241 static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn,
242                                uint64_t Address, const void *Decoder);
243 static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn,
244                                  uint64_t Address, const void *Decoder);
245 static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address,
246                                const void *Decoder);
247 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
248                                  const void *Decoder);
249 static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address,
250                                const void *Decoder);
251
252 #include "SparcGenDisassemblerTables.inc"
253
254 /// Read four bytes from the ArrayRef and return 32 bit word.
255 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
256                                       uint64_t &Size, uint32_t &Insn,
257                                       bool IsLittleEndian) {
258   // We want to read exactly 4 Bytes of data.
259   if (Bytes.size() < 4) {
260     Size = 0;
261     return MCDisassembler::Fail;
262   }
263
264   Insn = IsLittleEndian
265              ? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
266                    (Bytes[3] << 24)
267              : (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) |
268                    (Bytes[0] << 24);
269
270   return MCDisassembler::Success;
271 }
272
273 DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
274                                                ArrayRef<uint8_t> Bytes,
275                                                uint64_t Address,
276                                                raw_ostream &VStream,
277                                                raw_ostream &CStream) const {
278   uint32_t Insn;
279   bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian();
280   DecodeStatus Result =
281       readInstruction32(Bytes, Address, Size, Insn, isLittleEndian);
282   if (Result == MCDisassembler::Fail)
283     return MCDisassembler::Fail;
284
285   // Calling the auto-generated decoder function.
286   Result =
287       decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI);
288
289   if (Result != MCDisassembler::Fail) {
290     Size = 4;
291     return Result;
292   }
293
294   return MCDisassembler::Fail;
295 }
296
297
298 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
299                                    const void *Decoder);
300
301 static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address,
302                               const void *Decoder,
303                               bool isLoad, DecodeFunc DecodeRD) {
304   unsigned rd = fieldFromInstruction(insn, 25, 5);
305   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
306   bool isImm = fieldFromInstruction(insn, 13, 1);
307   bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field)
308   unsigned asi = fieldFromInstruction(insn, 5, 8);
309   unsigned rs2 = 0;
310   unsigned simm13 = 0;
311   if (isImm)
312     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
313   else
314     rs2 = fieldFromInstruction(insn, 0, 5);
315
316   DecodeStatus status;
317   if (isLoad) {
318     status = DecodeRD(MI, rd, Address, Decoder);
319     if (status != MCDisassembler::Success)
320       return status;
321   }
322
323   // Decode rs1.
324   status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
325   if (status != MCDisassembler::Success)
326     return status;
327
328   // Decode imm|rs2.
329   if (isImm)
330     MI.addOperand(MCOperand::createImm(simm13));
331   else {
332     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
333     if (status != MCDisassembler::Success)
334       return status;
335   }
336
337   if (hasAsi)
338     MI.addOperand(MCOperand::createImm(asi));
339
340   if (!isLoad) {
341     status = DecodeRD(MI, rd, Address, Decoder);
342     if (status != MCDisassembler::Success)
343       return status;
344   }
345   return MCDisassembler::Success;
346 }
347
348 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
349                                   const void *Decoder) {
350   return DecodeMem(Inst, insn, Address, Decoder, true,
351                    DecodeIntRegsRegisterClass);
352 }
353
354 static DecodeStatus DecodeLoadIntPair(MCInst &Inst, unsigned insn, uint64_t Address,
355                                   const void *Decoder) {
356   return DecodeMem(Inst, insn, Address, Decoder, true,
357                    DecodeIntPairRegisterClass);
358 }
359
360 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
361                                  const void *Decoder) {
362   return DecodeMem(Inst, insn, Address, Decoder, true,
363                    DecodeFPRegsRegisterClass);
364 }
365
366 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
367                                   const void *Decoder) {
368   return DecodeMem(Inst, insn, Address, Decoder, true,
369                    DecodeDFPRegsRegisterClass);
370 }
371
372 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
373                                   const void *Decoder) {
374   return DecodeMem(Inst, insn, Address, Decoder, true,
375                    DecodeQFPRegsRegisterClass);
376 }
377
378 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
379                                    uint64_t Address, const void *Decoder) {
380   return DecodeMem(Inst, insn, Address, Decoder, false,
381                    DecodeIntRegsRegisterClass);
382 }
383
384 static DecodeStatus DecodeStoreIntPair(MCInst &Inst, unsigned insn,
385                                    uint64_t Address, const void *Decoder) {
386   return DecodeMem(Inst, insn, Address, Decoder, false,
387                    DecodeIntPairRegisterClass);
388 }
389
390 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address,
391                                   const void *Decoder) {
392   return DecodeMem(Inst, insn, Address, Decoder, false,
393                    DecodeFPRegsRegisterClass);
394 }
395
396 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
397                                    uint64_t Address, const void *Decoder) {
398   return DecodeMem(Inst, insn, Address, Decoder, false,
399                    DecodeDFPRegsRegisterClass);
400 }
401
402 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
403                                    uint64_t Address, const void *Decoder) {
404   return DecodeMem(Inst, insn, Address, Decoder, false,
405                    DecodeQFPRegsRegisterClass);
406 }
407
408 static bool tryAddingSymbolicOperand(int64_t Value,  bool isBranch,
409                                      uint64_t Address, uint64_t Offset,
410                                      uint64_t Width, MCInst &MI,
411                                      const void *Decoder) {
412   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
413   return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
414                                        Offset, Width);
415 }
416
417 static DecodeStatus DecodeCall(MCInst &MI, unsigned insn,
418                                uint64_t Address, const void *Decoder) {
419   unsigned tgt = fieldFromInstruction(insn, 0, 30);
420   tgt <<= 2;
421   if (!tryAddingSymbolicOperand(tgt+Address, false, Address,
422                                 0, 30, MI, Decoder))
423     MI.addOperand(MCOperand::createImm(tgt));
424   return MCDisassembler::Success;
425 }
426
427 static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn,
428                                  uint64_t Address, const void *Decoder) {
429   unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
430   MI.addOperand(MCOperand::createImm(tgt));
431   return MCDisassembler::Success;
432 }
433
434 static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address,
435                                const void *Decoder) {
436
437   unsigned rd = fieldFromInstruction(insn, 25, 5);
438   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
439   unsigned isImm = fieldFromInstruction(insn, 13, 1);
440   unsigned rs2 = 0;
441   unsigned simm13 = 0;
442   if (isImm)
443     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
444   else
445     rs2 = fieldFromInstruction(insn, 0, 5);
446
447   // Decode RD.
448   DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
449   if (status != MCDisassembler::Success)
450     return status;
451
452   // Decode RS1.
453   status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
454   if (status != MCDisassembler::Success)
455     return status;
456
457   // Decode RS1 | SIMM13.
458   if (isImm)
459     MI.addOperand(MCOperand::createImm(simm13));
460   else {
461     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
462     if (status != MCDisassembler::Success)
463       return status;
464   }
465   return MCDisassembler::Success;
466 }
467
468 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
469                                  const void *Decoder) {
470
471   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
472   unsigned isImm = fieldFromInstruction(insn, 13, 1);
473   unsigned rs2 = 0;
474   unsigned simm13 = 0;
475   if (isImm)
476     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
477   else
478     rs2 = fieldFromInstruction(insn, 0, 5);
479
480   // Decode RS1.
481   DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
482   if (status != MCDisassembler::Success)
483     return status;
484
485   // Decode RS2 | SIMM13.
486   if (isImm)
487     MI.addOperand(MCOperand::createImm(simm13));
488   else {
489     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
490     if (status != MCDisassembler::Success)
491       return status;
492   }
493   return MCDisassembler::Success;
494 }
495
496 static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address,
497                                const void *Decoder) {
498
499   unsigned rd = fieldFromInstruction(insn, 25, 5);
500   unsigned rs1 = fieldFromInstruction(insn, 14, 5);
501   unsigned isImm = fieldFromInstruction(insn, 13, 1);
502   bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field)
503   unsigned asi = fieldFromInstruction(insn, 5, 8);
504   unsigned rs2 = 0;
505   unsigned simm13 = 0;
506   if (isImm)
507     simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
508   else
509     rs2 = fieldFromInstruction(insn, 0, 5);
510
511   // Decode RD.
512   DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
513   if (status != MCDisassembler::Success)
514     return status;
515
516   // Decode RS1.
517   status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
518   if (status != MCDisassembler::Success)
519     return status;
520
521   // Decode RS1 | SIMM13.
522   if (isImm)
523     MI.addOperand(MCOperand::createImm(simm13));
524   else {
525     status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
526     if (status != MCDisassembler::Success)
527       return status;
528   }
529
530   if (hasAsi)
531     MI.addOperand(MCOperand::createImm(asi));
532
533   return MCDisassembler::Success;
534 }