1 /// Types and constants of M68k architecture
2 module capstone.m68k;
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 M68kRegister : RegisterImpl!M68kRegisterId {
17     package this(in Capstone cs, in int id) {
18         super(cs, id);
19     }
20 }
21 
22 /// Architecture-specific InstructionGroup variant
23 class M68kInstructionGroup : InstructionGroupImpl!M68kInstructionGroupId {
24     package this(in Capstone cs, in int id) {
25         super(cs, id);
26     }
27 }
28 
29 /// Architecture-specific Detail variant
30 class M68kDetail : DetailImpl!(M68kRegister, M68kInstructionGroup, M68kInstructionDetail) {
31     package this(in Capstone cs, cs_detail* internal) {
32 		super(cs, internal);
33 	}
34 }
35 
36 /// Architecture-specific instruction variant
37 class M68kInstruction : InstructionImpl!(M68kInstructionId, M68kRegister, M68kDetail) {
38     package this(in Capstone cs, cs_insn* internal) {
39 		super(cs, internal);
40 	}
41 }
42 
43 /// Architecture-specific Capstone variant
44 class CapstoneM68k : CapstoneImpl!(M68kInstructionId, M68kInstruction) {
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.m68k, modeFlags);
52     }
53 }
54 
55 /** Instruction's operand referring to memory
56 
57 This is associated with the `M68kOpType.mem` operand type
58 */
59 struct M68kOpMem {
60     M68kRegister baseReg;   /// Base register (or M68K_REG_INVALID if irrelevant)
61     M68kRegister indexReg;  /// Index register (or M68K_REG_INVALID if irrelevant)
62     M68kRegister inBaseReg; /// Indirect base register (or M68K_REG_INVALID if irrelevant)
63     uint inDisp;            /// Indirect displacement
64     uint outDisp;           /// Other displacement
65     short disp;	            /// Displacement value
66     ubyte scale;            /// Scale for index register
67     ubyte bitfield;         /// Set to true if the two values below should be used
68     ubyte width;            /// Used for bf* instructions
69     ubyte offset;           /// Used for bf* instructions
70     ubyte indexSize;        /// 0 = w, 1 = l
71 
72 	package this(in Capstone cs, m68k_op_mem internal) {
73 		baseReg = new M68kRegister(cs, internal.base_reg);
74 		indexReg = new M68kRegister(cs, internal.index_reg);
75 		inBaseReg = new M68kRegister(cs, internal.in_base_reg);
76 		inDisp = internal.in_disp;
77 		outDisp = internal.out_disp;
78 		disp = internal.disp;
79 		scale = internal.scale;
80 		bitfield = internal.bitfield;
81 		width = internal.width;
82 		offset = internal.offset;
83 		indexSize = internal.index_size;
84 	}
85 }
86 
87 /// Branch displacement operand data
88 struct M68kOpBrDisp {
89 	int disp;       /// Displacement value
90 	ubyte dispSize; /// Size from m68k_op_br_disp_size type above
91 
92 	package this(m68k_op_br_disp internal) {
93 		disp = internal.disp;
94 		dispSize = internal.disp_size;
95 	}
96 }
97 
98 /// Union of possible operand types
99 union M68kOpValue{
100 	ulong imm;               /// Immediate value for IMM operand
101 	double dimm;             /// Double imm
102 	float simm;              /// Float imm
103 	M68kRegister reg;        /// Register value for REG operand
104 	M68kRegister[2] regPair; /// Register pair in one operand
105 	M68kOpMem mem; 	         /// Data when operand is targeting memory
106 	M68kOpBrDisp brDisp;     /// Data when operand is a branch displacement
107 	uint registerBits;       /// Register bits for movem etc. (always in d0-d7, a0-a7, fp0 - fp7 order)
108 }
109 
110 /// Instruction's operand
111 struct M68kOp {
112 	M68kOpType type;             /// Operand type
113     SafeUnion!M68kOpValue value; /// Operand value of type `type`
114     alias value this;            /// Convenient access to value (as in original bindings)
115 
116 	M68kAddressMode addressMode; /// M68k addressing mode for this op
117 
118     package this(in Capstone cs, cs_m68k_op internal) {
119         type = internal.type.to!M68kOpType;
120         final switch(type) {
121 			case M68kOpType.invalid:
122 				break;
123 			case M68kOpType.reg:
124 				value.reg = new M68kRegister(cs, internal.reg);
125 				break;
126 			case M68kOpType.imm:
127 				value.imm = internal.imm;
128 				break;
129 			case M68kOpType.mem:
130 				value.mem = M68kOpMem(cs, internal.mem);
131 				break;
132 			case M68kOpType.fpSingle:
133 				value.simm = internal.simm;
134 				break;
135 			case M68kOpType.fpDouble:
136 				value.dimm = internal.dimm;
137 				break;
138 			case M68kOpType.regBits:
139 				value.registerBits = internal.register_bits;
140 				break;
141 			case M68kOpType.regPair:
142 				value.regPair = [new M68kRegister(cs, internal.reg_pair.reg_0), new M68kRegister(cs, internal.reg_pair.reg_1)];
143 				break;
144 			case M68kOpType.brDisp:
145 				value.brDisp = M68kOpBrDisp(internal.br_disp);
146 				break;
147 		}
148 		addressMode = internal.address_mode.to!M68kAddressMode;
149 	}
150 }
151 
152 /// Operation size of the current instruction (NOT the actual size of instruction)
153 struct M68kOpSize {
154 	M68kSizeType type; /// Type of size
155 	union {
156 		M68kCpuSize cpuSize; /// Size of CPU instruction
157 		M68kFpuSize fpuSize; /// Size of the FPU instruction
158 	}
159 }
160 
161 /// M68k-specific information about an instruction
162 struct M68kInstructionDetail {
163 	M68kOp[] operands; /// Operands for this instruction.
164 	M68kOpSize opSize; /// Size of data operand works on in bytes (.b, .w, .l, etc)
165 
166 	package this(in Capstone cs, cs_arch_detail arch_detail){
167         auto internal = arch_detail.m68k;
168         foreach(op; internal.operands[0..internal.op_count])
169             operands ~= M68kOp(cs, op);
170     }
171 }
172 
173 //=============================================================================
174 // Constants
175 //=============================================================================
176 
177 /// M68k Addressing Modes
178 enum M68kAddressMode {
179 	none = 0,			    /// No address mode.
180 
181 	reg_direct_data,		/// Register direct - data
182 	reg_direct_addr,		/// Register direct - address
183 
184 	regi_addr,				/// Register indirect - address
185 	regi_addr_post_inc,		/// Register indirect - address with postincrement
186 	regi_addr_pre_dec,		/// Register indirect - address with predecrement
187 	regi_addr_disp,			/// Register indirect - address with displacement
188 
189 	aregi_index_8_bit_disp,	/// Address register indirect with index- 8-bit displacement
190 	aregi_index_base_disp,	/// Address register indirect with index- base displacement
191 
192 	memi_post_index,		/// Memory indirect - postindex
193 	memi_pre_index,			/// Memory indirect - preindex
194 
195 	pci_disp,				/// Program counter indirect - with displacement
196 
197 	pci_index_8_bit_disp,	/// Program counter indirect with index - with 8-bit displacement
198 	pci_index_base_disp,	/// Program counter indirect with index - with base displacement
199 
200 	pc_memi_post_index,		/// Program counter memory indirect - postindexed
201 	pc_memi_pre_index,		/// Program counter memory indirect - preindexed
202 
203 	absolute_data_short,	/// Absolute data addressing  - short
204 	absolute_data_long,		/// Absolute data addressing  - long
205 	immediate,              /// Immediate value
206 
207 	branch_displacement     /// Address as displacement from (pc+2) used by branches
208 }
209 
210 /// Operand type for instruction's operands
211 enum M68kOpType {
212 	invalid = 0, /// Uninitialized
213 	reg,         /// Register operand
214 	imm,         /// Immediate operand
215 	mem,         /// Memory operand
216 	fpSingle,    /// Single precision Floating-Point operand
217 	fpDouble,    /// Double precision Floating-Point operand
218 	regBits,     /// Register bits move
219 	regPair,     /// Register pair in the same op (upper 4 bits for first reg, lower for second)
220 	brDisp       /// Branch displacement
221 }
222 
223 /// Displacement size of branch displacement operand 
224 enum M68kOpBrDispSize {
225 	invalid = 0, /// Uninitialized
226 	byte_ = 1,   /// Signed 8-bit displacement
227 	word = 2,    /// Signed 16-bit displacement
228 	long_ = 4,   /// Signed 32-bit displacement
229 }
230 
231 /// Operation size of the CPU instructions
232 enum M68kCpuSize {
233 	none = 0,	// unsized or unspecified
234 	byte_ = 1,	// 1 byte in size
235 	word = 2,	// 2 bytes in size
236 	long_ = 4,	// 4 bytes in size
237 }
238 
239 /** Operation size of the FPU instructions
240 
241 Notice that FPU instruction can also use CPU sizes if needed
242 */
243 enum M68kFpuSize {
244 	none = 0,		/// Unsized like fsave/frestore
245 	single = 4,		/// 4 byte in size (single float)
246 	double_ = 8,	/// 8 byte in size (double)
247 	extended = 12,	/// 12 byte in size (extended real format)
248 }
249 
250 /// Type of size that is being used for the current instruction
251 enum M68kSizeType {
252 	invalid = 0,
253 
254 	cpu,
255 	fpu,
256 }
257 
258 /// M68k registers and special registers
259 enum M68kRegisterId {
260 	invalid = 0,
261 
262 	d0,
263 	d1,
264 	d2,
265 	d3,
266 	d4,
267 	d5,
268 	d6,
269 	d7,
270 
271 	a0,
272 	a1,
273 	a2,
274 	a3,
275 	a4,
276 	a5,
277 	a6,
278 	a7,
279 
280 	fp0,
281 	fp1,
282 	fp2,
283 	fp3,
284 	fp4,
285 	fp5,
286 	fp6,
287 	fp7,
288 
289 	pc,
290 
291 	sr,
292 	ccr,
293 	sfc,
294 	dfc,
295 	usp,
296 	vbr,
297 	cacr,
298 	caar,
299 	msp,
300 	isp,
301 	tc,
302 	itt0,
303 	itt1,
304 	dtt0,
305 	dtt1,
306 	mmusr,
307 	urp,
308 	srp,
309 
310 	fpcr,
311 	fpsr,
312 	fpiar
313 }
314 
315 /// M68k instruction
316 enum M68kInstructionId {
317 	invalid = 0,
318 
319 	abcd,
320 	add,
321 	adda,
322 	addi,
323 	addq,
324 	addx,
325 	and,
326 	andi,
327 	asl,
328 	asr,
329 	bhs,
330 	blo,
331 	bhi,
332 	bls,
333 	bcc,
334 	bcs,
335 	bne,
336 	beq,
337 	bvc,
338 	bvs,
339 	bpl,
340 	bmi,
341 	bge,
342 	blt,
343 	bgt,
344 	ble,
345 	bra,
346 	bsr,
347 	bchg,
348 	bclr,
349 	bset,
350 	btst,
351 	bfchg,
352 	bfclr,
353 	bfexts,
354 	bfextu,
355 	bfffo,
356 	bfins,
357 	bfset,
358 	bftst,
359 	bkpt,
360 	callm,
361 	cas,
362 	cas2,
363 	chk,
364 	chk2,
365 	clr,
366 	cmp,
367 	cmpa,
368 	cmpi,
369 	cmpm,
370 	cmp2,
371 	cinvl,
372 	cinvp,
373 	cinva,
374 	cpushl,
375 	cpushp,
376 	cpusha,
377 	dbt,
378 	dbf,
379 	dbhi,
380 	dbls,
381 	dbcc,
382 	dbcs,
383 	dbne,
384 	dbeq,
385 	dbvc,
386 	dbvs,
387 	dbpl,
388 	dbmi,
389 	dbge,
390 	dblt,
391 	dbgt,
392 	dble,
393 	dbra,
394 	divs,
395 	divsl,
396 	divu,
397 	divul,
398 	eor,
399 	eori,
400 	exg,
401 	ext,
402 	extb,
403 	fabs,
404 	fsabs,
405 	fdabs,
406 	facos,
407 	fadd,
408 	fsadd,
409 	fdadd,
410 	fasin,
411 	fatan,
412 	fatanh,
413 	fbf,
414 	fbeq,
415 	fbogt,
416 	fboge,
417 	fbolt,
418 	fbole,
419 	fbogl,
420 	fbor,
421 	fbun,
422 	fbueq,
423 	fbugt,
424 	fbuge,
425 	fbult,
426 	fbule,
427 	fbne,
428 	fbt,
429 	fbsf,
430 	fbseq,
431 	fbgt,
432 	fbge,
433 	fblt,
434 	fble,
435 	fbgl,
436 	fbgle,
437 	fbngle,
438 	fbngl,
439 	fbnle,
440 	fbnlt,
441 	fbnge,
442 	fbngt,
443 	fbsne,
444 	fbst,
445 	fcmp,
446 	fcos,
447 	fcosh,
448 	fdbf,
449 	fdbeq,
450 	fdbogt,
451 	fdboge,
452 	fdbolt,
453 	fdbole,
454 	fdbogl,
455 	fdbor,
456 	fdbun,
457 	fdbueq,
458 	fdbugt,
459 	fdbuge,
460 	fdbult,
461 	fdbule,
462 	fdbne,
463 	fdbt,
464 	fdbsf,
465 	fdbseq,
466 	fdbgt,
467 	fdbge,
468 	fdblt,
469 	fdble,
470 	fdbgl,
471 	fdbgle,
472 	fdbngle,
473 	fdbngl,
474 	fdbnle,
475 	fdbnlt,
476 	fdbnge,
477 	fdbngt,
478 	fdbsne,
479 	fdbst,
480 	fdiv,
481 	fsdiv,
482 	fddiv,
483 	fetox,
484 	fetoxm1,
485 	fgetexp,
486 	fgetman,
487 	fint,
488 	fintrz,
489 	flog10,
490 	flog2,
491 	flogn,
492 	flognp1,
493 	fmod,
494 	fmove,
495 	fsmove,
496 	fdmove,
497 	fmovecr,
498 	fmovem,
499 	fmul,
500 	fsmul,
501 	fdmul,
502 	fneg,
503 	fsneg,
504 	fdneg,
505 	fnop,
506 	frem,
507 	frestore,
508 	fsave,
509 	fscale,
510 	fsgldiv,
511 	fsglmul,
512 	fsin,
513 	fsincos,
514 	fsinh,
515 	fsqrt,
516 	fssqrt,
517 	fdsqrt,
518 	fsf,
519 	fsbeq,
520 	fsogt,
521 	fsoge,
522 	fsolt,
523 	fsole,
524 	fsogl,
525 	fsor,
526 	fsun,
527 	fsueq,
528 	fsugt,
529 	fsuge,
530 	fsult,
531 	fsule,
532 	fsne,
533 	fst,
534 	fssf,
535 	fsseq,
536 	fsgt,
537 	fsge,
538 	fslt,
539 	fsle,
540 	fsgl,
541 	fsgle,
542 	fsngle,
543 	fsngl,
544 	fsnle,
545 	fsnlt,
546 	fsnge,
547 	fsngt,
548 	fssne,
549 	fsst,
550 	fsub,
551 	fssub,
552 	fdsub,
553 	ftan,
554 	ftanh,
555 	ftentox,
556 	ftrapf,
557 	ftrapeq,
558 	ftrapogt,
559 	ftrapoge,
560 	ftrapolt,
561 	ftrapole,
562 	ftrapogl,
563 	ftrapor,
564 	ftrapun,
565 	ftrapueq,
566 	ftrapugt,
567 	ftrapuge,
568 	ftrapult,
569 	ftrapule,
570 	ftrapne,
571 	ftrapt,
572 	ftrapsf,
573 	ftrapseq,
574 	ftrapgt,
575 	ftrapge,
576 	ftraplt,
577 	ftraple,
578 	ftrapgl,
579 	ftrapgle,
580 	ftrapngle,
581 	ftrapngl,
582 	ftrapnle,
583 	ftrapnlt,
584 	ftrapnge,
585 	ftrapngt,
586 	ftrapsne,
587 	ftrapst,
588 	ftst,
589 	ftwotox,
590 	halt,
591 	illegal,
592 	jmp,
593 	jsr,
594 	lea,
595 	link,
596 	lpstop,
597 	lsl,
598 	lsr,
599 	move,
600 	movea,
601 	movec,
602 	movem,
603 	movep,
604 	moveq,
605 	moves,
606 	move16,
607 	muls,
608 	mulu,
609 	nbcd,
610 	neg,
611 	negx,
612 	nop,
613 	not,
614 	or,
615 	ori,
616 	pack,
617 	pea,
618 	pflush,
619 	pflusha,
620 	pflushan,
621 	pflushn,
622 	ploadr,
623 	ploadw,
624 	plpar,
625 	plpaw,
626 	pmove,
627 	pmovefd,
628 	ptestr,
629 	ptestw,
630 	pulse,
631 	rems,
632 	remu,
633 	reset,
634 	rol,
635 	ror,
636 	roxl,
637 	roxr,
638 	rtd,
639 	rte,
640 	rtm,
641 	rtr,
642 	rts,
643 	sbcd,
644 	st,
645 	sf,
646 	shi,
647 	sls,
648 	scc,
649 	shs,
650 	scs,
651 	slo,
652 	sne,
653 	seq,
654 	svc,
655 	svs,
656 	spl,
657 	smi,
658 	sge,
659 	slt,
660 	sgt,
661 	sle,
662 	stop,
663 	sub,
664 	suba,
665 	subi,
666 	subq,
667 	subx,
668 	swap,
669 	tas,
670 	trap,
671 	trapv,
672 	trapt,
673 	trapf,
674 	traphi,
675 	trapls,
676 	trapcc,
677 	traphs,
678 	trapcs,
679 	traplo,
680 	trapne,
681 	trapeq,
682 	trapvc,
683 	trapvs,
684 	trappl,
685 	trapmi,
686 	trapge,
687 	traplt,
688 	trapgt,
689 	traple,
690 	tst,
691 	unlk,
692 	unpk,
693 }
694 
695 /// Group of M68k instructions
696 enum M68kInstructionGroupId {
697 	invalid = 0,
698 	jump,
699 	ret = 3,
700 	iret = 5,
701 	branch_relative = 7
702 }