1 //===------ SparcDisassembler.cpp - Disassembler for PowerPC ------*- 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 /* Capstone Disassembly Engine */
11 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2014 */
12
13 #ifdef CAPSTONE_HAS_SPARC
14
15 #include <stdio.h> // DEBUG
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "../../cs_priv.h"
20 #include "../../utils.h"
21
22 #include "../../MCInst.h"
23 #include "../../MCInstrDesc.h"
24 #include "../../MCFixedLenDisassembler.h"
25 #include "../../MCRegisterInfo.h"
26 #include "../../MCDisassembler.h"
27 #include "../../MathExtras.h"
28
29
30 #define GET_REGINFO_MC_DESC
31 #define GET_REGINFO_ENUM
32 #include "SparcGenRegisterInfo.inc"
33 static const unsigned IntRegDecoderTable[] = {
34 SP_G0, SP_G1, SP_G2, SP_G3,
35 SP_G4, SP_G5, SP_G6, SP_G7,
36 SP_O0, SP_O1, SP_O2, SP_O3,
37 SP_O4, SP_O5, SP_O6, SP_O7,
38 SP_L0, SP_L1, SP_L2, SP_L3,
39 SP_L4, SP_L5, SP_L6, SP_L7,
40 SP_I0, SP_I1, SP_I2, SP_I3,
41 SP_I4, SP_I5, SP_I6, SP_I7
42 };
43
44 static const unsigned FPRegDecoderTable[] = {
45 SP_F0, SP_F1, SP_F2, SP_F3,
46 SP_F4, SP_F5, SP_F6, SP_F7,
47 SP_F8, SP_F9, SP_F10, SP_F11,
48 SP_F12, SP_F13, SP_F14, SP_F15,
49 SP_F16, SP_F17, SP_F18, SP_F19,
50 SP_F20, SP_F21, SP_F22, SP_F23,
51 SP_F24, SP_F25, SP_F26, SP_F27,
52 SP_F28, SP_F29, SP_F30, SP_F31
53 };
54
55 static const unsigned DFPRegDecoderTable[] = {
56 SP_D0, SP_D16, SP_D1, SP_D17,
57 SP_D2, SP_D18, SP_D3, SP_D19,
58 SP_D4, SP_D20, SP_D5, SP_D21,
59 SP_D6, SP_D22, SP_D7, SP_D23,
60 SP_D8, SP_D24, SP_D9, SP_D25,
61 SP_D10, SP_D26, SP_D11, SP_D27,
62 SP_D12, SP_D28, SP_D13, SP_D29,
63 SP_D14, SP_D30, SP_D15, SP_D31
64 };
65
66 static const unsigned QFPRegDecoderTable[] = {
67 SP_Q0, SP_Q8, ~0U, ~0U,
68 SP_Q1, SP_Q9, ~0U, ~0U,
69 SP_Q2, SP_Q10, ~0U, ~0U,
70 SP_Q3, SP_Q11, ~0U, ~0U,
71 SP_Q4, SP_Q12, ~0U, ~0U,
72 SP_Q5, SP_Q13, ~0U, ~0U,
73 SP_Q6, SP_Q14, ~0U, ~0U,
74 SP_Q7, SP_Q15, ~0U, ~0U
75 };
76
77 static const unsigned FCCRegDecoderTable[] = {
78 SP_FCC0, SP_FCC1, SP_FCC2, SP_FCC3
79 };
80
getFeatureBits(int mode)81 static uint64_t getFeatureBits(int mode)
82 {
83 // support everything
84 return (uint64_t)-1;
85 }
86
DecodeIntRegsRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)87 static DecodeStatus DecodeIntRegsRegisterClass(MCInst *Inst, unsigned RegNo,
88 uint64_t Address, const void *Decoder)
89 {
90 unsigned Reg;
91
92 if (RegNo > 31)
93 return MCDisassembler_Fail;
94
95 Reg = IntRegDecoderTable[RegNo];
96 MCOperand_CreateReg0(Inst, Reg);
97
98 return MCDisassembler_Success;
99 }
100
DecodeI64RegsRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)101 static DecodeStatus DecodeI64RegsRegisterClass(MCInst *Inst, unsigned RegNo,
102 uint64_t Address, const void *Decoder)
103 {
104 unsigned Reg;
105
106 if (RegNo > 31)
107 return MCDisassembler_Fail;
108
109 Reg = IntRegDecoderTable[RegNo];
110 MCOperand_CreateReg0(Inst, Reg);
111
112 return MCDisassembler_Success;
113 }
114
DecodeFPRegsRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)115 static DecodeStatus DecodeFPRegsRegisterClass(MCInst *Inst, unsigned RegNo,
116 uint64_t Address, const void *Decoder)
117 {
118 unsigned Reg;
119
120 if (RegNo > 31)
121 return MCDisassembler_Fail;
122
123 Reg = FPRegDecoderTable[RegNo];
124 MCOperand_CreateReg0(Inst, Reg);
125
126 return MCDisassembler_Success;
127 }
128
DecodeDFPRegsRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)129 static DecodeStatus DecodeDFPRegsRegisterClass(MCInst *Inst, unsigned RegNo,
130 uint64_t Address, const void *Decoder)
131 {
132 unsigned Reg;
133
134 if (RegNo > 31)
135 return MCDisassembler_Fail;
136
137 Reg = DFPRegDecoderTable[RegNo];
138 MCOperand_CreateReg0(Inst, Reg);
139
140 return MCDisassembler_Success;
141 }
142
DecodeQFPRegsRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)143 static DecodeStatus DecodeQFPRegsRegisterClass(MCInst *Inst, unsigned RegNo,
144 uint64_t Address, const void *Decoder)
145 {
146 unsigned Reg;
147
148 if (RegNo > 31)
149 return MCDisassembler_Fail;
150
151 Reg = QFPRegDecoderTable[RegNo];
152 if (Reg == ~0U)
153 return MCDisassembler_Fail;
154
155 MCOperand_CreateReg0(Inst, Reg);
156
157 return MCDisassembler_Success;
158 }
159
DecodeFCCRegsRegisterClass(MCInst * Inst,unsigned RegNo,uint64_t Address,const void * Decoder)160 static DecodeStatus DecodeFCCRegsRegisterClass(MCInst *Inst, unsigned RegNo,
161 uint64_t Address, const void *Decoder)
162 {
163 if (RegNo > 3)
164 return MCDisassembler_Fail;
165
166 MCOperand_CreateReg0(Inst, FCCRegDecoderTable[RegNo]);
167
168 return MCDisassembler_Success;
169 }
170
171
172 static DecodeStatus DecodeLoadInt(MCInst *Inst, unsigned insn, uint64_t Address,
173 const void *Decoder);
174 static DecodeStatus DecodeLoadFP(MCInst *Inst, unsigned insn, uint64_t Address,
175 const void *Decoder);
176 static DecodeStatus DecodeLoadDFP(MCInst *Inst, unsigned insn, uint64_t Address,
177 const void *Decoder);
178 static DecodeStatus DecodeLoadQFP(MCInst *Inst, unsigned insn, uint64_t Address,
179 const void *Decoder);
180 static DecodeStatus DecodeStoreInt(MCInst *Inst, unsigned insn,
181 uint64_t Address, const void *Decoder);
182 static DecodeStatus DecodeStoreFP(MCInst *Inst, unsigned insn,
183 uint64_t Address, const void *Decoder);
184 static DecodeStatus DecodeStoreDFP(MCInst *Inst, unsigned insn,
185 uint64_t Address, const void *Decoder);
186 static DecodeStatus DecodeStoreQFP(MCInst *Inst, unsigned insn,
187 uint64_t Address, const void *Decoder);
188 static DecodeStatus DecodeCall(MCInst *Inst, unsigned insn,
189 uint64_t Address, const void *Decoder);
190 static DecodeStatus DecodeSIMM13(MCInst *Inst, unsigned insn,
191 uint64_t Address, const void *Decoder);
192 static DecodeStatus DecodeJMPL(MCInst *Inst, unsigned insn, uint64_t Address,
193 const void *Decoder);
194 static DecodeStatus DecodeReturn(MCInst *MI, unsigned insn, uint64_t Address,
195 const void *Decoder);
196 static DecodeStatus DecodeSWAP(MCInst *Inst, unsigned insn, uint64_t Address,
197 const void *Decoder);
198
199
200 #define GET_SUBTARGETINFO_ENUM
201 #include "SparcGenSubtargetInfo.inc"
202 #include "SparcGenDisassemblerTables.inc"
203
204 /// readInstruction - read four bytes and return 32 bit word.
readInstruction32(const uint8_t * code,size_t len,uint32_t * Insn)205 static DecodeStatus readInstruction32(const uint8_t *code, size_t len, uint32_t *Insn)
206 {
207 uint8_t Bytes[4];
208
209 if (len < 4)
210 // not enough data
211 return MCDisassembler_Fail;
212
213 memcpy(Bytes, code, 4);
214
215 // Encoded as a big-endian 32-bit word in the stream.
216 *Insn = (Bytes[3] << 0) |
217 (Bytes[2] << 8) |
218 (Bytes[1] << 16) |
219 (Bytes[0] << 24);
220
221 return MCDisassembler_Success;
222 }
223
Sparc_getInstruction(csh ud,const uint8_t * code,size_t code_len,MCInst * MI,uint16_t * size,uint64_t address,void * info)224 bool Sparc_getInstruction(csh ud, const uint8_t *code, size_t code_len, MCInst *MI,
225 uint16_t *size, uint64_t address, void *info)
226 {
227 uint32_t Insn;
228 DecodeStatus Result;
229
230 Result = readInstruction32(code, code_len, &Insn);
231 if (Result == MCDisassembler_Fail)
232 return false;
233
234 if (MI->flat_insn->detail) {
235 memset(MI->flat_insn->detail, 0, sizeof(cs_detail));
236 }
237
238 Result = decodeInstruction_4(DecoderTableSparc32, MI, Insn, address,
239 (MCRegisterInfo *)info, 0);
240 if (Result != MCDisassembler_Fail) {
241 *size = 4;
242 return true;
243 }
244
245 return false;
246 }
247
248 typedef DecodeStatus (*DecodeFunc)(MCInst *MI, unsigned insn, uint64_t Address,
249 const void *Decoder);
250
DecodeMem(MCInst * MI,unsigned insn,uint64_t Address,const void * Decoder,bool isLoad,DecodeFunc DecodeRD)251 static DecodeStatus DecodeMem(MCInst *MI, unsigned insn, uint64_t Address,
252 const void *Decoder,
253 bool isLoad, DecodeFunc DecodeRD)
254 {
255 DecodeStatus status;
256 unsigned rd = fieldFromInstruction_4(insn, 25, 5);
257 unsigned rs1 = fieldFromInstruction_4(insn, 14, 5);
258 bool isImm = fieldFromInstruction_4(insn, 13, 1) != 0;
259 unsigned rs2 = 0;
260 unsigned simm13 = 0;
261
262 if (isImm)
263 simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
264 else
265 rs2 = fieldFromInstruction_4(insn, 0, 5);
266
267 if (isLoad) {
268 status = DecodeRD(MI, rd, Address, Decoder);
269 if (status != MCDisassembler_Success)
270 return status;
271 }
272
273 // Decode rs1.
274 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
275 if (status != MCDisassembler_Success)
276 return status;
277
278 // Decode imm|rs2.
279 if (isImm)
280 MCOperand_CreateImm0(MI, simm13);
281 else {
282 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
283 if (status != MCDisassembler_Success)
284 return status;
285 }
286
287 if (!isLoad) {
288 status = DecodeRD(MI, rd, Address, Decoder);
289 if (status != MCDisassembler_Success)
290 return status;
291 }
292
293 return MCDisassembler_Success;
294 }
295
DecodeLoadInt(MCInst * Inst,unsigned insn,uint64_t Address,const void * Decoder)296 static DecodeStatus DecodeLoadInt(MCInst *Inst, unsigned insn, uint64_t Address,
297 const void *Decoder)
298 {
299 return DecodeMem(Inst, insn, Address, Decoder, true,
300 DecodeIntRegsRegisterClass);
301 }
302
DecodeLoadFP(MCInst * Inst,unsigned insn,uint64_t Address,const void * Decoder)303 static DecodeStatus DecodeLoadFP(MCInst *Inst, unsigned insn, uint64_t Address,
304 const void *Decoder)
305 {
306 return DecodeMem(Inst, insn, Address, Decoder, true,
307 DecodeFPRegsRegisterClass);
308 }
309
DecodeLoadDFP(MCInst * Inst,unsigned insn,uint64_t Address,const void * Decoder)310 static DecodeStatus DecodeLoadDFP(MCInst *Inst, unsigned insn, uint64_t Address,
311 const void *Decoder)
312 {
313 return DecodeMem(Inst, insn, Address, Decoder, true,
314 DecodeDFPRegsRegisterClass);
315 }
316
DecodeLoadQFP(MCInst * Inst,unsigned insn,uint64_t Address,const void * Decoder)317 static DecodeStatus DecodeLoadQFP(MCInst *Inst, unsigned insn, uint64_t Address,
318 const void *Decoder)
319 {
320 return DecodeMem(Inst, insn, Address, Decoder, true,
321 DecodeQFPRegsRegisterClass);
322 }
323
DecodeStoreInt(MCInst * Inst,unsigned insn,uint64_t Address,const void * Decoder)324 static DecodeStatus DecodeStoreInt(MCInst *Inst, unsigned insn,
325 uint64_t Address, const void *Decoder)
326 {
327 return DecodeMem(Inst, insn, Address, Decoder, false,
328 DecodeIntRegsRegisterClass);
329 }
330
DecodeStoreFP(MCInst * Inst,unsigned insn,uint64_t Address,const void * Decoder)331 static DecodeStatus DecodeStoreFP(MCInst *Inst, unsigned insn, uint64_t Address,
332 const void *Decoder)
333 {
334 return DecodeMem(Inst, insn, Address, Decoder, false,
335 DecodeFPRegsRegisterClass);
336 }
337
DecodeStoreDFP(MCInst * Inst,unsigned insn,uint64_t Address,const void * Decoder)338 static DecodeStatus DecodeStoreDFP(MCInst *Inst, unsigned insn,
339 uint64_t Address, const void *Decoder)
340 {
341 return DecodeMem(Inst, insn, Address, Decoder, false,
342 DecodeDFPRegsRegisterClass);
343 }
344
DecodeStoreQFP(MCInst * Inst,unsigned insn,uint64_t Address,const void * Decoder)345 static DecodeStatus DecodeStoreQFP(MCInst *Inst, unsigned insn,
346 uint64_t Address, const void *Decoder)
347 {
348 return DecodeMem(Inst, insn, Address, Decoder, false,
349 DecodeQFPRegsRegisterClass);
350 }
351
DecodeCall(MCInst * MI,unsigned insn,uint64_t Address,const void * Decoder)352 static DecodeStatus DecodeCall(MCInst *MI, unsigned insn,
353 uint64_t Address, const void *Decoder)
354 {
355 unsigned tgt = fieldFromInstruction_4(insn, 0, 30);
356 tgt <<= 2;
357
358 MCOperand_CreateImm0(MI, tgt);
359
360 return MCDisassembler_Success;
361 }
362
DecodeSIMM13(MCInst * MI,unsigned insn,uint64_t Address,const void * Decoder)363 static DecodeStatus DecodeSIMM13(MCInst *MI, unsigned insn,
364 uint64_t Address, const void *Decoder)
365 {
366 unsigned tgt = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
367
368 MCOperand_CreateImm0(MI, tgt);
369
370 return MCDisassembler_Success;
371 }
372
DecodeJMPL(MCInst * MI,unsigned insn,uint64_t Address,const void * Decoder)373 static DecodeStatus DecodeJMPL(MCInst *MI, unsigned insn, uint64_t Address,
374 const void *Decoder)
375 {
376 DecodeStatus status;
377 unsigned rd = fieldFromInstruction_4(insn, 25, 5);
378 unsigned rs1 = fieldFromInstruction_4(insn, 14, 5);
379 unsigned isImm = fieldFromInstruction_4(insn, 13, 1);
380 unsigned rs2 = 0;
381 unsigned simm13 = 0;
382
383 if (isImm)
384 simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
385 else
386 rs2 = fieldFromInstruction_4(insn, 0, 5);
387
388 // Decode RD.
389 status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
390 if (status != MCDisassembler_Success)
391 return status;
392
393 // Decode RS1.
394 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
395 if (status != MCDisassembler_Success)
396 return status;
397
398 // Decode RS1 | SIMM13.
399 if (isImm)
400 MCOperand_CreateImm0(MI, simm13);
401 else {
402 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
403 if (status != MCDisassembler_Success)
404 return status;
405 }
406
407 return MCDisassembler_Success;
408 }
409
DecodeReturn(MCInst * MI,unsigned insn,uint64_t Address,const void * Decoder)410 static DecodeStatus DecodeReturn(MCInst *MI, unsigned insn, uint64_t Address,
411 const void *Decoder)
412 {
413 DecodeStatus status;
414 unsigned rs1 = fieldFromInstruction_4(insn, 14, 5);
415 unsigned isImm = fieldFromInstruction_4(insn, 13, 1);
416 unsigned rs2 = 0;
417 unsigned simm13 = 0;
418 if (isImm)
419 simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
420 else
421 rs2 = fieldFromInstruction_4(insn, 0, 5);
422
423 // Decode RS1.
424 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
425 if (status != MCDisassembler_Success)
426 return status;
427
428 // Decode RS2 | SIMM13.
429 if (isImm)
430 MCOperand_CreateImm0(MI, simm13);
431 else {
432 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
433 if (status != MCDisassembler_Success)
434 return status;
435 }
436
437 return MCDisassembler_Success;
438 }
439
DecodeSWAP(MCInst * MI,unsigned insn,uint64_t Address,const void * Decoder)440 static DecodeStatus DecodeSWAP(MCInst *MI, unsigned insn, uint64_t Address,
441 const void *Decoder)
442 {
443 DecodeStatus status;
444 unsigned rd = fieldFromInstruction_4(insn, 25, 5);
445 unsigned rs1 = fieldFromInstruction_4(insn, 14, 5);
446 unsigned isImm = fieldFromInstruction_4(insn, 13, 1);
447 unsigned rs2 = 0;
448 unsigned simm13 = 0;
449
450 if (isImm)
451 simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13);
452 else
453 rs2 = fieldFromInstruction_4(insn, 0, 5);
454
455 // Decode RD.
456 status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
457 if (status != MCDisassembler_Success)
458 return status;
459
460 // Decode RS1.
461 status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
462 if (status != MCDisassembler_Success)
463 return status;
464
465 // Decode RS1 | SIMM13.
466 if (isImm)
467 MCOperand_CreateImm0(MI, simm13);
468 else {
469 status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
470 if (status != MCDisassembler_Success)
471 return status;
472 }
473
474 return MCDisassembler_Success;
475 }
476
Sparc_init(MCRegisterInfo * MRI)477 void Sparc_init(MCRegisterInfo *MRI)
478 {
479 /*
480 InitMCRegisterInfo(SparcRegDesc, 119, RA, PC,
481 SparcMCRegisterClasses, 8,
482 SparcRegUnitRoots,
483 86,
484 SparcRegDiffLists,
485 SparcRegStrings,
486 SparcSubRegIdxLists,
487 7,
488 SparcSubRegIdxRanges,
489 SparcRegEncodingTable);
490 */
491
492 MCRegisterInfo_InitMCRegisterInfo(MRI, SparcRegDesc, 119,
493 0, 0,
494 SparcMCRegisterClasses, 8,
495 0, 0,
496 SparcRegDiffLists,
497 0,
498 SparcSubRegIdxLists, 7,
499 0);
500 }
501
502 #endif
503