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