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