1 /// Types and constants of SPARC architecturem
2 module capstone.sparc;
3 
4 import std.variant;
5 import std.exception: enforce;
6 import std.conv: to;
7 import std.typecons: BitFlags;
8 
9 import capstone.internal;
10 import capstone.utils;
11 
12 /** Instruction's operand referring to memory
13 
14 This is associated with the `SparcOpType.mem` operand type
15 */
16 struct SparcOpMem {
17 	SparcRegister base;	 /// Base register
18 	SparcRegister index; /// Index register
19 	int disp;    		 /// Displacement/offset value
20 
21 	this(sparc_op_mem internal){
22 		base = internal.base.to!SparcRegister;
23 		index = internal.index.to!SparcRegister;
24 		disp = internal.disp;
25 	}
26 }
27 
28 /// Tagged union of possible operand types
29 alias SparcOpValue = TaggedUnion!(SparcRegister, "reg", int, "imm", SparcOpMem, "mem");
30 
31 /// Instruction's operand
32 struct SparcOp {
33     SparcOpType type;   /// Operand type
34     SparcOpValue value; /// Operand value of type `type`
35     alias value this; 	/// Convenient access to value (as in original bindings)
36 
37     package this(cs_sparc_op internal){
38         type = internal.type;
39         final switch(internal.type) {
40             case SparcOpType.invalid:
41                 break;
42             case SparcOpType.reg:
43                 value.reg = internal.reg;
44                 break;
45             case SparcOpType.imm:
46                 value.imm = internal.imm;
47                 break;
48             case SparcOpType.mem:
49                 value.mem = SparcOpMem(internal.mem);
50                 break;
51         }
52     }
53 }
54 
55 /// Sparc-specific information about an instruction
56 struct SparcInstructionDetail {
57 	SparcCc cc; 			 /// Code condition for this instruction
58 	BitFlags!SparcHint hint; /// Branch hint: encoding as bitwise OR of `SparcHint`, invalid if = 0
59     SparcOp[] operands; 	 /// Operands for this instruction.
60 
61     package this(cs_arch_detail arch_detail){
62 		this(arch_detail.sparc);
63 	}
64     package this(cs_sparc internal){
65 		cc = internal.cc;
66 		hint = internal.hint;
67         foreach(op; internal.operands[0..internal.op_count])
68             operands ~= SparcOp(op);
69     }
70 }
71 
72 //=============================================================================
73 // Constants
74 //=============================================================================
75 
76 /// Operand type for instruction's operands
77 enum SparcOpType {
78 	invalid = 0, /// Uninitialized
79 	reg, 		 /// Register operand
80 	imm, 		 /// Immediate operand
81 	mem, 		 /// Memory operand
82 }
83 
84 /// Enums corresponding to Sparc condition codes, both icc's and fcc's.
85 enum SparcCc {
86 	invalid = 0,	   /// Invalid CC (default)
87 
88 	// Integer condition codes
89 	icc_a   =  8+256,  /// Always
90 	icc_n   =  0+256,  /// Never
91 	icc_ne  =  9+256,  /// Not Equal
92 	icc_e   =  1+256,  /// Equal
93 	icc_g   = 10+256,  /// Greater
94 	icc_le  =  2+256,  /// Less or Equal
95 	icc_ge  = 11+256,  /// Greater or Equal
96 	icc_l   =  3+256,  /// Less
97 	icc_gu  = 12+256,  /// Greater Unsigned
98 	icc_leu =  4+256,  /// Less or Equal Unsigned
99 	icc_cc  = 13+256,  /// Carry Clear/Great or Equal Unsigned
100 	icc_cs  =  5+256,  /// Carry Set/Less Unsigned
101 	icc_pos = 14+256,  /// Positive
102 	icc_neg =  6+256,  /// Negative
103 	icc_vc  = 15+256,  /// Overflow Clear
104 	icc_vs  =  7+256,  /// Overflow Set
105 
106 	// Floating condition codes
107 	fcc_a   =  8+16+256,  /// Always
108 	fcc_n   =  0+16+256,  /// Never
109 	fcc_u   =  7+16+256,  /// Unordered
110 	fcc_g   =  6+16+256,  /// Greater
111 	fcc_ug  =  5+16+256,  /// Unordered or Greater
112 	fcc_l   =  4+16+256,  /// Less
113 	fcc_ul  =  3+16+256,  /// Unordered or Less
114 	fcc_lg  =  2+16+256,  /// Less or Greater
115 	fcc_ne  =  1+16+256,  /// Not Equal
116 	fcc_e   =  9+16+256,  /// Equal
117 	fcc_ue  = 10+16+256,  /// Unordered or Equal
118 	fcc_ge  = 11+16+256,  /// Greater or Equal
119 	fcc_uge = 12+16+256,  /// Unordered or Greater or Equal
120 	fcc_le  = 13+16+256,  /// Less or Equal
121 	fcc_ule = 14+16+256,  /// Unordered or Less or Equal
122 	fcc_o   = 15+16+256,  /// Ordered
123 }
124 
125 /// Branch hint
126 enum SparcHint {
127 	invalid = 0,	/// No hint
128 	a	= 1 << 0,	/// Annul delay slot instruction
129 	pt	= 1 << 1,	/// Branch taken
130 	pn	= 1 << 2,	/// Branch NOT taken
131 }
132 
133 /// SPARC registers
134 enum SparcRegister {
135 	invalid = 0,
136 
137 	f0,
138 	f1,
139 	f2,
140 	f3,
141 	f4,
142 	f5,
143 	f6,
144 	f7,
145 	f8,
146 	f9,
147 	f10,
148 	f11,
149 	f12,
150 	f13,
151 	f14,
152 	f15,
153 	f16,
154 	f17,
155 	f18,
156 	f19,
157 	f20,
158 	f21,
159 	f22,
160 	f23,
161 	f24,
162 	f25,
163 	f26,
164 	f27,
165 	f28,
166 	f29,
167 	f30,
168 	f31,
169 	f32,
170 	f34,
171 	f36,
172 	f38,
173 	f40,
174 	f42,
175 	f44,
176 	f46,
177 	f48,
178 	f50,
179 	f52,
180 	f54,
181 	f56,
182 	f58,
183 	f60,
184 	f62,
185 	fcc0,	// Floating condition codes
186 	fcc1,
187 	fcc2,
188 	fcc3,
189 	fp,
190 	g0,
191 	g1,
192 	g2,
193 	g3,
194 	g4,
195 	g5,
196 	g6,
197 	g7,
198 	i0,
199 	i1,
200 	i2,
201 	i3,
202 	i4,
203 	i5,
204 	i7,
205 	icc,	// Integer condition codes
206 	l0,
207 	l1,
208 	l2,
209 	l3,
210 	l4,
211 	l5,
212 	l6,
213 	l7,
214 	o0,
215 	o1,
216 	o2,
217 	o3,
218 	o4,
219 	o5,
220 	o7,
221 	sp,
222 	y,
223 
224 	// Special register
225 	xcc,
226 
227 	// Extras
228 	o6 = sp,
229 	i6 = fp,
230 }
231 
232 /// SPARC instruction
233 enum SparcInstructionId {
234 	invalid = 0,
235 
236 	addcc,
237 	addx,
238 	addxcc,
239 	addxc,
240 	addxccc,
241 	add,
242 	alignaddr,
243 	alignaddrl,
244 	andcc,
245 	andncc,
246 	andn,
247 	and,
248 	array16,
249 	array32,
250 	array8,
251 	b,
252 	jmp,
253 	bmask,
254 	fb,
255 	brgez,
256 	brgz,
257 	brlez,
258 	brlz,
259 	brnz,
260 	brz,
261 	bshuffle,
262 	call,
263 	casx,
264 	cas,
265 	cmask16,
266 	cmask32,
267 	cmask8,
268 	cmp,
269 	edge16,
270 	edge16l,
271 	edge16ln,
272 	edge16n,
273 	edge32,
274 	edge32l,
275 	edge32ln,
276 	edge32n,
277 	edge8,
278 	edge8l,
279 	edge8ln,
280 	edge8n,
281 	fabsd,
282 	fabsq,
283 	fabss,
284 	faddd,
285 	faddq,
286 	fadds,
287 	faligndata,
288 	fand,
289 	fandnot1,
290 	fandnot1s,
291 	fandnot2,
292 	fandnot2s,
293 	fands,
294 	fchksm16,
295 	fcmpd,
296 	fcmpeq16,
297 	fcmpeq32,
298 	fcmpgt16,
299 	fcmpgt32,
300 	fcmple16,
301 	fcmple32,
302 	fcmpne16,
303 	fcmpne32,
304 	fcmpq,
305 	fcmps,
306 	fdivd,
307 	fdivq,
308 	fdivs,
309 	fdmulq,
310 	fdtoi,
311 	fdtoq,
312 	fdtos,
313 	fdtox,
314 	fexpand,
315 	fhaddd,
316 	fhadds,
317 	fhsubd,
318 	fhsubs,
319 	fitod,
320 	fitoq,
321 	fitos,
322 	flcmpd,
323 	flcmps,
324 	flushw,
325 	fmean16,
326 	fmovd,
327 	fmovq,
328 	fmovrdgez,
329 	fmovrqgez,
330 	fmovrsgez,
331 	fmovrdgz,
332 	fmovrqgz,
333 	fmovrsgz,
334 	fmovrdlez,
335 	fmovrqlez,
336 	fmovrslez,
337 	fmovrdlz,
338 	fmovrqlz,
339 	fmovrslz,
340 	fmovrdnz,
341 	fmovrqnz,
342 	fmovrsnz,
343 	fmovrdz,
344 	fmovrqz,
345 	fmovrsz,
346 	fmovs,
347 	fmul8sux16,
348 	fmul8ulx16,
349 	fmul8x16,
350 	fmul8x16al,
351 	fmul8x16au,
352 	fmuld,
353 	fmuld8sux16,
354 	fmuld8ulx16,
355 	fmulq,
356 	fmuls,
357 	fnaddd,
358 	fnadds,
359 	fnand,
360 	fnands,
361 	fnegd,
362 	fnegq,
363 	fnegs,
364 	fnhaddd,
365 	fnhadds,
366 	fnor,
367 	fnors,
368 	fnot1,
369 	fnot1s,
370 	fnot2,
371 	fnot2s,
372 	fone,
373 	fones,
374 	for_,
375 	fornot1,
376 	fornot1s,
377 	fornot2,
378 	fornot2s,
379 	fors,
380 	fpack16,
381 	fpack32,
382 	fpackfix,
383 	fpadd16,
384 	fpadd16s,
385 	fpadd32,
386 	fpadd32s,
387 	fpadd64,
388 	fpmerge,
389 	fpsub16,
390 	fpsub16s,
391 	fpsub32,
392 	fpsub32s,
393 	fqtod,
394 	fqtoi,
395 	fqtos,
396 	fqtox,
397 	fslas16,
398 	fslas32,
399 	fsll16,
400 	fsll32,
401 	fsmuld,
402 	fsqrtd,
403 	fsqrtq,
404 	fsqrts,
405 	fsra16,
406 	fsra32,
407 	fsrc1,
408 	fsrc1s,
409 	fsrc2,
410 	fsrc2s,
411 	fsrl16,
412 	fsrl32,
413 	fstod,
414 	fstoi,
415 	fstoq,
416 	fstox,
417 	fsubd,
418 	fsubq,
419 	fsubs,
420 	fxnor,
421 	fxnors,
422 	fxor,
423 	fxors,
424 	fxtod,
425 	fxtoq,
426 	fxtos,
427 	fzero,
428 	fzeros,
429 	jmpl,
430 	ldd,
431 	ld,
432 	ldq,
433 	ldsb,
434 	ldsh,
435 	ldsw,
436 	ldub,
437 	lduh,
438 	ldx,
439 	lzcnt,
440 	membar,
441 	movdtox,
442 	mov,
443 	movrgez,
444 	movrgz,
445 	movrlez,
446 	movrlz,
447 	movrnz,
448 	movrz,
449 	movstosw,
450 	movstouw,
451 	mulx,
452 	nop,
453 	orcc,
454 	orncc,
455 	orn,
456 	or,
457 	pdist,
458 	pdistn,
459 	popc,
460 	rd,
461 	restore,
462 	rett,
463 	save,
464 	sdivcc,
465 	sdivx,
466 	sdiv,
467 	sethi,
468 	shutdown,
469 	siam,
470 	sllx,
471 	sll,
472 	smulcc,
473 	smul,
474 	srax,
475 	sra,
476 	srlx,
477 	srl,
478 	stbar,
479 	stb,
480 	std,
481 	st,
482 	sth,
483 	stq,
484 	stx,
485 	subcc,
486 	subx,
487 	subxcc,
488 	sub,
489 	swap,
490 	taddcctv,
491 	taddcc,
492 	t,
493 	tsubcctv,
494 	tsubcc,
495 	udivcc,
496 	udivx,
497 	udiv,
498 	umulcc,
499 	umulxhi,
500 	umul,
501 	unimp,
502 	fcmped,
503 	fcmpeq,
504 	fcmpes,
505 	wr,
506 	xmulx,
507 	xmulxhi,
508 	xnorcc,
509 	xnor,
510 	xorcc,
511 	xor,
512 
513 	// alias instructions
514 	ret,
515 	retl,
516 }
517 
518 /// Group of SPARC instructions
519 enum SparcInstructionGroup {
520 	invalid = 0,
521 
522 	// Generic groups
523 	// all jump instructions (conditional+direct+indirect jumps)
524 	jump,
525 
526 	// Architecture-specific groups
527 	hardquad = 128,
528 	v9,
529 	vis,
530 	vis2,
531 	vis3, 
532 	bit32,
533 	bit64,
534 }