1 /* Capstone Disassembly Engine */
2 /* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
3 
4 #include <stdio.h>
5 #include <capstone/capstone.h>
6 
7 void print_insn_detail_m680x(csh handle, cs_insn *insn);
8 
9 static const char *s_access[] = {
10 	"UNCHANGED", "READ", "WRITE", "READ | WRITE",
11 };
12 
13 
print_read_write_regs(csh handle,cs_detail * detail)14 static void print_read_write_regs(csh handle, cs_detail *detail)
15 {
16 	int i;
17 
18 	if (detail->regs_read_count > 0) {
19 		printf("\treading from regs: ");
20 
21 		for (i = 0; i < detail->regs_read_count; ++i) {
22 			if (i > 0)
23 				printf(", ");
24 
25 			printf("%s", cs_reg_name(handle, detail->regs_read[i]));
26 		}
27 
28 		printf("\n");
29 	}
30 
31 	if (detail->regs_write_count > 0) {
32 		printf("\twriting to regs: ");
33 
34 		for (i = 0; i < detail->regs_write_count; ++i) {
35 			if (i > 0)
36 				printf(", ");
37 
38 			printf("%s", cs_reg_name(handle,
39 					detail->regs_write[i]));
40 		}
41 
42 		printf("\n");
43 	}
44 }
45 
print_insn_detail_m680x(csh handle,cs_insn * insn)46 void print_insn_detail_m680x(csh handle, cs_insn *insn)
47 {
48 	cs_detail *detail = insn->detail;
49 	cs_m680x *m680x = NULL;
50 	int i;
51 
52 	// detail can be NULL on "data" instruction if SKIPDATA option is
53 	// turned ON
54 	if (detail == NULL)
55 		return;
56 
57 	m680x = &detail->m680x;
58 
59 	if (m680x->op_count)
60 		printf("\top_count: %u\n", m680x->op_count);
61 
62 	for (i = 0; i < m680x->op_count; i++) {
63 		cs_m680x_op *op = &(m680x->operands[i]);
64 		const char *comment;
65 
66 		switch ((int)op->type) {
67 		default:
68 			break;
69 
70 		case M680X_OP_REGISTER:
71 			comment = "";
72 
73 			if ((i == 0 && m680x->flags & M680X_FIRST_OP_IN_MNEM) ||
74 				(i == 1 && m680x->flags &
75 					M680X_SECOND_OP_IN_MNEM))
76 				comment = " (in mnemonic)";
77 
78 			printf("\t\toperands[%u].type: REGISTER = %s%s\n", i,
79 				cs_reg_name(handle, op->reg), comment);
80 			break;
81 
82 		case M680X_OP_CONSTANT:
83 			printf("\t\toperands[%u].type: CONSTANT = %u\n", i,
84 				op->const_val);
85 			break;
86 
87 		case M680X_OP_IMMEDIATE:
88 			printf("\t\toperands[%u].type: IMMEDIATE = #%d\n", i,
89 				op->imm);
90 			break;
91 
92 		case M680X_OP_DIRECT:
93 			printf("\t\toperands[%u].type: DIRECT = 0x%02x\n", i,
94 				op->direct_addr);
95 			break;
96 
97 		case M680X_OP_EXTENDED:
98 			printf("\t\toperands[%u].type: EXTENDED %s = 0x%04x\n",
99 				i, op->ext.indirect ? "INDIRECT" : "",
100 				op->ext.address);
101 			break;
102 
103 		case M680X_OP_RELATIVE:
104 			printf("\t\toperands[%u].type: RELATIVE = 0x%04x\n", i,
105 				op->rel.address);
106 			break;
107 
108 		case M680X_OP_INDEXED:
109 			printf("\t\toperands[%u].type: INDEXED%s\n", i,
110 				(op->idx.flags & M680X_IDX_INDIRECT) ?
111 				" INDIRECT" : "");
112 
113 			if (op->idx.base_reg != M680X_REG_INVALID)
114 				printf("\t\t\tbase register: %s\n",
115 					cs_reg_name(handle, op->idx.base_reg));
116 
117 			if (op->idx.offset_reg != M680X_REG_INVALID)
118 				printf("\t\t\toffset register: %s\n",
119 					cs_reg_name(handle, op->idx.offset_reg));
120 
121 			if ((op->idx.offset_bits != 0) &&
122 				(op->idx.offset_reg == M680X_REG_INVALID) &&
123 				!op->idx.inc_dec) {
124 				printf("\t\t\toffset: %d\n", op->idx.offset);
125 
126 				if (op->idx.base_reg == M680X_REG_PC)
127 					printf("\t\t\toffset address: 0x%x\n",
128 						op->idx.offset_addr);
129 
130 				printf("\t\t\toffset bits: %u\n",
131 					op->idx.offset_bits);
132 			}
133 
134 			if (op->idx.inc_dec) {
135 				const char *post_pre = op->idx.flags &
136 					M680X_IDX_POST_INC_DEC ? "post" : "pre";
137 				const char *inc_dec = (op->idx.inc_dec > 0) ?
138 					"increment" : "decrement";
139 
140 				printf("\t\t\t%s %s: %d\n", post_pre, inc_dec,
141 					abs(op->idx.inc_dec));
142 			}
143 
144 			break;
145 		}
146 
147 		if (op->size != 0)
148 			printf("\t\t\tsize: %u\n", op->size);
149 
150 		if (op->access != CS_AC_INVALID)
151 			printf("\t\t\taccess: %s\n", s_access[op->access]);
152 	}
153 
154 	print_read_write_regs(handle, detail);
155 }
156 
157