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