1 /// Types and constants of TMS320C64x architecture
2 module capstone.tms320c64x;
3 
4 import std.conv: to;
5 
6 import capstone.api;
7 import capstone.capstone;
8 import capstone.detail;
9 import capstone.instruction;
10 import capstone.instructiongroup;
11 import capstone.internal;
12 import capstone.register;
13 import capstone.utils;
14 
15 /// Architecture-specific Register variant
16 class Tms320c64xRegister : RegisterImpl!Tms320c64xRegisterId {
17     package this(in Capstone cs, in int id) {
18         super(cs, id);
19     }
20 }
21 
22 /// Architecture-specific InstructionGroup variant
23 class Tms320c64xInstructionGroup : InstructionGroupImpl!Tms320c64xInstructionGroupId {
24     package this(in Capstone cs, in int id) {
25         super(cs, id);
26     }
27 }
28 
29 /// Architecture-specific Detail variant
30 class Tms320c64xDetail : DetailImpl!(Tms320c64xRegister, Tms320c64xInstructionGroup, Tms320c64xInstructionDetail) {
31     package this(in Capstone cs, cs_detail* internal) {
32 		super(cs, internal);
33 	}
34 }
35 
36 /// Architecture-specific instruction variant
37 class Tms320c64xInstruction : InstructionImpl!(Tms320c64xInstructionId, Tms320c64xRegister, Tms320c64xDetail) {
38     package this(in Capstone cs, cs_insn* internal) {
39 		super(cs, internal);
40 	}
41 }
42 
43 /// Architecture-specific Capstone variant
44 class CapstoneTms320c64x : CapstoneImpl!(Tms320c64xInstructionId, Tms320c64xInstruction) {
45     /** Creates an architecture-specific instance with a given mode of interpretation
46     
47     Params:
48         modeFlags = The (initial) mode of interpretation, which can still be changed later on
49     */
50 	this(in ModeFlags modeFlags){
51         super(Arch.tms320c64x, modeFlags);
52     }
53 }
54 
55 /// Union of possible displacement values
56 union Tms320c64xDispValue {
57 	uint constant;				 /// Constant displacement/offset
58 	Tms320c64xRegister register; /// Register stating displacement/offset
59 }
60 
61 /** Instruction's operand referring to memory
62 
63 This is associated with the `Tms320c64xOpType.mem` operand type
64 */
65 struct Tms320c64xOpMem {
66 	Tms320c64xRegister base; 	/// Base register
67 	SafeUnion!Tms320c64xDispValue disp;	/// Displacement/offset value
68 	uint unit;				 	/// Unit of base and offset register
69 	uint scaled;			 	/// Offset scaled
70 	Tms320c64xMemDisp disptype;	/// Displacement type
71 	Tms320c64xMemDir direction;	/// Direction
72 	Tms320c64xMemMod modify; 	/// Modification
73 
74 	package this(in Capstone cs, tms320c64x_op_mem internal) {
75 		base = new Tms320c64xRegister(cs, internal.base);
76 		unit = internal.unit;
77 		scaled = internal.scaled;
78 		disptype = internal.disptype.to!Tms320c64xMemDisp;
79 		if(disptype == Tms320c64xMemDisp.register)
80 			disp.register = new Tms320c64xRegister(cs, internal.disp);
81 		else
82 			disp.constant = internal.disp;
83 		direction = internal.direction.to!Tms320c64xMemDir;
84 		modify = internal.modify.to!Tms320c64xMemMod;
85 	}
86 }
87 
88 /// Union of possible operand types
89 union Tms320c64xOpValue{
90     Tms320c64xRegister reg; /// Register
91     int imm;				/// Immediate
92     Tms320c64xOpMem mem;	/// Memory
93     Tms320c64xRegister[2] regpair; /// Register pair
94 }
95 
96 /// Instruction's operand
97 struct Tms320c64xOp {
98     Tms320c64xOpType type;   /// Operand type
99     SafeUnion!Tms320c64xOpValue value; /// Operand value of type `type`
100     alias value this;  /// Convenient access to value (as in original bindings)
101 
102     package this(in Capstone cs, cs_tms320c64x_op internal){
103         type = internal.type.to!Tms320c64xOpType;
104         final switch(internal.type) {
105             case Tms320c64xOpType.invalid:
106                 break;
107             case Tms320c64xOpType.reg:
108                 value.reg = new Tms320c64xRegister(cs, internal.reg);
109                 break;
110             case Tms320c64xOpType.imm:
111                 value.imm = internal.imm;
112                 break;
113             case Tms320c64xOpType.mem:
114                 value.mem = Tms320c64xOpMem(cs, internal.mem);
115                 break;
116 			case Tms320c64xOpType.regpair:
117 				value.regpair = [new Tms320c64xRegister(cs, internal.reg), new Tms320c64xRegister(cs, internal.reg+1)];
118 				break;
119         }
120     }
121 }
122 
123 /// Condition of instruction
124 struct Tms320c64xCondition {
125 	Tms320c64xRegister reg; /// Condition register tested
126 	bool zero;				/// True iff testing for zero
127 
128 	package this(in Capstone cs, cs_tms320c64x_condition internal) {
129 		reg = new Tms320c64xRegister(cs, internal.reg);
130 		zero = internal.zero == 1;
131 	}
132 }
133 
134 /// Funcional unit associated with an instruction
135 struct Tms320c64xFunit {
136 	Tms320c64xFunitType unit; /// Functional unit identifier
137 	uint side; /// The side/data path the unit is on
138 	bool crosspath; /// True iff using crosspath
139 
140 	package this(cs_tms320c64x_funit internal) {
141 		unit = internal.unit.to!Tms320c64xFunitType;
142 		side = internal.side;
143 		crosspath = internal.crosspath==1;
144 	}
145 }
146 
147 /// TMS320C64x-specific information about an instruction
148 struct Tms320c64xInstructionDetail {
149     Tms320c64xOp[] operands; /// Operands for this instruction.
150 	Tms320c64xCondition condition; /// Condition of instruction (irrelevant if invalid conditional register)
151 	Tms320c64xFunit funit; /// Associated functional unit
152 	bool parallel; /// True iff executed in parallel with previous instruction
153 
154     package this(in Capstone cs, cs_arch_detail arch_detail){
155         auto internal = arch_detail.tms320c64x;
156         foreach(op; internal.operands[0..internal.op_count])
157             operands ~= Tms320c64xOp(cs, op);
158 		condition = Tms320c64xCondition(cs, internal.condition);
159 		funit = Tms320c64xFunit(internal.funit);
160 		parallel = internal.parallel.to!bool;
161     }
162 }
163 
164 //=============================================================================
165 // Constants
166 //=============================================================================
167 
168 /// Operand type for instruction's operands
169 enum Tms320c64xOpType {
170 	invalid = 0,  /// Uninitialized
171 	reg, 		  /// Register operand
172 	imm, 		  /// Immediate operand
173 	mem, 		  /// Memory operand
174 	regpair = 64, /// Register pair for double word ops
175 }
176 
177 /// Memory operand displacement kind
178 enum Tms320c64xMemDisp {
179 	invalid = 0,
180 	constant,
181 	register,
182 }
183 
184 /// Memory operand direction
185 enum Tms320c64xMemDir {
186 	invalid = 0,
187 	fw,
188 	bw,
189 }
190 
191 /// Memory operand modification type
192 enum Tms320c64xMemMod {
193 	invalid = 0,
194 	no,
195 	pre,
196 	post,
197 }
198 
199 /// Functional unit type
200 enum Tms320c64xFunitType {
201 	invalid = 0,
202 	d, /// Adder/Subtractor (used for address generation)
203 	l, /// ALU
204 	m, /// Multiplier
205 	s, /// Shifter
206 	no
207 }
208 
209 /// TMS320C64x registers
210 enum Tms320c64xRegisterId {
211 	invalid = 0,
212 
213 	amr,
214 	csr,
215 	dier,
216 	dnum,
217 	ecr,
218 	gfpgfr,
219 	gplya,
220 	gplyb,
221 	icr,
222 	ier,
223 	ierr,
224 	ilc,
225 	irp,
226 	isr,
227 	istp,
228 	itsr,
229 	nrp,
230 	ntsr,
231 	rep,
232 	rilc,
233 	ssr,
234 	tsch,
235 	tscl,
236 	tsr,
237 	a0,
238 	a1,
239 	a2,
240 	a3,
241 	a4,
242 	a5,
243 	a6,
244 	a7,
245 	a8,
246 	a9,
247 	a10,
248 	a11,
249 	a12,
250 	a13,
251 	a14,
252 	a15,
253 	a16,
254 	a17,
255 	a18,
256 	a19,
257 	a20,
258 	a21,
259 	a22,
260 	a23,
261 	a24,
262 	a25,
263 	a26,
264 	a27,
265 	a28,
266 	a29,
267 	a30,
268 	a31,
269 	b0,
270 	b1,
271 	b2,
272 	b3,
273 	b4,
274 	b5,
275 	b6,
276 	b7,
277 	b8,
278 	b9,
279 	b10,
280 	b11,
281 	b12,
282 	b13,
283 	b14,
284 	b15,
285 	b16,
286 	b17,
287 	b18,
288 	b19,
289 	b20,
290 	b21,
291 	b22,
292 	b23,
293 	b24,
294 	b25,
295 	b26,
296 	b27,
297 	b28,
298 	b29,
299 	b30,
300 	b31,
301 	pce1,
302 
303 	// Alias registers
304 	efr = ecr,
305 	ifr = isr,
306 }
307 
308 /// TMS320C64x instructions
309 enum Tms320c64xInstructionId {
310 	invalid = 0,
311 
312 	abs,
313 	abs2,
314 	add,
315 	add2,
316 	add4,
317 	addab,
318 	addad,
319 	addah,
320 	addaw,
321 	addk,
322 	addkpc,
323 	addu,
324 	and,
325 	andn,
326 	avg2,
327 	avgu4,
328 	b,
329 	bdec,
330 	bitc4,
331 	bnop,
332 	bpos,
333 	clr,
334 	cmpeq,
335 	cmpeq2,
336 	cmpeq4,
337 	cmpgt,
338 	cmpgt2,
339 	cmpgtu4,
340 	cmplt,
341 	cmpltu,
342 	deal,
343 	dotp2,
344 	dotpn2,
345 	dotpnrsu2,
346 	dotprsu2,
347 	dotpsu4,
348 	dotpu4,
349 	ext,
350 	extu,
351 	gmpgtu,
352 	gmpy4,
353 	ldb,
354 	ldbu,
355 	lddw,
356 	ldh,
357 	ldhu,
358 	ldndw,
359 	ldnw,
360 	ldw,
361 	lmbd,
362 	max2,
363 	maxu4,
364 	min2,
365 	minu4,
366 	mpy,
367 	mpy2,
368 	mpyh,
369 	mpyhi,
370 	mpyhir,
371 	mpyhl,
372 	mpyhlu,
373 	mpyhslu,
374 	mpyhsu,
375 	mpyhu,
376 	mpyhuls,
377 	mpyhus,
378 	mpylh,
379 	mpylhu,
380 	mpyli,
381 	mpylir,
382 	mpylshu,
383 	mpyluhs,
384 	mpysu,
385 	mpysu4,
386 	mpyu,
387 	mpyu4,
388 	mpyus,
389 	mvc,
390 	mvd,
391 	mvk,
392 	mvkl,
393 	mvklh,
394 	nop,
395 	norm,
396 	or,
397 	pack2,
398 	packh2,
399 	packh4,
400 	packhl2,
401 	packl4,
402 	packlh2,
403 	rotl,
404 	sadd,
405 	sadd2,
406 	saddu4,
407 	saddus2,
408 	sat,
409 	set,
410 	shfl,
411 	shl,
412 	shlmb,
413 	shr,
414 	shr2,
415 	shrmb,
416 	shru,
417 	shru2,
418 	smpy,
419 	smpy2,
420 	smpyh,
421 	smpyhl,
422 	smpylh,
423 	spack2,
424 	spacku4,
425 	sshl,
426 	sshvl,
427 	sshvr,
428 	ssub,
429 	stb,
430 	stdw,
431 	sth,
432 	stndw,
433 	stnw,
434 	stw,
435 	sub,
436 	sub2,
437 	sub4,
438 	subab,
439 	subabs4,
440 	subah,
441 	subaw,
442 	subc,
443 	subu,
444 	swap4,
445 	unpkhu4,
446 	unpklu4,
447 	xor,
448 	xpnd2,
449 	xpnd4,
450 	// Aliases
451 	idle,
452 	mv,
453 	neg,
454 	not,
455 	swap2,
456 	zero,
457 }
458 
459 /// Group of TMS320C64x instructions
460 enum Tms320c64xInstructionGroupId {
461 	invalid = 0,
462 
463 	jump,
464 
465 	funit_d = 128,
466 	funit_l,
467 	funit_m,
468 	funit_s,
469 	funit_no,
470 }