xref: /aosp_15_r20/external/capstone/arch/M680X/M680XDisassembler.c (revision 9a0e4156d50a75a99ec4f1653a0e9602a5d45c18)
1*9a0e4156SSadaf Ebrahimi /* Capstone Disassembly Engine */
2*9a0e4156SSadaf Ebrahimi /* M680X Backend by Wolfgang Schwotzer <[email protected]> 2017 */
3*9a0e4156SSadaf Ebrahimi 
4*9a0e4156SSadaf Ebrahimi /* ======================================================================== */
5*9a0e4156SSadaf Ebrahimi /* ================================ INCLUDES ============================== */
6*9a0e4156SSadaf Ebrahimi /* ======================================================================== */
7*9a0e4156SSadaf Ebrahimi 
8*9a0e4156SSadaf Ebrahimi #include <stdlib.h>
9*9a0e4156SSadaf Ebrahimi #include <stdio.h>
10*9a0e4156SSadaf Ebrahimi #include <string.h>
11*9a0e4156SSadaf Ebrahimi 
12*9a0e4156SSadaf Ebrahimi #include "../../cs_priv.h"
13*9a0e4156SSadaf Ebrahimi #include "../../utils.h"
14*9a0e4156SSadaf Ebrahimi 
15*9a0e4156SSadaf Ebrahimi #include "../../MCInst.h"
16*9a0e4156SSadaf Ebrahimi #include "../../MCInstrDesc.h"
17*9a0e4156SSadaf Ebrahimi #include "../../MCRegisterInfo.h"
18*9a0e4156SSadaf Ebrahimi #include "M680XInstPrinter.h"
19*9a0e4156SSadaf Ebrahimi #include "M680XDisassembler.h"
20*9a0e4156SSadaf Ebrahimi #include "M680XDisassemblerInternals.h"
21*9a0e4156SSadaf Ebrahimi 
22*9a0e4156SSadaf Ebrahimi #ifdef CAPSTONE_HAS_M680X
23*9a0e4156SSadaf Ebrahimi 
24*9a0e4156SSadaf Ebrahimi #ifndef DECL_SPEC
25*9a0e4156SSadaf Ebrahimi #ifdef _MSC_VER
26*9a0e4156SSadaf Ebrahimi #define DECL_SPEC __cdecl
27*9a0e4156SSadaf Ebrahimi #else
28*9a0e4156SSadaf Ebrahimi #define DECL_SPEC
29*9a0e4156SSadaf Ebrahimi #endif  // _MSC_VER
30*9a0e4156SSadaf Ebrahimi #endif  // DECL_SPEC
31*9a0e4156SSadaf Ebrahimi 
32*9a0e4156SSadaf Ebrahimi /* ======================================================================== */
33*9a0e4156SSadaf Ebrahimi /* ============================ GENERAL DEFINES =========================== */
34*9a0e4156SSadaf Ebrahimi /* ======================================================================== */
35*9a0e4156SSadaf Ebrahimi 
36*9a0e4156SSadaf Ebrahimi /* ======================================================================== */
37*9a0e4156SSadaf Ebrahimi /* =============================== PROTOTYPES ============================= */
38*9a0e4156SSadaf Ebrahimi /* ======================================================================== */
39*9a0e4156SSadaf Ebrahimi 
40*9a0e4156SSadaf Ebrahimi typedef enum insn_hdlr_id {
41*9a0e4156SSadaf Ebrahimi 	illgl_hid,
42*9a0e4156SSadaf Ebrahimi 	rel8_hid,
43*9a0e4156SSadaf Ebrahimi 	rel16_hid,
44*9a0e4156SSadaf Ebrahimi 	imm8_hid,
45*9a0e4156SSadaf Ebrahimi 	imm16_hid,
46*9a0e4156SSadaf Ebrahimi 	imm32_hid,
47*9a0e4156SSadaf Ebrahimi 	dir_hid,
48*9a0e4156SSadaf Ebrahimi 	ext_hid,
49*9a0e4156SSadaf Ebrahimi 	idxX_hid,
50*9a0e4156SSadaf Ebrahimi 	idxY_hid,
51*9a0e4156SSadaf Ebrahimi 	idx09_hid,
52*9a0e4156SSadaf Ebrahimi 	inh_hid,
53*9a0e4156SSadaf Ebrahimi 	rr09_hid,
54*9a0e4156SSadaf Ebrahimi 	rbits_hid,
55*9a0e4156SSadaf Ebrahimi 	bitmv_hid,
56*9a0e4156SSadaf Ebrahimi 	tfm_hid,
57*9a0e4156SSadaf Ebrahimi 	opidx_hid,
58*9a0e4156SSadaf Ebrahimi 	opidxdr_hid,
59*9a0e4156SSadaf Ebrahimi 	idxX0_hid,
60*9a0e4156SSadaf Ebrahimi 	idxX16_hid,
61*9a0e4156SSadaf Ebrahimi 	imm8rel_hid,
62*9a0e4156SSadaf Ebrahimi 	idxS_hid,
63*9a0e4156SSadaf Ebrahimi 	idxS16_hid,
64*9a0e4156SSadaf Ebrahimi 	idxXp_hid,
65*9a0e4156SSadaf Ebrahimi 	idxX0p_hid,
66*9a0e4156SSadaf Ebrahimi 	idx12_hid,
67*9a0e4156SSadaf Ebrahimi 	idx12s_hid,
68*9a0e4156SSadaf Ebrahimi 	rr12_hid,
69*9a0e4156SSadaf Ebrahimi 	loop_hid,
70*9a0e4156SSadaf Ebrahimi 	index_hid,
71*9a0e4156SSadaf Ebrahimi 	imm8i12x_hid,
72*9a0e4156SSadaf Ebrahimi 	imm16i12x_hid,
73*9a0e4156SSadaf Ebrahimi 	exti12x_hid,
74*9a0e4156SSadaf Ebrahimi 	HANDLER_ID_ENDING,
75*9a0e4156SSadaf Ebrahimi } insn_hdlr_id;
76*9a0e4156SSadaf Ebrahimi 
77*9a0e4156SSadaf Ebrahimi // Access modes for the first 4 operands. If there are more than
78*9a0e4156SSadaf Ebrahimi // four operands they use the same access mode as the 4th operand.
79*9a0e4156SSadaf Ebrahimi //
80*9a0e4156SSadaf Ebrahimi // u: unchanged
81*9a0e4156SSadaf Ebrahimi // r: (r)read access
82*9a0e4156SSadaf Ebrahimi // w: (w)write access
83*9a0e4156SSadaf Ebrahimi // m: (m)odify access (= read + write)
84*9a0e4156SSadaf Ebrahimi //
85*9a0e4156SSadaf Ebrahimi typedef enum e_access_mode {
86*9a0e4156SSadaf Ebrahimi 
87*9a0e4156SSadaf Ebrahimi 	uuuu,
88*9a0e4156SSadaf Ebrahimi 	rrrr,
89*9a0e4156SSadaf Ebrahimi 	wwww,
90*9a0e4156SSadaf Ebrahimi 	rwww,
91*9a0e4156SSadaf Ebrahimi 	rrrm,
92*9a0e4156SSadaf Ebrahimi 	rmmm,
93*9a0e4156SSadaf Ebrahimi 	wrrr,
94*9a0e4156SSadaf Ebrahimi 	mrrr,
95*9a0e4156SSadaf Ebrahimi 	mwww,
96*9a0e4156SSadaf Ebrahimi 	mmmm,
97*9a0e4156SSadaf Ebrahimi 	mwrr,
98*9a0e4156SSadaf Ebrahimi 	mmrr,
99*9a0e4156SSadaf Ebrahimi 	wmmm,
100*9a0e4156SSadaf Ebrahimi 	rruu,
101*9a0e4156SSadaf Ebrahimi 	muuu,
102*9a0e4156SSadaf Ebrahimi 	ACCESS_MODE_ENDING,
103*9a0e4156SSadaf Ebrahimi } e_access_mode;
104*9a0e4156SSadaf Ebrahimi 
105*9a0e4156SSadaf Ebrahimi // Access type values are compatible with enum cs_ac_type:
106*9a0e4156SSadaf Ebrahimi typedef enum e_access {
107*9a0e4156SSadaf Ebrahimi 	UNCHANGED = CS_AC_INVALID,
108*9a0e4156SSadaf Ebrahimi 	READ = CS_AC_READ,
109*9a0e4156SSadaf Ebrahimi 	WRITE = CS_AC_WRITE,
110*9a0e4156SSadaf Ebrahimi 	MODIFY = (CS_AC_READ | CS_AC_WRITE),
111*9a0e4156SSadaf Ebrahimi } e_access;
112*9a0e4156SSadaf Ebrahimi 
113*9a0e4156SSadaf Ebrahimi /* Properties of one instruction in PAGE1 (without prefix) */
114*9a0e4156SSadaf Ebrahimi typedef struct inst_page1 {
115*9a0e4156SSadaf Ebrahimi 	m680x_insn insn : 9;
116*9a0e4156SSadaf Ebrahimi 	insn_hdlr_id handler_id1 : 6; /* first instruction handler id */
117*9a0e4156SSadaf Ebrahimi 	insn_hdlr_id handler_id2 : 6; /* second instruction handler id */
118*9a0e4156SSadaf Ebrahimi } inst_page1;
119*9a0e4156SSadaf Ebrahimi 
120*9a0e4156SSadaf Ebrahimi /* Properties of one instruction in any other PAGE X */
121*9a0e4156SSadaf Ebrahimi typedef struct inst_pageX {
122*9a0e4156SSadaf Ebrahimi 	unsigned opcode : 8;
123*9a0e4156SSadaf Ebrahimi 	m680x_insn insn : 9;
124*9a0e4156SSadaf Ebrahimi 	insn_hdlr_id handler_id1 : 6; /* first instruction handler id */
125*9a0e4156SSadaf Ebrahimi 	insn_hdlr_id handler_id2 : 6; /* second instruction handler id */
126*9a0e4156SSadaf Ebrahimi } inst_pageX;
127*9a0e4156SSadaf Ebrahimi 
128*9a0e4156SSadaf Ebrahimi typedef struct insn_props {
129*9a0e4156SSadaf Ebrahimi 	unsigned group : 4;
130*9a0e4156SSadaf Ebrahimi 	e_access_mode access_mode : 5;
131*9a0e4156SSadaf Ebrahimi 	m680x_reg reg0 : 5;
132*9a0e4156SSadaf Ebrahimi 	m680x_reg reg1 : 5;
133*9a0e4156SSadaf Ebrahimi 	bool cc_modified : 1;
134*9a0e4156SSadaf Ebrahimi 	bool update_reg_access : 1;
135*9a0e4156SSadaf Ebrahimi } insn_props;
136*9a0e4156SSadaf Ebrahimi 
137*9a0e4156SSadaf Ebrahimi #include "m6800.inc"
138*9a0e4156SSadaf Ebrahimi #include "m6801.inc"
139*9a0e4156SSadaf Ebrahimi #include "hd6301.inc"
140*9a0e4156SSadaf Ebrahimi #include "m6811.inc"
141*9a0e4156SSadaf Ebrahimi #include "cpu12.inc"
142*9a0e4156SSadaf Ebrahimi #include "m6805.inc"
143*9a0e4156SSadaf Ebrahimi #include "m6808.inc"
144*9a0e4156SSadaf Ebrahimi #include "hcs08.inc"
145*9a0e4156SSadaf Ebrahimi #include "m6809.inc"
146*9a0e4156SSadaf Ebrahimi #include "hd6309.inc"
147*9a0e4156SSadaf Ebrahimi 
148*9a0e4156SSadaf Ebrahimi #include "insn_props.inc"
149*9a0e4156SSadaf Ebrahimi 
150*9a0e4156SSadaf Ebrahimi //////////////////////////////////////////////////////////////////////////////
151*9a0e4156SSadaf Ebrahimi 
152*9a0e4156SSadaf Ebrahimi // M680X instuctions have 1 up to 8 bytes (CPU12: MOVW IDX2,IDX2).
153*9a0e4156SSadaf Ebrahimi // A reader is needed to read a byte or word from a given memory address.
154*9a0e4156SSadaf Ebrahimi // See also X86 reader(...)
read_byte(const m680x_info * info,uint8_t * byte,uint16_t address)155*9a0e4156SSadaf Ebrahimi static bool read_byte(const m680x_info *info, uint8_t *byte, uint16_t address)
156*9a0e4156SSadaf Ebrahimi {
157*9a0e4156SSadaf Ebrahimi 	if (address - info->offset >= info->size)
158*9a0e4156SSadaf Ebrahimi 		// out of code buffer range
159*9a0e4156SSadaf Ebrahimi 		return false;
160*9a0e4156SSadaf Ebrahimi 
161*9a0e4156SSadaf Ebrahimi 	*byte = info->code[address - info->offset];
162*9a0e4156SSadaf Ebrahimi 
163*9a0e4156SSadaf Ebrahimi 	return true;
164*9a0e4156SSadaf Ebrahimi }
165*9a0e4156SSadaf Ebrahimi 
read_byte_sign_extended(const m680x_info * info,int16_t * word,uint16_t address)166*9a0e4156SSadaf Ebrahimi static bool read_byte_sign_extended(const m680x_info *info, int16_t *word,
167*9a0e4156SSadaf Ebrahimi 	uint16_t address)
168*9a0e4156SSadaf Ebrahimi {
169*9a0e4156SSadaf Ebrahimi 	if (address - info->offset >= info->size)
170*9a0e4156SSadaf Ebrahimi 		// out of code buffer range
171*9a0e4156SSadaf Ebrahimi 		return false;
172*9a0e4156SSadaf Ebrahimi 
173*9a0e4156SSadaf Ebrahimi 	*word = (int16_t) info->code[address - info->offset];
174*9a0e4156SSadaf Ebrahimi 
175*9a0e4156SSadaf Ebrahimi 	if (*word & 0x80)
176*9a0e4156SSadaf Ebrahimi 		*word |= 0xFF00;
177*9a0e4156SSadaf Ebrahimi 
178*9a0e4156SSadaf Ebrahimi 	return true;
179*9a0e4156SSadaf Ebrahimi }
180*9a0e4156SSadaf Ebrahimi 
read_word(const m680x_info * info,uint16_t * word,uint16_t address)181*9a0e4156SSadaf Ebrahimi static bool read_word(const m680x_info *info, uint16_t *word, uint16_t address)
182*9a0e4156SSadaf Ebrahimi {
183*9a0e4156SSadaf Ebrahimi 	if (address + 1 - info->offset >= info->size)
184*9a0e4156SSadaf Ebrahimi 		// out of code buffer range
185*9a0e4156SSadaf Ebrahimi 		return false;
186*9a0e4156SSadaf Ebrahimi 
187*9a0e4156SSadaf Ebrahimi 	*word = (uint16_t)info->code[address - info->offset] << 8;
188*9a0e4156SSadaf Ebrahimi 	*word |= (uint16_t)info->code[address + 1 - info->offset];
189*9a0e4156SSadaf Ebrahimi 
190*9a0e4156SSadaf Ebrahimi 	return true;
191*9a0e4156SSadaf Ebrahimi }
192*9a0e4156SSadaf Ebrahimi 
read_sdword(const m680x_info * info,int32_t * sdword,uint16_t address)193*9a0e4156SSadaf Ebrahimi static bool read_sdword(const m680x_info *info, int32_t *sdword,
194*9a0e4156SSadaf Ebrahimi 	uint16_t address)
195*9a0e4156SSadaf Ebrahimi {
196*9a0e4156SSadaf Ebrahimi 	if (address + 3 - info->offset >= info->size)
197*9a0e4156SSadaf Ebrahimi 		// out of code buffer range
198*9a0e4156SSadaf Ebrahimi 		return false;
199*9a0e4156SSadaf Ebrahimi 
200*9a0e4156SSadaf Ebrahimi 	*sdword = (uint32_t)info->code[address - info->offset] << 24;
201*9a0e4156SSadaf Ebrahimi 	*sdword |= (uint32_t)info->code[address + 1 - info->offset] << 16;
202*9a0e4156SSadaf Ebrahimi 	*sdword |= (uint32_t)info->code[address + 2 - info->offset] << 8;
203*9a0e4156SSadaf Ebrahimi 	*sdword |= (uint32_t)info->code[address + 3 - info->offset];
204*9a0e4156SSadaf Ebrahimi 
205*9a0e4156SSadaf Ebrahimi 	return true;
206*9a0e4156SSadaf Ebrahimi }
207*9a0e4156SSadaf Ebrahimi 
208*9a0e4156SSadaf Ebrahimi // For PAGE2 and PAGE3 opcodes when using an an array of inst_page1 most
209*9a0e4156SSadaf Ebrahimi // entries have M680X_INS_ILLGL. To avoid wasting memory an inst_pageX is
210*9a0e4156SSadaf Ebrahimi // used which contains the opcode. Using a binary search for the right opcode
211*9a0e4156SSadaf Ebrahimi // is much faster (= O(log n) ) in comparison to a linear search ( = O(n) ).
binary_search(const inst_pageX * const inst_pageX_table,int table_size,uint8_t opcode)212*9a0e4156SSadaf Ebrahimi static int binary_search(const inst_pageX *const inst_pageX_table,
213*9a0e4156SSadaf Ebrahimi 	int table_size, uint8_t opcode)
214*9a0e4156SSadaf Ebrahimi {
215*9a0e4156SSadaf Ebrahimi 	int first = 0;
216*9a0e4156SSadaf Ebrahimi 	int last = table_size - 1;
217*9a0e4156SSadaf Ebrahimi 	int middle = (first + last) / 2;
218*9a0e4156SSadaf Ebrahimi 
219*9a0e4156SSadaf Ebrahimi 	while (first <= last) {
220*9a0e4156SSadaf Ebrahimi 		if (inst_pageX_table[middle].opcode < opcode) {
221*9a0e4156SSadaf Ebrahimi 			first = middle + 1;
222*9a0e4156SSadaf Ebrahimi 		}
223*9a0e4156SSadaf Ebrahimi 		else if (inst_pageX_table[middle].opcode == opcode) {
224*9a0e4156SSadaf Ebrahimi 			return middle;  /* item found */
225*9a0e4156SSadaf Ebrahimi 		}
226*9a0e4156SSadaf Ebrahimi 		else
227*9a0e4156SSadaf Ebrahimi 			last = middle - 1;
228*9a0e4156SSadaf Ebrahimi 
229*9a0e4156SSadaf Ebrahimi 		middle = (first + last) / 2;
230*9a0e4156SSadaf Ebrahimi 	}
231*9a0e4156SSadaf Ebrahimi 
232*9a0e4156SSadaf Ebrahimi 	if (first > last)
233*9a0e4156SSadaf Ebrahimi 		return -1;  /* item not found */
234*9a0e4156SSadaf Ebrahimi 
235*9a0e4156SSadaf Ebrahimi 	return -2;
236*9a0e4156SSadaf Ebrahimi }
237*9a0e4156SSadaf Ebrahimi 
M680X_get_insn_id(cs_struct * handle,cs_insn * insn,unsigned int id)238*9a0e4156SSadaf Ebrahimi void M680X_get_insn_id(cs_struct *handle, cs_insn *insn, unsigned int id)
239*9a0e4156SSadaf Ebrahimi {
240*9a0e4156SSadaf Ebrahimi 	const m680x_info *const info = (const m680x_info *)handle->printer_info;
241*9a0e4156SSadaf Ebrahimi 	const cpu_tables *cpu = info->cpu;
242*9a0e4156SSadaf Ebrahimi 	uint8_t insn_prefix = (id >> 8) & 0xff;
243*9a0e4156SSadaf Ebrahimi 	int index;
244*9a0e4156SSadaf Ebrahimi 	int i;
245*9a0e4156SSadaf Ebrahimi 
246*9a0e4156SSadaf Ebrahimi 	insn->id = M680X_INS_ILLGL;
247*9a0e4156SSadaf Ebrahimi 
248*9a0e4156SSadaf Ebrahimi 	for (i = 0; i < ARR_SIZE(cpu->pageX_prefix); ++i) {
249*9a0e4156SSadaf Ebrahimi 		if (cpu->pageX_table_size[i] == 0 ||
250*9a0e4156SSadaf Ebrahimi 			(cpu->inst_pageX_table[i] == NULL))
251*9a0e4156SSadaf Ebrahimi 			break;
252*9a0e4156SSadaf Ebrahimi 
253*9a0e4156SSadaf Ebrahimi 		if (cpu->pageX_prefix[i] == insn_prefix) {
254*9a0e4156SSadaf Ebrahimi 			index = binary_search(cpu->inst_pageX_table[i],
255*9a0e4156SSadaf Ebrahimi 					cpu->pageX_table_size[i], id & 0xff);
256*9a0e4156SSadaf Ebrahimi 			insn->id = (index >= 0) ?
257*9a0e4156SSadaf Ebrahimi 				cpu->inst_pageX_table[i][index].insn :
258*9a0e4156SSadaf Ebrahimi 				M680X_INS_ILLGL;
259*9a0e4156SSadaf Ebrahimi 			return;
260*9a0e4156SSadaf Ebrahimi 		}
261*9a0e4156SSadaf Ebrahimi 	}
262*9a0e4156SSadaf Ebrahimi 
263*9a0e4156SSadaf Ebrahimi 	if (insn_prefix != 0)
264*9a0e4156SSadaf Ebrahimi 		return;
265*9a0e4156SSadaf Ebrahimi 
266*9a0e4156SSadaf Ebrahimi 	insn->id = cpu->inst_page1_table[id].insn;
267*9a0e4156SSadaf Ebrahimi 
268*9a0e4156SSadaf Ebrahimi 	if (insn->id != M680X_INS_ILLGL)
269*9a0e4156SSadaf Ebrahimi 		return;
270*9a0e4156SSadaf Ebrahimi 
271*9a0e4156SSadaf Ebrahimi 	// Check if opcode byte is present in an overlay table
272*9a0e4156SSadaf Ebrahimi 	for (i = 0; i < ARR_SIZE(cpu->overlay_table_size); ++i) {
273*9a0e4156SSadaf Ebrahimi 		if (cpu->overlay_table_size[i] == 0 ||
274*9a0e4156SSadaf Ebrahimi 			(cpu->inst_overlay_table[i] == NULL))
275*9a0e4156SSadaf Ebrahimi 			break;
276*9a0e4156SSadaf Ebrahimi 
277*9a0e4156SSadaf Ebrahimi 		if ((index = binary_search(cpu->inst_overlay_table[i],
278*9a0e4156SSadaf Ebrahimi 						cpu->overlay_table_size[i],
279*9a0e4156SSadaf Ebrahimi 						id & 0xff)) >= 0) {
280*9a0e4156SSadaf Ebrahimi 			insn->id = cpu->inst_overlay_table[i][index].insn;
281*9a0e4156SSadaf Ebrahimi 			return;
282*9a0e4156SSadaf Ebrahimi 		}
283*9a0e4156SSadaf Ebrahimi 	}
284*9a0e4156SSadaf Ebrahimi }
285*9a0e4156SSadaf Ebrahimi 
add_insn_group(cs_detail * detail,m680x_group_type group)286*9a0e4156SSadaf Ebrahimi static void add_insn_group(cs_detail *detail, m680x_group_type group)
287*9a0e4156SSadaf Ebrahimi {
288*9a0e4156SSadaf Ebrahimi 	if (detail != NULL &&
289*9a0e4156SSadaf Ebrahimi 		(group != M680X_GRP_INVALID) && (group != M680X_GRP_ENDING))
290*9a0e4156SSadaf Ebrahimi 		detail->groups[detail->groups_count++] = (uint8_t)group;
291*9a0e4156SSadaf Ebrahimi }
292*9a0e4156SSadaf Ebrahimi 
exists_reg_list(uint16_t * regs,uint8_t count,m680x_reg reg)293*9a0e4156SSadaf Ebrahimi static bool exists_reg_list(uint16_t *regs, uint8_t count, m680x_reg reg)
294*9a0e4156SSadaf Ebrahimi {
295*9a0e4156SSadaf Ebrahimi 	uint8_t i;
296*9a0e4156SSadaf Ebrahimi 
297*9a0e4156SSadaf Ebrahimi 	for (i = 0; i < count; ++i) {
298*9a0e4156SSadaf Ebrahimi 		if (regs[i] == (uint16_t)reg)
299*9a0e4156SSadaf Ebrahimi 			return true;
300*9a0e4156SSadaf Ebrahimi 	}
301*9a0e4156SSadaf Ebrahimi 
302*9a0e4156SSadaf Ebrahimi 	return false;
303*9a0e4156SSadaf Ebrahimi }
304*9a0e4156SSadaf Ebrahimi 
add_reg_to_rw_list(MCInst * MI,m680x_reg reg,e_access access)305*9a0e4156SSadaf Ebrahimi static void add_reg_to_rw_list(MCInst *MI, m680x_reg reg, e_access access)
306*9a0e4156SSadaf Ebrahimi {
307*9a0e4156SSadaf Ebrahimi 	cs_detail *detail = MI->flat_insn->detail;
308*9a0e4156SSadaf Ebrahimi 
309*9a0e4156SSadaf Ebrahimi 	if (detail == NULL || (reg == M680X_REG_INVALID))
310*9a0e4156SSadaf Ebrahimi 		return;
311*9a0e4156SSadaf Ebrahimi 
312*9a0e4156SSadaf Ebrahimi 	switch (access) {
313*9a0e4156SSadaf Ebrahimi 	case MODIFY:
314*9a0e4156SSadaf Ebrahimi 		if (!exists_reg_list(detail->regs_read,
315*9a0e4156SSadaf Ebrahimi 				detail->regs_read_count, reg))
316*9a0e4156SSadaf Ebrahimi 			detail->regs_read[detail->regs_read_count++] =
317*9a0e4156SSadaf Ebrahimi 				(uint16_t)reg;
318*9a0e4156SSadaf Ebrahimi 
319*9a0e4156SSadaf Ebrahimi 	// intentionally fall through
320*9a0e4156SSadaf Ebrahimi 
321*9a0e4156SSadaf Ebrahimi 	case WRITE:
322*9a0e4156SSadaf Ebrahimi 		if (!exists_reg_list(detail->regs_write,
323*9a0e4156SSadaf Ebrahimi 				detail->regs_write_count, reg))
324*9a0e4156SSadaf Ebrahimi 			detail->regs_write[detail->regs_write_count++] =
325*9a0e4156SSadaf Ebrahimi 				(uint16_t)reg;
326*9a0e4156SSadaf Ebrahimi 
327*9a0e4156SSadaf Ebrahimi 		break;
328*9a0e4156SSadaf Ebrahimi 
329*9a0e4156SSadaf Ebrahimi 	case READ:
330*9a0e4156SSadaf Ebrahimi 		if (!exists_reg_list(detail->regs_read,
331*9a0e4156SSadaf Ebrahimi 				detail->regs_read_count, reg))
332*9a0e4156SSadaf Ebrahimi 			detail->regs_read[detail->regs_read_count++] =
333*9a0e4156SSadaf Ebrahimi 				(uint16_t)reg;
334*9a0e4156SSadaf Ebrahimi 
335*9a0e4156SSadaf Ebrahimi 		break;
336*9a0e4156SSadaf Ebrahimi 
337*9a0e4156SSadaf Ebrahimi 	case UNCHANGED:
338*9a0e4156SSadaf Ebrahimi 	default:
339*9a0e4156SSadaf Ebrahimi 		break;
340*9a0e4156SSadaf Ebrahimi 	}
341*9a0e4156SSadaf Ebrahimi }
342*9a0e4156SSadaf Ebrahimi 
update_am_reg_list(MCInst * MI,m680x_info * info,cs_m680x_op * op,e_access access)343*9a0e4156SSadaf Ebrahimi static void update_am_reg_list(MCInst *MI, m680x_info *info, cs_m680x_op *op,
344*9a0e4156SSadaf Ebrahimi 	e_access access)
345*9a0e4156SSadaf Ebrahimi {
346*9a0e4156SSadaf Ebrahimi 	if (MI->flat_insn->detail == NULL)
347*9a0e4156SSadaf Ebrahimi 		return;
348*9a0e4156SSadaf Ebrahimi 
349*9a0e4156SSadaf Ebrahimi 	switch (op->type) {
350*9a0e4156SSadaf Ebrahimi 	case M680X_OP_REGISTER:
351*9a0e4156SSadaf Ebrahimi 		add_reg_to_rw_list(MI, op->reg, access);
352*9a0e4156SSadaf Ebrahimi 		break;
353*9a0e4156SSadaf Ebrahimi 
354*9a0e4156SSadaf Ebrahimi 	case M680X_OP_INDEXED:
355*9a0e4156SSadaf Ebrahimi 		add_reg_to_rw_list(MI, op->idx.base_reg, READ);
356*9a0e4156SSadaf Ebrahimi 
357*9a0e4156SSadaf Ebrahimi 		if (op->idx.base_reg == M680X_REG_X &&
358*9a0e4156SSadaf Ebrahimi 			info->cpu->reg_byte_size[M680X_REG_H])
359*9a0e4156SSadaf Ebrahimi 			add_reg_to_rw_list(MI, M680X_REG_H, READ);
360*9a0e4156SSadaf Ebrahimi 
361*9a0e4156SSadaf Ebrahimi 
362*9a0e4156SSadaf Ebrahimi 		if (op->idx.offset_reg != M680X_REG_INVALID)
363*9a0e4156SSadaf Ebrahimi 			add_reg_to_rw_list(MI, op->idx.offset_reg, READ);
364*9a0e4156SSadaf Ebrahimi 
365*9a0e4156SSadaf Ebrahimi 		if (op->idx.inc_dec) {
366*9a0e4156SSadaf Ebrahimi 			add_reg_to_rw_list(MI, op->idx.base_reg, WRITE);
367*9a0e4156SSadaf Ebrahimi 
368*9a0e4156SSadaf Ebrahimi 			if (op->idx.base_reg == M680X_REG_X &&
369*9a0e4156SSadaf Ebrahimi 				info->cpu->reg_byte_size[M680X_REG_H])
370*9a0e4156SSadaf Ebrahimi 				add_reg_to_rw_list(MI, M680X_REG_H, WRITE);
371*9a0e4156SSadaf Ebrahimi 		}
372*9a0e4156SSadaf Ebrahimi 
373*9a0e4156SSadaf Ebrahimi 		break;
374*9a0e4156SSadaf Ebrahimi 
375*9a0e4156SSadaf Ebrahimi 	default:
376*9a0e4156SSadaf Ebrahimi 		break;
377*9a0e4156SSadaf Ebrahimi 	}
378*9a0e4156SSadaf Ebrahimi }
379*9a0e4156SSadaf Ebrahimi 
380*9a0e4156SSadaf Ebrahimi static const e_access g_access_mode_to_access[4][15] = {
381*9a0e4156SSadaf Ebrahimi 	{
382*9a0e4156SSadaf Ebrahimi 		UNCHANGED, READ, WRITE, READ,  READ, READ,   WRITE, MODIFY,
383*9a0e4156SSadaf Ebrahimi 		MODIFY, MODIFY, MODIFY, MODIFY, WRITE, READ, MODIFY,
384*9a0e4156SSadaf Ebrahimi 	},
385*9a0e4156SSadaf Ebrahimi 	{
386*9a0e4156SSadaf Ebrahimi 		UNCHANGED, READ, WRITE, WRITE, READ, MODIFY, READ,  READ,
387*9a0e4156SSadaf Ebrahimi 		WRITE, MODIFY, WRITE, MODIFY, MODIFY, READ, UNCHANGED,
388*9a0e4156SSadaf Ebrahimi 	},
389*9a0e4156SSadaf Ebrahimi 	{
390*9a0e4156SSadaf Ebrahimi 		UNCHANGED, READ, WRITE, WRITE, READ, MODIFY, READ,  READ,
391*9a0e4156SSadaf Ebrahimi 		WRITE, MODIFY, READ, READ, MODIFY, UNCHANGED, UNCHANGED,
392*9a0e4156SSadaf Ebrahimi 	},
393*9a0e4156SSadaf Ebrahimi 	{
394*9a0e4156SSadaf Ebrahimi 		UNCHANGED, READ, WRITE, WRITE, MODIFY, MODIFY, READ, READ,
395*9a0e4156SSadaf Ebrahimi 		WRITE, MODIFY, READ, READ, MODIFY, UNCHANGED, UNCHANGED,
396*9a0e4156SSadaf Ebrahimi 	},
397*9a0e4156SSadaf Ebrahimi };
398*9a0e4156SSadaf Ebrahimi 
get_access(int operator_index,e_access_mode access_mode)399*9a0e4156SSadaf Ebrahimi static e_access get_access(int operator_index, e_access_mode access_mode)
400*9a0e4156SSadaf Ebrahimi {
401*9a0e4156SSadaf Ebrahimi 	int idx = (operator_index > 3) ? 3 : operator_index;
402*9a0e4156SSadaf Ebrahimi 
403*9a0e4156SSadaf Ebrahimi 	return g_access_mode_to_access[idx][access_mode];
404*9a0e4156SSadaf Ebrahimi }
405*9a0e4156SSadaf Ebrahimi 
build_regs_read_write_counts(MCInst * MI,m680x_info * info,e_access_mode access_mode)406*9a0e4156SSadaf Ebrahimi static void build_regs_read_write_counts(MCInst *MI, m680x_info *info,
407*9a0e4156SSadaf Ebrahimi 	e_access_mode access_mode)
408*9a0e4156SSadaf Ebrahimi {
409*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
410*9a0e4156SSadaf Ebrahimi 	int i;
411*9a0e4156SSadaf Ebrahimi 
412*9a0e4156SSadaf Ebrahimi 	if (MI->flat_insn->detail == NULL || (!m680x->op_count))
413*9a0e4156SSadaf Ebrahimi 		return;
414*9a0e4156SSadaf Ebrahimi 
415*9a0e4156SSadaf Ebrahimi 	for (i = 0; i < m680x->op_count; ++i) {
416*9a0e4156SSadaf Ebrahimi 
417*9a0e4156SSadaf Ebrahimi 		e_access access = get_access(i, access_mode);
418*9a0e4156SSadaf Ebrahimi 		update_am_reg_list(MI, info, &m680x->operands[i], access);
419*9a0e4156SSadaf Ebrahimi 	}
420*9a0e4156SSadaf Ebrahimi }
421*9a0e4156SSadaf Ebrahimi 
add_operators_access(MCInst * MI,m680x_info * info,e_access_mode access_mode)422*9a0e4156SSadaf Ebrahimi static void add_operators_access(MCInst *MI, m680x_info *info,
423*9a0e4156SSadaf Ebrahimi 	e_access_mode access_mode)
424*9a0e4156SSadaf Ebrahimi {
425*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
426*9a0e4156SSadaf Ebrahimi 	int offset = 0;
427*9a0e4156SSadaf Ebrahimi 	int i;
428*9a0e4156SSadaf Ebrahimi 
429*9a0e4156SSadaf Ebrahimi 	if (MI->flat_insn->detail == NULL || (!m680x->op_count) ||
430*9a0e4156SSadaf Ebrahimi 		(access_mode == uuuu))
431*9a0e4156SSadaf Ebrahimi 		return;
432*9a0e4156SSadaf Ebrahimi 
433*9a0e4156SSadaf Ebrahimi 	for (i = 0; i < m680x->op_count; ++i) {
434*9a0e4156SSadaf Ebrahimi 		e_access access;
435*9a0e4156SSadaf Ebrahimi 
436*9a0e4156SSadaf Ebrahimi 		// Ugly fix: MULD has a register operand, an immediate operand
437*9a0e4156SSadaf Ebrahimi 		// AND an implicitly changed register W
438*9a0e4156SSadaf Ebrahimi 		if (info->insn == M680X_INS_MULD && (i == 1))
439*9a0e4156SSadaf Ebrahimi 			offset = 1;
440*9a0e4156SSadaf Ebrahimi 
441*9a0e4156SSadaf Ebrahimi 		access = get_access(i + offset, access_mode);
442*9a0e4156SSadaf Ebrahimi 		m680x->operands[i].access = access;
443*9a0e4156SSadaf Ebrahimi 	}
444*9a0e4156SSadaf Ebrahimi }
445*9a0e4156SSadaf Ebrahimi 
446*9a0e4156SSadaf Ebrahimi typedef struct insn_to_changed_regs {
447*9a0e4156SSadaf Ebrahimi 	m680x_insn insn;
448*9a0e4156SSadaf Ebrahimi 	e_access_mode access_mode;
449*9a0e4156SSadaf Ebrahimi 	m680x_reg regs[10];
450*9a0e4156SSadaf Ebrahimi } insn_to_changed_regs;
451*9a0e4156SSadaf Ebrahimi 
set_changed_regs_read_write_counts(MCInst * MI,m680x_info * info)452*9a0e4156SSadaf Ebrahimi static void set_changed_regs_read_write_counts(MCInst *MI, m680x_info *info)
453*9a0e4156SSadaf Ebrahimi {
454*9a0e4156SSadaf Ebrahimi 	//TABLE
455*9a0e4156SSadaf Ebrahimi #define EOL M680X_REG_INVALID
456*9a0e4156SSadaf Ebrahimi 	static const insn_to_changed_regs changed_regs[] = {
457*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_BSR, mmmm, { M680X_REG_S, EOL } },
458*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_CALL, mmmm, { M680X_REG_S, EOL } },
459*9a0e4156SSadaf Ebrahimi 		{
460*9a0e4156SSadaf Ebrahimi 			M680X_INS_CWAI, mrrr, {
461*9a0e4156SSadaf Ebrahimi 				M680X_REG_S, M680X_REG_PC, M680X_REG_U,
462*9a0e4156SSadaf Ebrahimi 				M680X_REG_Y, M680X_REG_X, M680X_REG_DP,
463*9a0e4156SSadaf Ebrahimi 				M680X_REG_D, M680X_REG_CC, EOL
464*9a0e4156SSadaf Ebrahimi 			},
465*9a0e4156SSadaf Ebrahimi 		},
466*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_DAA, mrrr, { M680X_REG_A, EOL } },
467*9a0e4156SSadaf Ebrahimi 		{
468*9a0e4156SSadaf Ebrahimi 			M680X_INS_DIV, mmrr, {
469*9a0e4156SSadaf Ebrahimi 				M680X_REG_A, M680X_REG_H, M680X_REG_X, EOL
470*9a0e4156SSadaf Ebrahimi 			}
471*9a0e4156SSadaf Ebrahimi 		},
472*9a0e4156SSadaf Ebrahimi 		{
473*9a0e4156SSadaf Ebrahimi 			M680X_INS_EDIV, mmrr, {
474*9a0e4156SSadaf Ebrahimi 				M680X_REG_D, M680X_REG_Y, M680X_REG_X, EOL
475*9a0e4156SSadaf Ebrahimi 			}
476*9a0e4156SSadaf Ebrahimi 		},
477*9a0e4156SSadaf Ebrahimi 		{
478*9a0e4156SSadaf Ebrahimi 			M680X_INS_EDIVS, mmrr, {
479*9a0e4156SSadaf Ebrahimi 				M680X_REG_D, M680X_REG_Y, M680X_REG_X, EOL
480*9a0e4156SSadaf Ebrahimi 			}
481*9a0e4156SSadaf Ebrahimi 		},
482*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_EMACS, mrrr, { M680X_REG_X, M680X_REG_Y, EOL } },
483*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_EMAXM, rrrr, { M680X_REG_D, EOL } },
484*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_EMINM, rrrr, { M680X_REG_D, EOL } },
485*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_EMUL, mmrr, { M680X_REG_D, M680X_REG_Y, EOL } },
486*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_EMULS, mmrr, { M680X_REG_D, M680X_REG_Y, EOL } },
487*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_ETBL, wmmm, { M680X_REG_A, M680X_REG_B, EOL } },
488*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_FDIV, mmmm, { M680X_REG_D, M680X_REG_X, EOL } },
489*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_IDIV, mmmm, { M680X_REG_D, M680X_REG_X, EOL } },
490*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_IDIVS, mmmm, { M680X_REG_D, M680X_REG_X, EOL } },
491*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_JSR, mmmm, { M680X_REG_S, EOL } },
492*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_LBSR, mmmm, { M680X_REG_S, EOL } },
493*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_MAXM, rrrr, { M680X_REG_A, EOL } },
494*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_MINM, rrrr, { M680X_REG_A, EOL } },
495*9a0e4156SSadaf Ebrahimi 		{
496*9a0e4156SSadaf Ebrahimi 			M680X_INS_MEM, mmrr, {
497*9a0e4156SSadaf Ebrahimi 				M680X_REG_X, M680X_REG_Y, M680X_REG_A, EOL
498*9a0e4156SSadaf Ebrahimi 			}
499*9a0e4156SSadaf Ebrahimi 		},
500*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_MUL, mmmm, { M680X_REG_A, M680X_REG_B, EOL } },
501*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_MULD, mwrr, { M680X_REG_D, M680X_REG_W, EOL } },
502*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PSHA, rmmm, { M680X_REG_A, M680X_REG_S, EOL } },
503*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PSHB, rmmm, { M680X_REG_B, M680X_REG_S, EOL } },
504*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PSHC, rmmm, { M680X_REG_CC, M680X_REG_S, EOL } },
505*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PSHD, rmmm, { M680X_REG_D, M680X_REG_S, EOL } },
506*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PSHH, rmmm, { M680X_REG_H, M680X_REG_S, EOL } },
507*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PSHX, rmmm, { M680X_REG_X, M680X_REG_S, EOL } },
508*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PSHY, rmmm, { M680X_REG_Y, M680X_REG_S, EOL } },
509*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PULA, wmmm, { M680X_REG_A, M680X_REG_S, EOL } },
510*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PULB, wmmm, { M680X_REG_B, M680X_REG_S, EOL } },
511*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PULC, wmmm, { M680X_REG_CC, M680X_REG_S, EOL } },
512*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PULD, wmmm, { M680X_REG_D, M680X_REG_S, EOL } },
513*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PULH, wmmm, { M680X_REG_H, M680X_REG_S, EOL } },
514*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PULX, wmmm, { M680X_REG_X, M680X_REG_S, EOL } },
515*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_PULY, wmmm, { M680X_REG_Y, M680X_REG_S, EOL } },
516*9a0e4156SSadaf Ebrahimi 		{
517*9a0e4156SSadaf Ebrahimi 			M680X_INS_REV, mmrr, {
518*9a0e4156SSadaf Ebrahimi 				M680X_REG_A, M680X_REG_X, M680X_REG_Y, EOL
519*9a0e4156SSadaf Ebrahimi 			}
520*9a0e4156SSadaf Ebrahimi 		},
521*9a0e4156SSadaf Ebrahimi 		{
522*9a0e4156SSadaf Ebrahimi 			M680X_INS_REVW, mmmm, {
523*9a0e4156SSadaf Ebrahimi 				M680X_REG_A, M680X_REG_X, M680X_REG_Y, EOL
524*9a0e4156SSadaf Ebrahimi 			}
525*9a0e4156SSadaf Ebrahimi 		},
526*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_RTC, mwww, { M680X_REG_S, M680X_REG_PC, EOL } },
527*9a0e4156SSadaf Ebrahimi 		{
528*9a0e4156SSadaf Ebrahimi 			M680X_INS_RTI, mwww, {
529*9a0e4156SSadaf Ebrahimi 				M680X_REG_S, M680X_REG_CC, M680X_REG_B,
530*9a0e4156SSadaf Ebrahimi 				M680X_REG_A, M680X_REG_DP, M680X_REG_X,
531*9a0e4156SSadaf Ebrahimi 				M680X_REG_Y, M680X_REG_U, M680X_REG_PC,
532*9a0e4156SSadaf Ebrahimi 				EOL
533*9a0e4156SSadaf Ebrahimi 			},
534*9a0e4156SSadaf Ebrahimi 		},
535*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_RTS, mwww, { M680X_REG_S, M680X_REG_PC, EOL } },
536*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_SEX, wrrr, { M680X_REG_A, M680X_REG_B, EOL } },
537*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_SEXW, rwww, { M680X_REG_W, M680X_REG_D, EOL } },
538*9a0e4156SSadaf Ebrahimi 		{
539*9a0e4156SSadaf Ebrahimi 			M680X_INS_SWI, mmrr, {
540*9a0e4156SSadaf Ebrahimi 				M680X_REG_S, M680X_REG_PC, M680X_REG_U,
541*9a0e4156SSadaf Ebrahimi 				M680X_REG_Y, M680X_REG_X, M680X_REG_DP,
542*9a0e4156SSadaf Ebrahimi 				M680X_REG_A, M680X_REG_B, M680X_REG_CC,
543*9a0e4156SSadaf Ebrahimi 				EOL
544*9a0e4156SSadaf Ebrahimi 			}
545*9a0e4156SSadaf Ebrahimi 		},
546*9a0e4156SSadaf Ebrahimi 		{
547*9a0e4156SSadaf Ebrahimi 			M680X_INS_SWI2, mmrr, {
548*9a0e4156SSadaf Ebrahimi 				M680X_REG_S, M680X_REG_PC, M680X_REG_U,
549*9a0e4156SSadaf Ebrahimi 				M680X_REG_Y, M680X_REG_X, M680X_REG_DP,
550*9a0e4156SSadaf Ebrahimi 				M680X_REG_A, M680X_REG_B, M680X_REG_CC,
551*9a0e4156SSadaf Ebrahimi 				EOL
552*9a0e4156SSadaf Ebrahimi 			},
553*9a0e4156SSadaf Ebrahimi 		},
554*9a0e4156SSadaf Ebrahimi 		{
555*9a0e4156SSadaf Ebrahimi 			M680X_INS_SWI3, mmrr, {
556*9a0e4156SSadaf Ebrahimi 				M680X_REG_S, M680X_REG_PC, M680X_REG_U,
557*9a0e4156SSadaf Ebrahimi 				M680X_REG_Y, M680X_REG_X, M680X_REG_DP,
558*9a0e4156SSadaf Ebrahimi 				M680X_REG_A, M680X_REG_B, M680X_REG_CC,
559*9a0e4156SSadaf Ebrahimi 				EOL
560*9a0e4156SSadaf Ebrahimi 			},
561*9a0e4156SSadaf Ebrahimi 		},
562*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_TBL, wrrr, { M680X_REG_A, M680X_REG_B, EOL } },
563*9a0e4156SSadaf Ebrahimi 		{
564*9a0e4156SSadaf Ebrahimi 			M680X_INS_WAI, mrrr, {
565*9a0e4156SSadaf Ebrahimi 				M680X_REG_S, M680X_REG_PC, M680X_REG_X,
566*9a0e4156SSadaf Ebrahimi 				M680X_REG_A, M680X_REG_B, M680X_REG_CC,
567*9a0e4156SSadaf Ebrahimi 				EOL
568*9a0e4156SSadaf Ebrahimi 			}
569*9a0e4156SSadaf Ebrahimi 		},
570*9a0e4156SSadaf Ebrahimi 		{
571*9a0e4156SSadaf Ebrahimi 			M680X_INS_WAV, rmmm, {
572*9a0e4156SSadaf Ebrahimi 				M680X_REG_A, M680X_REG_B, M680X_REG_X,
573*9a0e4156SSadaf Ebrahimi 				M680X_REG_Y, EOL
574*9a0e4156SSadaf Ebrahimi 			}
575*9a0e4156SSadaf Ebrahimi 		},
576*9a0e4156SSadaf Ebrahimi 		{
577*9a0e4156SSadaf Ebrahimi 			M680X_INS_WAVR, rmmm, {
578*9a0e4156SSadaf Ebrahimi 				M680X_REG_A, M680X_REG_B, M680X_REG_X,
579*9a0e4156SSadaf Ebrahimi 				M680X_REG_Y, EOL
580*9a0e4156SSadaf Ebrahimi 			}
581*9a0e4156SSadaf Ebrahimi 		},
582*9a0e4156SSadaf Ebrahimi 	};
583*9a0e4156SSadaf Ebrahimi 
584*9a0e4156SSadaf Ebrahimi 	int i, j;
585*9a0e4156SSadaf Ebrahimi 
586*9a0e4156SSadaf Ebrahimi 	if (MI->flat_insn->detail == NULL)
587*9a0e4156SSadaf Ebrahimi 		return;
588*9a0e4156SSadaf Ebrahimi 
589*9a0e4156SSadaf Ebrahimi 	for (i = 0; i < ARR_SIZE(changed_regs); ++i) {
590*9a0e4156SSadaf Ebrahimi 		if (info->insn == changed_regs[i].insn) {
591*9a0e4156SSadaf Ebrahimi 			e_access_mode access_mode = changed_regs[i].access_mode;
592*9a0e4156SSadaf Ebrahimi 
593*9a0e4156SSadaf Ebrahimi 			for (j = 0; changed_regs[i].regs[j] != EOL; ++j) {
594*9a0e4156SSadaf Ebrahimi 				e_access access;
595*9a0e4156SSadaf Ebrahimi 
596*9a0e4156SSadaf Ebrahimi 				m680x_reg reg = changed_regs[i].regs[j];
597*9a0e4156SSadaf Ebrahimi 
598*9a0e4156SSadaf Ebrahimi 				if (!info->cpu->reg_byte_size[reg]) {
599*9a0e4156SSadaf Ebrahimi 					if (info->insn != M680X_INS_MUL)
600*9a0e4156SSadaf Ebrahimi 						continue;
601*9a0e4156SSadaf Ebrahimi 
602*9a0e4156SSadaf Ebrahimi 					// Hack for M68HC05: MUL uses reg. A,X
603*9a0e4156SSadaf Ebrahimi 					reg = M680X_REG_X;
604*9a0e4156SSadaf Ebrahimi 				}
605*9a0e4156SSadaf Ebrahimi 
606*9a0e4156SSadaf Ebrahimi 				access = get_access(j, access_mode);
607*9a0e4156SSadaf Ebrahimi 				add_reg_to_rw_list(MI, reg, access);
608*9a0e4156SSadaf Ebrahimi 			}
609*9a0e4156SSadaf Ebrahimi 		}
610*9a0e4156SSadaf Ebrahimi 	}
611*9a0e4156SSadaf Ebrahimi 
612*9a0e4156SSadaf Ebrahimi #undef EOL
613*9a0e4156SSadaf Ebrahimi }
614*9a0e4156SSadaf Ebrahimi 
615*9a0e4156SSadaf Ebrahimi typedef struct insn_desc {
616*9a0e4156SSadaf Ebrahimi 	uint32_t opcode;
617*9a0e4156SSadaf Ebrahimi 	m680x_insn insn;
618*9a0e4156SSadaf Ebrahimi 	insn_hdlr_id hid[2];
619*9a0e4156SSadaf Ebrahimi 	uint16_t insn_size;
620*9a0e4156SSadaf Ebrahimi } insn_desc;
621*9a0e4156SSadaf Ebrahimi 
is_indexed09_post_byte_valid(const m680x_info * info,uint16_t * address,uint8_t post_byte,insn_desc * insn_description)622*9a0e4156SSadaf Ebrahimi static bool is_indexed09_post_byte_valid(const m680x_info *info,
623*9a0e4156SSadaf Ebrahimi 	uint16_t *address, uint8_t post_byte, insn_desc *insn_description)
624*9a0e4156SSadaf Ebrahimi {
625*9a0e4156SSadaf Ebrahimi 	uint8_t ir = 0;
626*9a0e4156SSadaf Ebrahimi 	bool retval;
627*9a0e4156SSadaf Ebrahimi 
628*9a0e4156SSadaf Ebrahimi 	switch (post_byte & 0x9F) {
629*9a0e4156SSadaf Ebrahimi 	case 0x87:
630*9a0e4156SSadaf Ebrahimi 	case 0x8A:
631*9a0e4156SSadaf Ebrahimi 	case 0x8E:
632*9a0e4156SSadaf Ebrahimi 	case 0x8F:
633*9a0e4156SSadaf Ebrahimi 	case 0x90:
634*9a0e4156SSadaf Ebrahimi 	case 0x92:
635*9a0e4156SSadaf Ebrahimi 	case 0x97:
636*9a0e4156SSadaf Ebrahimi 	case 0x9A:
637*9a0e4156SSadaf Ebrahimi 	case 0x9E:
638*9a0e4156SSadaf Ebrahimi 		return false; // illegal indexed post bytes
639*9a0e4156SSadaf Ebrahimi 
640*9a0e4156SSadaf Ebrahimi 	case 0x88: // n8,R
641*9a0e4156SSadaf Ebrahimi 	case 0x8C: // n8,PCR
642*9a0e4156SSadaf Ebrahimi 	case 0x98: // [n8,R]
643*9a0e4156SSadaf Ebrahimi 	case 0x9C: // [n8,PCR]
644*9a0e4156SSadaf Ebrahimi 		insn_description->insn_size++;
645*9a0e4156SSadaf Ebrahimi 		return read_byte(info, &ir, (*address)++);
646*9a0e4156SSadaf Ebrahimi 
647*9a0e4156SSadaf Ebrahimi 	case 0x89: // n16,R
648*9a0e4156SSadaf Ebrahimi 	case 0x8D: // n16,PCR
649*9a0e4156SSadaf Ebrahimi 	case 0x99: // [n16,R]
650*9a0e4156SSadaf Ebrahimi 	case 0x9D: // [n16,PCR]
651*9a0e4156SSadaf Ebrahimi 		insn_description->insn_size += 2;
652*9a0e4156SSadaf Ebrahimi 		retval = read_byte(info, &ir, *address + 1);
653*9a0e4156SSadaf Ebrahimi 		*address += 2;
654*9a0e4156SSadaf Ebrahimi 		return retval;
655*9a0e4156SSadaf Ebrahimi 
656*9a0e4156SSadaf Ebrahimi 	case 0x9F: // [n]
657*9a0e4156SSadaf Ebrahimi 		insn_description->insn_size += 2;
658*9a0e4156SSadaf Ebrahimi 		retval = (post_byte & 0x60) == 0 &&
659*9a0e4156SSadaf Ebrahimi 			read_byte(info, &ir, *address + 1);
660*9a0e4156SSadaf Ebrahimi 		*address += 2;
661*9a0e4156SSadaf Ebrahimi 		return retval;
662*9a0e4156SSadaf Ebrahimi 	}
663*9a0e4156SSadaf Ebrahimi 
664*9a0e4156SSadaf Ebrahimi 	return true; // Any other indexed post byte is valid and
665*9a0e4156SSadaf Ebrahimi 	// no additional bytes have to be read.
666*9a0e4156SSadaf Ebrahimi }
667*9a0e4156SSadaf Ebrahimi 
is_indexed12_post_byte_valid(const m680x_info * info,uint16_t * address,uint8_t post_byte,insn_desc * insn_description,bool is_subset)668*9a0e4156SSadaf Ebrahimi static bool is_indexed12_post_byte_valid(const m680x_info *info,
669*9a0e4156SSadaf Ebrahimi 	uint16_t *address, uint8_t post_byte, insn_desc *insn_description,
670*9a0e4156SSadaf Ebrahimi 	bool is_subset)
671*9a0e4156SSadaf Ebrahimi {
672*9a0e4156SSadaf Ebrahimi 	uint8_t ir;
673*9a0e4156SSadaf Ebrahimi 	bool result;
674*9a0e4156SSadaf Ebrahimi 
675*9a0e4156SSadaf Ebrahimi 	if (!(post_byte & 0x20)) // n5,R
676*9a0e4156SSadaf Ebrahimi 		return true;
677*9a0e4156SSadaf Ebrahimi 
678*9a0e4156SSadaf Ebrahimi 	switch (post_byte & 0xe7) {
679*9a0e4156SSadaf Ebrahimi 	case 0xe0:
680*9a0e4156SSadaf Ebrahimi 	case 0xe1: // n9,R
681*9a0e4156SSadaf Ebrahimi 		if (is_subset)
682*9a0e4156SSadaf Ebrahimi 			return false;
683*9a0e4156SSadaf Ebrahimi 
684*9a0e4156SSadaf Ebrahimi 		insn_description->insn_size++;
685*9a0e4156SSadaf Ebrahimi 		return read_byte(info, &ir, (*address)++);
686*9a0e4156SSadaf Ebrahimi 
687*9a0e4156SSadaf Ebrahimi 	case 0xe2: // n16,R
688*9a0e4156SSadaf Ebrahimi 	case 0xe3: // [n16,R]
689*9a0e4156SSadaf Ebrahimi 		if (is_subset)
690*9a0e4156SSadaf Ebrahimi 			return false;
691*9a0e4156SSadaf Ebrahimi 
692*9a0e4156SSadaf Ebrahimi 		insn_description->insn_size += 2;
693*9a0e4156SSadaf Ebrahimi 		result = read_byte(info, &ir, *address + 1);
694*9a0e4156SSadaf Ebrahimi 		*address += 2;
695*9a0e4156SSadaf Ebrahimi 		return result;
696*9a0e4156SSadaf Ebrahimi 
697*9a0e4156SSadaf Ebrahimi 	case 0xe4: // A,R
698*9a0e4156SSadaf Ebrahimi 	case 0xe5: // B,R
699*9a0e4156SSadaf Ebrahimi 	case 0xe6: // D,R
700*9a0e4156SSadaf Ebrahimi 	case 0xe7: // [D,R]
701*9a0e4156SSadaf Ebrahimi 	default: // n,-r n,+r n,r- n,r+
702*9a0e4156SSadaf Ebrahimi 		break;
703*9a0e4156SSadaf Ebrahimi 	}
704*9a0e4156SSadaf Ebrahimi 
705*9a0e4156SSadaf Ebrahimi 	return true;
706*9a0e4156SSadaf Ebrahimi }
707*9a0e4156SSadaf Ebrahimi 
708*9a0e4156SSadaf Ebrahimi // Check for M6809/HD6309 TFR/EXG instruction for valid register
is_tfr09_reg_valid(const m680x_info * info,uint8_t reg_nibble)709*9a0e4156SSadaf Ebrahimi static bool is_tfr09_reg_valid(const m680x_info *info, uint8_t reg_nibble)
710*9a0e4156SSadaf Ebrahimi {
711*9a0e4156SSadaf Ebrahimi 	if (info->cpu->tfr_reg_valid != NULL)
712*9a0e4156SSadaf Ebrahimi 		return info->cpu->tfr_reg_valid[reg_nibble];
713*9a0e4156SSadaf Ebrahimi 
714*9a0e4156SSadaf Ebrahimi 	return true; // e.g. for the M6309 all registers are valid
715*9a0e4156SSadaf Ebrahimi }
716*9a0e4156SSadaf Ebrahimi 
717*9a0e4156SSadaf Ebrahimi // Check for CPU12 TFR/EXG instruction for valid register
is_exg_tfr12_post_byte_valid(const m680x_info * info,uint8_t post_byte)718*9a0e4156SSadaf Ebrahimi static bool is_exg_tfr12_post_byte_valid(const m680x_info *info,
719*9a0e4156SSadaf Ebrahimi 	uint8_t post_byte)
720*9a0e4156SSadaf Ebrahimi {
721*9a0e4156SSadaf Ebrahimi 	return !(post_byte & 0x08);
722*9a0e4156SSadaf Ebrahimi }
723*9a0e4156SSadaf Ebrahimi 
is_tfm_reg_valid(const m680x_info * info,uint8_t reg_nibble)724*9a0e4156SSadaf Ebrahimi static bool is_tfm_reg_valid(const m680x_info *info, uint8_t reg_nibble)
725*9a0e4156SSadaf Ebrahimi {
726*9a0e4156SSadaf Ebrahimi 	// HD6809 TFM instruction: Only register X,Y,U,S,D is allowed
727*9a0e4156SSadaf Ebrahimi 	return reg_nibble <= 4;
728*9a0e4156SSadaf Ebrahimi }
729*9a0e4156SSadaf Ebrahimi 
is_loop_post_byte_valid(const m680x_info * info,uint8_t post_byte)730*9a0e4156SSadaf Ebrahimi static bool is_loop_post_byte_valid(const m680x_info *info, uint8_t post_byte)
731*9a0e4156SSadaf Ebrahimi {
732*9a0e4156SSadaf Ebrahimi 	// According to documentation bit 3 is don't care and not checked here.
733*9a0e4156SSadaf Ebrahimi 	if (post_byte >= 0xc0)
734*9a0e4156SSadaf Ebrahimi 		return false;
735*9a0e4156SSadaf Ebrahimi 
736*9a0e4156SSadaf Ebrahimi 	return ((post_byte & 0x07) != 2 && ((post_byte & 0x07) != 3));
737*9a0e4156SSadaf Ebrahimi }
738*9a0e4156SSadaf Ebrahimi 
is_sufficient_code_size(const m680x_info * info,uint16_t address,insn_desc * insn_description)739*9a0e4156SSadaf Ebrahimi static bool is_sufficient_code_size(const m680x_info *info, uint16_t address,
740*9a0e4156SSadaf Ebrahimi 	insn_desc *insn_description)
741*9a0e4156SSadaf Ebrahimi {
742*9a0e4156SSadaf Ebrahimi 	int i;
743*9a0e4156SSadaf Ebrahimi 	bool retval;
744*9a0e4156SSadaf Ebrahimi 
745*9a0e4156SSadaf Ebrahimi 	for (i = 0; i < 2; i++) {
746*9a0e4156SSadaf Ebrahimi 		uint8_t ir = 0;
747*9a0e4156SSadaf Ebrahimi 		bool is_subset = false;
748*9a0e4156SSadaf Ebrahimi 
749*9a0e4156SSadaf Ebrahimi 		switch (insn_description->hid[i]) {
750*9a0e4156SSadaf Ebrahimi 
751*9a0e4156SSadaf Ebrahimi 		case imm32_hid:
752*9a0e4156SSadaf Ebrahimi 			insn_description->insn_size += 4;
753*9a0e4156SSadaf Ebrahimi 			retval = read_byte(info, &ir, address + 3);
754*9a0e4156SSadaf Ebrahimi 			address += 4;
755*9a0e4156SSadaf Ebrahimi 			break;
756*9a0e4156SSadaf Ebrahimi 
757*9a0e4156SSadaf Ebrahimi 		case ext_hid:
758*9a0e4156SSadaf Ebrahimi 		case imm16_hid:
759*9a0e4156SSadaf Ebrahimi 		case rel16_hid:
760*9a0e4156SSadaf Ebrahimi 		case imm8rel_hid:
761*9a0e4156SSadaf Ebrahimi 		case opidxdr_hid:
762*9a0e4156SSadaf Ebrahimi 		case idxX16_hid:
763*9a0e4156SSadaf Ebrahimi 		case idxS16_hid:
764*9a0e4156SSadaf Ebrahimi 			insn_description->insn_size += 2;
765*9a0e4156SSadaf Ebrahimi 			retval = read_byte(info, &ir, address + 1);
766*9a0e4156SSadaf Ebrahimi 			address += 2;
767*9a0e4156SSadaf Ebrahimi 			break;
768*9a0e4156SSadaf Ebrahimi 
769*9a0e4156SSadaf Ebrahimi 		case rel8_hid:
770*9a0e4156SSadaf Ebrahimi 		case dir_hid:
771*9a0e4156SSadaf Ebrahimi 		case rbits_hid:
772*9a0e4156SSadaf Ebrahimi 		case imm8_hid:
773*9a0e4156SSadaf Ebrahimi 		case idxX_hid:
774*9a0e4156SSadaf Ebrahimi 		case idxXp_hid:
775*9a0e4156SSadaf Ebrahimi 		case idxY_hid:
776*9a0e4156SSadaf Ebrahimi 		case idxS_hid:
777*9a0e4156SSadaf Ebrahimi 		case index_hid:
778*9a0e4156SSadaf Ebrahimi 			insn_description->insn_size += 1;
779*9a0e4156SSadaf Ebrahimi 			retval = read_byte(info, &ir, address++);
780*9a0e4156SSadaf Ebrahimi 			break;
781*9a0e4156SSadaf Ebrahimi 
782*9a0e4156SSadaf Ebrahimi 		case illgl_hid:
783*9a0e4156SSadaf Ebrahimi 		case inh_hid:
784*9a0e4156SSadaf Ebrahimi 		case idxX0_hid:
785*9a0e4156SSadaf Ebrahimi 		case idxX0p_hid:
786*9a0e4156SSadaf Ebrahimi 		case opidx_hid:
787*9a0e4156SSadaf Ebrahimi 			retval = true;
788*9a0e4156SSadaf Ebrahimi 			break;
789*9a0e4156SSadaf Ebrahimi 
790*9a0e4156SSadaf Ebrahimi 		case idx09_hid:
791*9a0e4156SSadaf Ebrahimi 			insn_description->insn_size += 1;
792*9a0e4156SSadaf Ebrahimi 
793*9a0e4156SSadaf Ebrahimi 			if (!read_byte(info, &ir, address++))
794*9a0e4156SSadaf Ebrahimi 				retval = false;
795*9a0e4156SSadaf Ebrahimi 			else
796*9a0e4156SSadaf Ebrahimi 				retval = is_indexed09_post_byte_valid(info,
797*9a0e4156SSadaf Ebrahimi 						&address, ir, insn_description);
798*9a0e4156SSadaf Ebrahimi 
799*9a0e4156SSadaf Ebrahimi 			break;
800*9a0e4156SSadaf Ebrahimi 
801*9a0e4156SSadaf Ebrahimi 		case idx12s_hid:
802*9a0e4156SSadaf Ebrahimi 			is_subset = true;
803*9a0e4156SSadaf Ebrahimi 
804*9a0e4156SSadaf Ebrahimi 		// intentionally fall through
805*9a0e4156SSadaf Ebrahimi 
806*9a0e4156SSadaf Ebrahimi 		case idx12_hid:
807*9a0e4156SSadaf Ebrahimi 			insn_description->insn_size += 1;
808*9a0e4156SSadaf Ebrahimi 
809*9a0e4156SSadaf Ebrahimi 			if (!read_byte(info, &ir, address++))
810*9a0e4156SSadaf Ebrahimi 				retval = false;
811*9a0e4156SSadaf Ebrahimi 			else
812*9a0e4156SSadaf Ebrahimi 				retval = is_indexed12_post_byte_valid(info,
813*9a0e4156SSadaf Ebrahimi 						&address, ir, insn_description,
814*9a0e4156SSadaf Ebrahimi 						is_subset);
815*9a0e4156SSadaf Ebrahimi 
816*9a0e4156SSadaf Ebrahimi 			break;
817*9a0e4156SSadaf Ebrahimi 
818*9a0e4156SSadaf Ebrahimi 		case exti12x_hid:
819*9a0e4156SSadaf Ebrahimi 		case imm16i12x_hid:
820*9a0e4156SSadaf Ebrahimi 			insn_description->insn_size += 1;
821*9a0e4156SSadaf Ebrahimi 
822*9a0e4156SSadaf Ebrahimi 			if (!read_byte(info, &ir, address++))
823*9a0e4156SSadaf Ebrahimi 				retval = false;
824*9a0e4156SSadaf Ebrahimi 			else if (!is_indexed12_post_byte_valid(info, &address,
825*9a0e4156SSadaf Ebrahimi 					ir, insn_description, false))
826*9a0e4156SSadaf Ebrahimi 				retval = false;
827*9a0e4156SSadaf Ebrahimi 			else {
828*9a0e4156SSadaf Ebrahimi 				insn_description->insn_size += 2;
829*9a0e4156SSadaf Ebrahimi 				retval = read_byte(info, &ir, address + 1);
830*9a0e4156SSadaf Ebrahimi 				address += 2;
831*9a0e4156SSadaf Ebrahimi 			}
832*9a0e4156SSadaf Ebrahimi 
833*9a0e4156SSadaf Ebrahimi 			break;
834*9a0e4156SSadaf Ebrahimi 
835*9a0e4156SSadaf Ebrahimi 		case imm8i12x_hid:
836*9a0e4156SSadaf Ebrahimi 			insn_description->insn_size += 1;
837*9a0e4156SSadaf Ebrahimi 
838*9a0e4156SSadaf Ebrahimi 			if (!read_byte(info, &ir, address++))
839*9a0e4156SSadaf Ebrahimi 				retval = false;
840*9a0e4156SSadaf Ebrahimi 			else if (!is_indexed12_post_byte_valid(info, &address,
841*9a0e4156SSadaf Ebrahimi 					ir, insn_description, false))
842*9a0e4156SSadaf Ebrahimi 				retval = false;
843*9a0e4156SSadaf Ebrahimi 			else {
844*9a0e4156SSadaf Ebrahimi 				insn_description->insn_size += 1;
845*9a0e4156SSadaf Ebrahimi 				retval = read_byte(info, &ir, address++);
846*9a0e4156SSadaf Ebrahimi 			}
847*9a0e4156SSadaf Ebrahimi 
848*9a0e4156SSadaf Ebrahimi 			break;
849*9a0e4156SSadaf Ebrahimi 
850*9a0e4156SSadaf Ebrahimi 		case tfm_hid:
851*9a0e4156SSadaf Ebrahimi 			insn_description->insn_size += 1;
852*9a0e4156SSadaf Ebrahimi 
853*9a0e4156SSadaf Ebrahimi 			if (!read_byte(info, &ir, address++))
854*9a0e4156SSadaf Ebrahimi 				retval = false;
855*9a0e4156SSadaf Ebrahimi 			else
856*9a0e4156SSadaf Ebrahimi 				retval = is_tfm_reg_valid(info, (ir >> 4) & 0x0F) &&
857*9a0e4156SSadaf Ebrahimi 					is_tfm_reg_valid(info, ir & 0x0F);
858*9a0e4156SSadaf Ebrahimi 
859*9a0e4156SSadaf Ebrahimi 			break;
860*9a0e4156SSadaf Ebrahimi 
861*9a0e4156SSadaf Ebrahimi 		case rr09_hid:
862*9a0e4156SSadaf Ebrahimi 			insn_description->insn_size += 1;
863*9a0e4156SSadaf Ebrahimi 
864*9a0e4156SSadaf Ebrahimi 			if (!read_byte(info, &ir, address++))
865*9a0e4156SSadaf Ebrahimi 				retval = false;
866*9a0e4156SSadaf Ebrahimi 			else
867*9a0e4156SSadaf Ebrahimi 				retval = is_tfr09_reg_valid(info, (ir >> 4) & 0x0F) &&
868*9a0e4156SSadaf Ebrahimi 					is_tfr09_reg_valid(info, ir & 0x0F);
869*9a0e4156SSadaf Ebrahimi 
870*9a0e4156SSadaf Ebrahimi 			break;
871*9a0e4156SSadaf Ebrahimi 
872*9a0e4156SSadaf Ebrahimi 		case rr12_hid:
873*9a0e4156SSadaf Ebrahimi 			insn_description->insn_size += 1;
874*9a0e4156SSadaf Ebrahimi 
875*9a0e4156SSadaf Ebrahimi 			if (!read_byte(info, &ir, address++))
876*9a0e4156SSadaf Ebrahimi 				retval = false;
877*9a0e4156SSadaf Ebrahimi 			else
878*9a0e4156SSadaf Ebrahimi 				retval = is_exg_tfr12_post_byte_valid(info, ir);
879*9a0e4156SSadaf Ebrahimi 
880*9a0e4156SSadaf Ebrahimi 			break;
881*9a0e4156SSadaf Ebrahimi 
882*9a0e4156SSadaf Ebrahimi 		case bitmv_hid:
883*9a0e4156SSadaf Ebrahimi 			insn_description->insn_size += 2;
884*9a0e4156SSadaf Ebrahimi 
885*9a0e4156SSadaf Ebrahimi 			if (!read_byte(info, &ir, address++))
886*9a0e4156SSadaf Ebrahimi 				retval = false;
887*9a0e4156SSadaf Ebrahimi 			else if ((ir & 0xc0) == 0xc0)
888*9a0e4156SSadaf Ebrahimi 				retval = false; // Invalid register specified
889*9a0e4156SSadaf Ebrahimi 			else
890*9a0e4156SSadaf Ebrahimi 				retval = read_byte(info, &ir, address++);
891*9a0e4156SSadaf Ebrahimi 
892*9a0e4156SSadaf Ebrahimi 			break;
893*9a0e4156SSadaf Ebrahimi 
894*9a0e4156SSadaf Ebrahimi 		case loop_hid:
895*9a0e4156SSadaf Ebrahimi 			insn_description->insn_size += 2;
896*9a0e4156SSadaf Ebrahimi 
897*9a0e4156SSadaf Ebrahimi 			if (!read_byte(info, &ir, address++))
898*9a0e4156SSadaf Ebrahimi 				retval = false;
899*9a0e4156SSadaf Ebrahimi 			else if (!is_loop_post_byte_valid(info, ir))
900*9a0e4156SSadaf Ebrahimi 				retval = false;
901*9a0e4156SSadaf Ebrahimi 			else
902*9a0e4156SSadaf Ebrahimi 				retval = read_byte(info, &ir, address++);
903*9a0e4156SSadaf Ebrahimi 
904*9a0e4156SSadaf Ebrahimi 			break;
905*9a0e4156SSadaf Ebrahimi 
906*9a0e4156SSadaf Ebrahimi 		default:
907*9a0e4156SSadaf Ebrahimi 			fprintf(stderr, "Internal error: Unexpected instruction "
908*9a0e4156SSadaf Ebrahimi 				"handler id %d\n", insn_description->hid[i]);
909*9a0e4156SSadaf Ebrahimi 			retval = false;
910*9a0e4156SSadaf Ebrahimi 			break;
911*9a0e4156SSadaf Ebrahimi 		}
912*9a0e4156SSadaf Ebrahimi 
913*9a0e4156SSadaf Ebrahimi 		if (!retval)
914*9a0e4156SSadaf Ebrahimi 			return false;
915*9a0e4156SSadaf Ebrahimi 	}
916*9a0e4156SSadaf Ebrahimi 
917*9a0e4156SSadaf Ebrahimi 	return retval;
918*9a0e4156SSadaf Ebrahimi }
919*9a0e4156SSadaf Ebrahimi 
920*9a0e4156SSadaf Ebrahimi // Check for a valid M680X instruction AND for enough bytes in the code buffer
921*9a0e4156SSadaf Ebrahimi // Return an instruction description in insn_desc.
decode_insn(const m680x_info * info,uint16_t address,insn_desc * insn_description)922*9a0e4156SSadaf Ebrahimi static bool decode_insn(const m680x_info *info, uint16_t address,
923*9a0e4156SSadaf Ebrahimi 	insn_desc *insn_description)
924*9a0e4156SSadaf Ebrahimi {
925*9a0e4156SSadaf Ebrahimi 	const inst_pageX *inst_table = NULL;
926*9a0e4156SSadaf Ebrahimi 	const cpu_tables *cpu = info->cpu;
927*9a0e4156SSadaf Ebrahimi 	int table_size = 0;
928*9a0e4156SSadaf Ebrahimi 	uint16_t base_address = address;
929*9a0e4156SSadaf Ebrahimi 	uint8_t ir; // instruction register
930*9a0e4156SSadaf Ebrahimi 	int i;
931*9a0e4156SSadaf Ebrahimi 	int index;
932*9a0e4156SSadaf Ebrahimi 
933*9a0e4156SSadaf Ebrahimi 	if (!read_byte(info, &ir, address++))
934*9a0e4156SSadaf Ebrahimi 		return false;
935*9a0e4156SSadaf Ebrahimi 
936*9a0e4156SSadaf Ebrahimi 	insn_description->insn = M680X_INS_ILLGL;
937*9a0e4156SSadaf Ebrahimi 	insn_description->opcode = ir;
938*9a0e4156SSadaf Ebrahimi 
939*9a0e4156SSadaf Ebrahimi 	// Check if a page prefix byte is present
940*9a0e4156SSadaf Ebrahimi 	for (i = 0; i < ARR_SIZE(cpu->pageX_table_size); ++i) {
941*9a0e4156SSadaf Ebrahimi 		if (cpu->pageX_table_size[i] == 0 ||
942*9a0e4156SSadaf Ebrahimi 			(cpu->inst_pageX_table[i] == NULL))
943*9a0e4156SSadaf Ebrahimi 			break;
944*9a0e4156SSadaf Ebrahimi 
945*9a0e4156SSadaf Ebrahimi 		if ((cpu->pageX_prefix[i] == ir)) {
946*9a0e4156SSadaf Ebrahimi 			// Get pageX instruction and handler id.
947*9a0e4156SSadaf Ebrahimi 			// Abort for illegal instr.
948*9a0e4156SSadaf Ebrahimi 			inst_table = cpu->inst_pageX_table[i];
949*9a0e4156SSadaf Ebrahimi 			table_size = cpu->pageX_table_size[i];
950*9a0e4156SSadaf Ebrahimi 
951*9a0e4156SSadaf Ebrahimi 			if (!read_byte(info, &ir, address++))
952*9a0e4156SSadaf Ebrahimi 				return false;
953*9a0e4156SSadaf Ebrahimi 
954*9a0e4156SSadaf Ebrahimi 			insn_description->opcode =
955*9a0e4156SSadaf Ebrahimi 				(insn_description->opcode << 8) | ir;
956*9a0e4156SSadaf Ebrahimi 
957*9a0e4156SSadaf Ebrahimi 			if ((index = binary_search(inst_table, table_size,					ir)) < 0)
958*9a0e4156SSadaf Ebrahimi 				return false;
959*9a0e4156SSadaf Ebrahimi 
960*9a0e4156SSadaf Ebrahimi 			insn_description->hid[0] =
961*9a0e4156SSadaf Ebrahimi 				inst_table[index].handler_id1;
962*9a0e4156SSadaf Ebrahimi 			insn_description->hid[1] =
963*9a0e4156SSadaf Ebrahimi 				inst_table[index].handler_id2;
964*9a0e4156SSadaf Ebrahimi 			insn_description->insn = inst_table[index].insn;
965*9a0e4156SSadaf Ebrahimi 			break;
966*9a0e4156SSadaf Ebrahimi 		}
967*9a0e4156SSadaf Ebrahimi 	}
968*9a0e4156SSadaf Ebrahimi 
969*9a0e4156SSadaf Ebrahimi 	if (insn_description->insn == M680X_INS_ILLGL) {
970*9a0e4156SSadaf Ebrahimi 		// Get page1 insn description
971*9a0e4156SSadaf Ebrahimi 		insn_description->insn = cpu->inst_page1_table[ir].insn;
972*9a0e4156SSadaf Ebrahimi 		insn_description->hid[0] =
973*9a0e4156SSadaf Ebrahimi 			cpu->inst_page1_table[ir].handler_id1;
974*9a0e4156SSadaf Ebrahimi 		insn_description->hid[1] =
975*9a0e4156SSadaf Ebrahimi 			cpu->inst_page1_table[ir].handler_id2;
976*9a0e4156SSadaf Ebrahimi 	}
977*9a0e4156SSadaf Ebrahimi 
978*9a0e4156SSadaf Ebrahimi 	if (insn_description->insn == M680X_INS_ILLGL) {
979*9a0e4156SSadaf Ebrahimi 		// Check if opcode byte is present in an overlay table
980*9a0e4156SSadaf Ebrahimi 		for (i = 0; i < ARR_SIZE(cpu->overlay_table_size); ++i) {
981*9a0e4156SSadaf Ebrahimi 			if (cpu->overlay_table_size[i] == 0 ||
982*9a0e4156SSadaf Ebrahimi 				(cpu->inst_overlay_table[i] == NULL))
983*9a0e4156SSadaf Ebrahimi 				break;
984*9a0e4156SSadaf Ebrahimi 
985*9a0e4156SSadaf Ebrahimi 			inst_table = cpu->inst_overlay_table[i];
986*9a0e4156SSadaf Ebrahimi 			table_size = cpu->overlay_table_size[i];
987*9a0e4156SSadaf Ebrahimi 
988*9a0e4156SSadaf Ebrahimi 			if ((index = binary_search(inst_table, table_size,
989*9a0e4156SSadaf Ebrahimi 							ir)) >= 0) {
990*9a0e4156SSadaf Ebrahimi 				insn_description->hid[0] =
991*9a0e4156SSadaf Ebrahimi 					inst_table[index].handler_id1;
992*9a0e4156SSadaf Ebrahimi 				insn_description->hid[1] =
993*9a0e4156SSadaf Ebrahimi 					inst_table[index].handler_id2;
994*9a0e4156SSadaf Ebrahimi 				insn_description->insn = inst_table[index].insn;
995*9a0e4156SSadaf Ebrahimi 				break;
996*9a0e4156SSadaf Ebrahimi 			}
997*9a0e4156SSadaf Ebrahimi 		}
998*9a0e4156SSadaf Ebrahimi 	}
999*9a0e4156SSadaf Ebrahimi 
1000*9a0e4156SSadaf Ebrahimi 	insn_description->insn_size = address - base_address;
1001*9a0e4156SSadaf Ebrahimi 
1002*9a0e4156SSadaf Ebrahimi 	return (insn_description->insn != M680X_INS_ILLGL) &&
1003*9a0e4156SSadaf Ebrahimi 		(insn_description->insn != M680X_INS_INVLD) &&
1004*9a0e4156SSadaf Ebrahimi 		is_sufficient_code_size(info, address, insn_description);
1005*9a0e4156SSadaf Ebrahimi }
1006*9a0e4156SSadaf Ebrahimi 
illegal_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1007*9a0e4156SSadaf Ebrahimi static void illegal_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1008*9a0e4156SSadaf Ebrahimi {
1009*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op0 = &info->m680x.operands[info->m680x.op_count++];
1010*9a0e4156SSadaf Ebrahimi 	uint8_t temp8 = 0;
1011*9a0e4156SSadaf Ebrahimi 
1012*9a0e4156SSadaf Ebrahimi 	info->insn = M680X_INS_ILLGL;
1013*9a0e4156SSadaf Ebrahimi 	read_byte(info, &temp8, (*address)++);
1014*9a0e4156SSadaf Ebrahimi 	op0->imm = (int32_t)temp8 & 0xff;
1015*9a0e4156SSadaf Ebrahimi 	op0->type = M680X_OP_IMMEDIATE;
1016*9a0e4156SSadaf Ebrahimi 	op0->size = 1;
1017*9a0e4156SSadaf Ebrahimi }
1018*9a0e4156SSadaf Ebrahimi 
inherent_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1019*9a0e4156SSadaf Ebrahimi static void inherent_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1020*9a0e4156SSadaf Ebrahimi {
1021*9a0e4156SSadaf Ebrahimi 	// There is nothing to do here :-)
1022*9a0e4156SSadaf Ebrahimi }
1023*9a0e4156SSadaf Ebrahimi 
add_reg_operand(m680x_info * info,m680x_reg reg)1024*9a0e4156SSadaf Ebrahimi static void add_reg_operand(m680x_info *info, m680x_reg reg)
1025*9a0e4156SSadaf Ebrahimi {
1026*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1027*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1028*9a0e4156SSadaf Ebrahimi 
1029*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_REGISTER;
1030*9a0e4156SSadaf Ebrahimi 	op->reg = reg;
1031*9a0e4156SSadaf Ebrahimi 	op->size = info->cpu->reg_byte_size[reg];
1032*9a0e4156SSadaf Ebrahimi }
1033*9a0e4156SSadaf Ebrahimi 
set_operand_size(m680x_info * info,cs_m680x_op * op,uint8_t default_size)1034*9a0e4156SSadaf Ebrahimi static void set_operand_size(m680x_info *info, cs_m680x_op *op,
1035*9a0e4156SSadaf Ebrahimi 	uint8_t default_size)
1036*9a0e4156SSadaf Ebrahimi {
1037*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1038*9a0e4156SSadaf Ebrahimi 
1039*9a0e4156SSadaf Ebrahimi 	if (info->insn == M680X_INS_JMP || info->insn == M680X_INS_JSR)
1040*9a0e4156SSadaf Ebrahimi 		op->size = 0;
1041*9a0e4156SSadaf Ebrahimi 	else if (info->insn == M680X_INS_DIVD ||
1042*9a0e4156SSadaf Ebrahimi 		((info->insn == M680X_INS_AIS || info->insn == M680X_INS_AIX) &&
1043*9a0e4156SSadaf Ebrahimi 			op->type != M680X_OP_REGISTER))
1044*9a0e4156SSadaf Ebrahimi 		op->size = 1;
1045*9a0e4156SSadaf Ebrahimi 	else if (info->insn == M680X_INS_DIVQ ||
1046*9a0e4156SSadaf Ebrahimi 		info->insn == M680X_INS_MOVW)
1047*9a0e4156SSadaf Ebrahimi 		op->size = 2;
1048*9a0e4156SSadaf Ebrahimi 	else if (info->insn == M680X_INS_EMACS)
1049*9a0e4156SSadaf Ebrahimi 		op->size = 4;
1050*9a0e4156SSadaf Ebrahimi 	else if ((m680x->op_count > 0) &&
1051*9a0e4156SSadaf Ebrahimi 		(m680x->operands[0].type == M680X_OP_REGISTER))
1052*9a0e4156SSadaf Ebrahimi 		op->size = m680x->operands[0].size;
1053*9a0e4156SSadaf Ebrahimi 	else
1054*9a0e4156SSadaf Ebrahimi 		op->size = default_size;
1055*9a0e4156SSadaf Ebrahimi }
1056*9a0e4156SSadaf Ebrahimi 
1057*9a0e4156SSadaf Ebrahimi static const m680x_reg reg_s_reg_ids[] = {
1058*9a0e4156SSadaf Ebrahimi 	M680X_REG_CC, M680X_REG_A, M680X_REG_B, M680X_REG_DP,
1059*9a0e4156SSadaf Ebrahimi 	M680X_REG_X,  M680X_REG_Y, M680X_REG_U, M680X_REG_PC,
1060*9a0e4156SSadaf Ebrahimi };
1061*9a0e4156SSadaf Ebrahimi 
1062*9a0e4156SSadaf Ebrahimi static const m680x_reg reg_u_reg_ids[] = {
1063*9a0e4156SSadaf Ebrahimi 	M680X_REG_CC, M680X_REG_A, M680X_REG_B, M680X_REG_DP,
1064*9a0e4156SSadaf Ebrahimi 	M680X_REG_X,  M680X_REG_Y, M680X_REG_S, M680X_REG_PC,
1065*9a0e4156SSadaf Ebrahimi };
1066*9a0e4156SSadaf Ebrahimi 
reg_bits_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1067*9a0e4156SSadaf Ebrahimi static void reg_bits_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1068*9a0e4156SSadaf Ebrahimi {
1069*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op0 = &info->m680x.operands[0];
1070*9a0e4156SSadaf Ebrahimi 	uint8_t reg_bits = 0;
1071*9a0e4156SSadaf Ebrahimi 	uint16_t bit_index;
1072*9a0e4156SSadaf Ebrahimi 	const m680x_reg *reg_to_reg_ids;
1073*9a0e4156SSadaf Ebrahimi 
1074*9a0e4156SSadaf Ebrahimi 	read_byte(info, &reg_bits, (*address)++);
1075*9a0e4156SSadaf Ebrahimi 
1076*9a0e4156SSadaf Ebrahimi 	switch (op0->reg) {
1077*9a0e4156SSadaf Ebrahimi 	case M680X_REG_U:
1078*9a0e4156SSadaf Ebrahimi 		reg_to_reg_ids = &reg_u_reg_ids[0];
1079*9a0e4156SSadaf Ebrahimi 		break;
1080*9a0e4156SSadaf Ebrahimi 
1081*9a0e4156SSadaf Ebrahimi 	case M680X_REG_S:
1082*9a0e4156SSadaf Ebrahimi 		reg_to_reg_ids = &reg_s_reg_ids[0];
1083*9a0e4156SSadaf Ebrahimi 		break;
1084*9a0e4156SSadaf Ebrahimi 
1085*9a0e4156SSadaf Ebrahimi 	default:
1086*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Unexpected operand0 register "
1087*9a0e4156SSadaf Ebrahimi 			"%d\n", op0->reg);
1088*9a0e4156SSadaf Ebrahimi 		abort();
1089*9a0e4156SSadaf Ebrahimi 	}
1090*9a0e4156SSadaf Ebrahimi 
1091*9a0e4156SSadaf Ebrahimi 	if ((info->insn == M680X_INS_PULU ||
1092*9a0e4156SSadaf Ebrahimi 			(info->insn == M680X_INS_PULS)) &&
1093*9a0e4156SSadaf Ebrahimi 		((reg_bits & 0x80) != 0))
1094*9a0e4156SSadaf Ebrahimi 		// PULS xxx,PC or PULU xxx,PC which is like return from
1095*9a0e4156SSadaf Ebrahimi 		// subroutine (RTS)
1096*9a0e4156SSadaf Ebrahimi 		add_insn_group(MI->flat_insn->detail, M680X_GRP_RET);
1097*9a0e4156SSadaf Ebrahimi 
1098*9a0e4156SSadaf Ebrahimi 	for (bit_index = 0; bit_index < 8; ++bit_index) {
1099*9a0e4156SSadaf Ebrahimi 		if (reg_bits & (1 << bit_index))
1100*9a0e4156SSadaf Ebrahimi 			add_reg_operand(info, reg_to_reg_ids[bit_index]);
1101*9a0e4156SSadaf Ebrahimi 	}
1102*9a0e4156SSadaf Ebrahimi }
1103*9a0e4156SSadaf Ebrahimi 
1104*9a0e4156SSadaf Ebrahimi static const m680x_reg g_tfr_exg_reg_ids[] = {
1105*9a0e4156SSadaf Ebrahimi 	/* 16-bit registers */
1106*9a0e4156SSadaf Ebrahimi 	M680X_REG_D, M680X_REG_X,  M680X_REG_Y,  M680X_REG_U,
1107*9a0e4156SSadaf Ebrahimi 	M680X_REG_S, M680X_REG_PC, M680X_REG_W,  M680X_REG_V,
1108*9a0e4156SSadaf Ebrahimi 	/* 8-bit registers */
1109*9a0e4156SSadaf Ebrahimi 	M680X_REG_A, M680X_REG_B,  M680X_REG_CC, M680X_REG_DP,
1110*9a0e4156SSadaf Ebrahimi 	M680X_REG_0, M680X_REG_0,  M680X_REG_E,  M680X_REG_F,
1111*9a0e4156SSadaf Ebrahimi };
1112*9a0e4156SSadaf Ebrahimi 
reg_reg09_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1113*9a0e4156SSadaf Ebrahimi static void reg_reg09_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1114*9a0e4156SSadaf Ebrahimi {
1115*9a0e4156SSadaf Ebrahimi 	uint8_t regs = 0;
1116*9a0e4156SSadaf Ebrahimi 
1117*9a0e4156SSadaf Ebrahimi 	read_byte(info, &regs, (*address)++);
1118*9a0e4156SSadaf Ebrahimi 
1119*9a0e4156SSadaf Ebrahimi 	add_reg_operand(info, g_tfr_exg_reg_ids[regs >> 4]);
1120*9a0e4156SSadaf Ebrahimi 	add_reg_operand(info, g_tfr_exg_reg_ids[regs & 0x0f]);
1121*9a0e4156SSadaf Ebrahimi 
1122*9a0e4156SSadaf Ebrahimi 	if ((regs & 0x0f) == 0x05) {
1123*9a0e4156SSadaf Ebrahimi 		// EXG xxx,PC or TFR xxx,PC which is like a JMP
1124*9a0e4156SSadaf Ebrahimi 		add_insn_group(MI->flat_insn->detail, M680X_GRP_JUMP);
1125*9a0e4156SSadaf Ebrahimi 	}
1126*9a0e4156SSadaf Ebrahimi }
1127*9a0e4156SSadaf Ebrahimi 
1128*9a0e4156SSadaf Ebrahimi 
reg_reg12_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1129*9a0e4156SSadaf Ebrahimi static void reg_reg12_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1130*9a0e4156SSadaf Ebrahimi {
1131*9a0e4156SSadaf Ebrahimi 	static const m680x_reg g_tfr_exg12_reg0_ids[] = {
1132*9a0e4156SSadaf Ebrahimi 		M680X_REG_A, M680X_REG_B,  M680X_REG_CC,  M680X_REG_TMP3,
1133*9a0e4156SSadaf Ebrahimi 		M680X_REG_D, M680X_REG_X, M680X_REG_Y,  M680X_REG_S,
1134*9a0e4156SSadaf Ebrahimi 	};
1135*9a0e4156SSadaf Ebrahimi 	static const m680x_reg g_tfr_exg12_reg1_ids[] = {
1136*9a0e4156SSadaf Ebrahimi 		M680X_REG_A, M680X_REG_B,  M680X_REG_CC,  M680X_REG_TMP2,
1137*9a0e4156SSadaf Ebrahimi 		M680X_REG_D, M680X_REG_X, M680X_REG_Y,  M680X_REG_S,
1138*9a0e4156SSadaf Ebrahimi 	};
1139*9a0e4156SSadaf Ebrahimi 	uint8_t regs = 0;
1140*9a0e4156SSadaf Ebrahimi 
1141*9a0e4156SSadaf Ebrahimi 	read_byte(info, &regs, (*address)++);
1142*9a0e4156SSadaf Ebrahimi 
1143*9a0e4156SSadaf Ebrahimi 	// The opcode of this instruction depends on
1144*9a0e4156SSadaf Ebrahimi 	// the msb of its post byte.
1145*9a0e4156SSadaf Ebrahimi 	if (regs & 0x80)
1146*9a0e4156SSadaf Ebrahimi 		info->insn = M680X_INS_EXG;
1147*9a0e4156SSadaf Ebrahimi 	else
1148*9a0e4156SSadaf Ebrahimi 		info->insn = M680X_INS_TFR;
1149*9a0e4156SSadaf Ebrahimi 
1150*9a0e4156SSadaf Ebrahimi 	add_reg_operand(info, g_tfr_exg12_reg0_ids[(regs >> 4) & 0x07]);
1151*9a0e4156SSadaf Ebrahimi 	add_reg_operand(info, g_tfr_exg12_reg1_ids[regs & 0x07]);
1152*9a0e4156SSadaf Ebrahimi }
1153*9a0e4156SSadaf Ebrahimi 
add_rel_operand(m680x_info * info,int16_t offset,uint16_t address)1154*9a0e4156SSadaf Ebrahimi static void add_rel_operand(m680x_info *info, int16_t offset, uint16_t address)
1155*9a0e4156SSadaf Ebrahimi {
1156*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1157*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1158*9a0e4156SSadaf Ebrahimi 
1159*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_RELATIVE;
1160*9a0e4156SSadaf Ebrahimi 	op->size = 0;
1161*9a0e4156SSadaf Ebrahimi 	op->rel.offset = offset;
1162*9a0e4156SSadaf Ebrahimi 	op->rel.address = address;
1163*9a0e4156SSadaf Ebrahimi }
1164*9a0e4156SSadaf Ebrahimi 
relative8_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1165*9a0e4156SSadaf Ebrahimi static void relative8_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1166*9a0e4156SSadaf Ebrahimi {
1167*9a0e4156SSadaf Ebrahimi 	int16_t offset = 0;
1168*9a0e4156SSadaf Ebrahimi 
1169*9a0e4156SSadaf Ebrahimi 	read_byte_sign_extended(info, &offset, (*address)++);
1170*9a0e4156SSadaf Ebrahimi 	add_rel_operand(info, offset, *address + offset);
1171*9a0e4156SSadaf Ebrahimi 	add_insn_group(MI->flat_insn->detail, M680X_GRP_BRAREL);
1172*9a0e4156SSadaf Ebrahimi 
1173*9a0e4156SSadaf Ebrahimi 	if ((info->insn != M680X_INS_BRA) &&
1174*9a0e4156SSadaf Ebrahimi 		(info->insn != M680X_INS_BSR) &&
1175*9a0e4156SSadaf Ebrahimi 		(info->insn != M680X_INS_BRN))
1176*9a0e4156SSadaf Ebrahimi 		add_reg_to_rw_list(MI, M680X_REG_CC, READ);
1177*9a0e4156SSadaf Ebrahimi }
1178*9a0e4156SSadaf Ebrahimi 
relative16_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1179*9a0e4156SSadaf Ebrahimi static void relative16_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1180*9a0e4156SSadaf Ebrahimi {
1181*9a0e4156SSadaf Ebrahimi 	uint16_t offset = 0;
1182*9a0e4156SSadaf Ebrahimi 
1183*9a0e4156SSadaf Ebrahimi 	read_word(info, &offset, *address);
1184*9a0e4156SSadaf Ebrahimi 	*address += 2;
1185*9a0e4156SSadaf Ebrahimi 	add_rel_operand(info, (int16_t)offset, *address + offset);
1186*9a0e4156SSadaf Ebrahimi 	add_insn_group(MI->flat_insn->detail, M680X_GRP_BRAREL);
1187*9a0e4156SSadaf Ebrahimi 
1188*9a0e4156SSadaf Ebrahimi 	if ((info->insn != M680X_INS_LBRA) &&
1189*9a0e4156SSadaf Ebrahimi 		(info->insn != M680X_INS_LBSR) &&
1190*9a0e4156SSadaf Ebrahimi 		(info->insn != M680X_INS_LBRN))
1191*9a0e4156SSadaf Ebrahimi 		add_reg_to_rw_list(MI, M680X_REG_CC, READ);
1192*9a0e4156SSadaf Ebrahimi }
1193*9a0e4156SSadaf Ebrahimi 
1194*9a0e4156SSadaf Ebrahimi static const m680x_reg g_rr5_to_reg_ids[] = {
1195*9a0e4156SSadaf Ebrahimi 	M680X_REG_X, M680X_REG_Y, M680X_REG_U, M680X_REG_S,
1196*9a0e4156SSadaf Ebrahimi };
1197*9a0e4156SSadaf Ebrahimi 
add_indexed_operand(m680x_info * info,m680x_reg base_reg,bool post_inc_dec,uint8_t inc_dec,uint8_t offset_bits,uint16_t offset,bool no_comma)1198*9a0e4156SSadaf Ebrahimi static void add_indexed_operand(m680x_info *info, m680x_reg base_reg,
1199*9a0e4156SSadaf Ebrahimi 	bool post_inc_dec, uint8_t inc_dec, uint8_t offset_bits,
1200*9a0e4156SSadaf Ebrahimi 	uint16_t offset, bool no_comma)
1201*9a0e4156SSadaf Ebrahimi {
1202*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1203*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1204*9a0e4156SSadaf Ebrahimi 
1205*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_INDEXED;
1206*9a0e4156SSadaf Ebrahimi 	set_operand_size(info, op, 1);
1207*9a0e4156SSadaf Ebrahimi 	op->idx.base_reg = base_reg;
1208*9a0e4156SSadaf Ebrahimi 	op->idx.offset_reg = M680X_REG_INVALID;
1209*9a0e4156SSadaf Ebrahimi 	op->idx.inc_dec = inc_dec;
1210*9a0e4156SSadaf Ebrahimi 
1211*9a0e4156SSadaf Ebrahimi 	if (inc_dec && post_inc_dec)
1212*9a0e4156SSadaf Ebrahimi 		op->idx.flags |= M680X_IDX_POST_INC_DEC;
1213*9a0e4156SSadaf Ebrahimi 
1214*9a0e4156SSadaf Ebrahimi 	if (offset_bits != M680X_OFFSET_NONE) {
1215*9a0e4156SSadaf Ebrahimi 		op->idx.offset = offset;
1216*9a0e4156SSadaf Ebrahimi 		op->idx.offset_addr = 0;
1217*9a0e4156SSadaf Ebrahimi 	}
1218*9a0e4156SSadaf Ebrahimi 
1219*9a0e4156SSadaf Ebrahimi 	op->idx.offset_bits = offset_bits;
1220*9a0e4156SSadaf Ebrahimi 	op->idx.flags |= (no_comma ? M680X_IDX_NO_COMMA : 0);
1221*9a0e4156SSadaf Ebrahimi }
1222*9a0e4156SSadaf Ebrahimi 
1223*9a0e4156SSadaf Ebrahimi // M6800/1/2/3 indexed mode handler
indexedX_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1224*9a0e4156SSadaf Ebrahimi static void indexedX_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1225*9a0e4156SSadaf Ebrahimi {
1226*9a0e4156SSadaf Ebrahimi 	uint8_t offset = 0;
1227*9a0e4156SSadaf Ebrahimi 
1228*9a0e4156SSadaf Ebrahimi 	read_byte(info, &offset, (*address)++);
1229*9a0e4156SSadaf Ebrahimi 
1230*9a0e4156SSadaf Ebrahimi 	add_indexed_operand(info, M680X_REG_X, false, 0, M680X_OFFSET_BITS_8,
1231*9a0e4156SSadaf Ebrahimi 		(uint16_t)offset, false);
1232*9a0e4156SSadaf Ebrahimi }
1233*9a0e4156SSadaf Ebrahimi 
indexedY_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1234*9a0e4156SSadaf Ebrahimi static void indexedY_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1235*9a0e4156SSadaf Ebrahimi {
1236*9a0e4156SSadaf Ebrahimi 	uint8_t offset = 0;
1237*9a0e4156SSadaf Ebrahimi 
1238*9a0e4156SSadaf Ebrahimi 	read_byte(info, &offset, (*address)++);
1239*9a0e4156SSadaf Ebrahimi 
1240*9a0e4156SSadaf Ebrahimi 	add_indexed_operand(info, M680X_REG_Y, false, 0, M680X_OFFSET_BITS_8,
1241*9a0e4156SSadaf Ebrahimi 		(uint16_t)offset, false);
1242*9a0e4156SSadaf Ebrahimi }
1243*9a0e4156SSadaf Ebrahimi 
1244*9a0e4156SSadaf Ebrahimi // M6809/M6309 indexed mode handler
indexed09_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1245*9a0e4156SSadaf Ebrahimi static void indexed09_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1246*9a0e4156SSadaf Ebrahimi {
1247*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1248*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1249*9a0e4156SSadaf Ebrahimi 	uint8_t post_byte = 0;
1250*9a0e4156SSadaf Ebrahimi 	uint16_t offset = 0;
1251*9a0e4156SSadaf Ebrahimi 	int16_t soffset = 0;
1252*9a0e4156SSadaf Ebrahimi 
1253*9a0e4156SSadaf Ebrahimi 	read_byte(info, &post_byte, (*address)++);
1254*9a0e4156SSadaf Ebrahimi 
1255*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_INDEXED;
1256*9a0e4156SSadaf Ebrahimi 	set_operand_size(info, op, 1);
1257*9a0e4156SSadaf Ebrahimi 	op->idx.base_reg = g_rr5_to_reg_ids[(post_byte >> 5) & 0x03];
1258*9a0e4156SSadaf Ebrahimi 	op->idx.offset_reg = M680X_REG_INVALID;
1259*9a0e4156SSadaf Ebrahimi 
1260*9a0e4156SSadaf Ebrahimi 	if (!(post_byte & 0x80)) {
1261*9a0e4156SSadaf Ebrahimi 		// n5,R
1262*9a0e4156SSadaf Ebrahimi 		if ((post_byte & 0x10) == 0x10)
1263*9a0e4156SSadaf Ebrahimi 			op->idx.offset = post_byte | 0xfff0;
1264*9a0e4156SSadaf Ebrahimi 		else
1265*9a0e4156SSadaf Ebrahimi 			op->idx.offset = post_byte & 0x0f;
1266*9a0e4156SSadaf Ebrahimi 
1267*9a0e4156SSadaf Ebrahimi 		op->idx.offset_addr = op->idx.offset + *address;
1268*9a0e4156SSadaf Ebrahimi 		op->idx.offset_bits = M680X_OFFSET_BITS_5;
1269*9a0e4156SSadaf Ebrahimi 	}
1270*9a0e4156SSadaf Ebrahimi 	else {
1271*9a0e4156SSadaf Ebrahimi 		if ((post_byte & 0x10) == 0x10)
1272*9a0e4156SSadaf Ebrahimi 			op->idx.flags |= M680X_IDX_INDIRECT;
1273*9a0e4156SSadaf Ebrahimi 
1274*9a0e4156SSadaf Ebrahimi 		// indexed addressing
1275*9a0e4156SSadaf Ebrahimi 		switch (post_byte & 0x1f) {
1276*9a0e4156SSadaf Ebrahimi 		case 0x00: // ,R+
1277*9a0e4156SSadaf Ebrahimi 			op->idx.inc_dec = 1;
1278*9a0e4156SSadaf Ebrahimi 			op->idx.flags |= M680X_IDX_POST_INC_DEC;
1279*9a0e4156SSadaf Ebrahimi 			break;
1280*9a0e4156SSadaf Ebrahimi 
1281*9a0e4156SSadaf Ebrahimi 		case 0x11: // [,R++]
1282*9a0e4156SSadaf Ebrahimi 		case 0x01: // ,R++
1283*9a0e4156SSadaf Ebrahimi 			op->idx.inc_dec = 2;
1284*9a0e4156SSadaf Ebrahimi 			op->idx.flags |= M680X_IDX_POST_INC_DEC;
1285*9a0e4156SSadaf Ebrahimi 			break;
1286*9a0e4156SSadaf Ebrahimi 
1287*9a0e4156SSadaf Ebrahimi 		case 0x02: // ,-R
1288*9a0e4156SSadaf Ebrahimi 			op->idx.inc_dec = -1;
1289*9a0e4156SSadaf Ebrahimi 			break;
1290*9a0e4156SSadaf Ebrahimi 
1291*9a0e4156SSadaf Ebrahimi 		case 0x13: // [,--R]
1292*9a0e4156SSadaf Ebrahimi 		case 0x03: // ,--R
1293*9a0e4156SSadaf Ebrahimi 			op->idx.inc_dec = -2;
1294*9a0e4156SSadaf Ebrahimi 			break;
1295*9a0e4156SSadaf Ebrahimi 
1296*9a0e4156SSadaf Ebrahimi 		case 0x14: // [,R]
1297*9a0e4156SSadaf Ebrahimi 		case 0x04: // ,R
1298*9a0e4156SSadaf Ebrahimi 			break;
1299*9a0e4156SSadaf Ebrahimi 
1300*9a0e4156SSadaf Ebrahimi 		case 0x15: // [B,R]
1301*9a0e4156SSadaf Ebrahimi 		case 0x05: // B,R
1302*9a0e4156SSadaf Ebrahimi 			op->idx.offset_reg = M680X_REG_B;
1303*9a0e4156SSadaf Ebrahimi 			break;
1304*9a0e4156SSadaf Ebrahimi 
1305*9a0e4156SSadaf Ebrahimi 		case 0x16: // [A,R]
1306*9a0e4156SSadaf Ebrahimi 		case 0x06: // A,R
1307*9a0e4156SSadaf Ebrahimi 			op->idx.offset_reg = M680X_REG_A;
1308*9a0e4156SSadaf Ebrahimi 			break;
1309*9a0e4156SSadaf Ebrahimi 
1310*9a0e4156SSadaf Ebrahimi 		case 0x1c: // [n8,PCR]
1311*9a0e4156SSadaf Ebrahimi 		case 0x0c: // n8,PCR
1312*9a0e4156SSadaf Ebrahimi 			op->idx.base_reg = M680X_REG_PC;
1313*9a0e4156SSadaf Ebrahimi 			read_byte_sign_extended(info, &soffset, (*address)++);
1314*9a0e4156SSadaf Ebrahimi 			op->idx.offset_addr = offset + *address;
1315*9a0e4156SSadaf Ebrahimi 			op->idx.offset = soffset;
1316*9a0e4156SSadaf Ebrahimi 			op->idx.offset_bits = M680X_OFFSET_BITS_8;
1317*9a0e4156SSadaf Ebrahimi 			break;
1318*9a0e4156SSadaf Ebrahimi 
1319*9a0e4156SSadaf Ebrahimi 		case 0x18: // [n8,R]
1320*9a0e4156SSadaf Ebrahimi 		case 0x08: // n8,R
1321*9a0e4156SSadaf Ebrahimi 			read_byte_sign_extended(info, &soffset, (*address)++);
1322*9a0e4156SSadaf Ebrahimi 			op->idx.offset = soffset;
1323*9a0e4156SSadaf Ebrahimi 			op->idx.offset_bits = M680X_OFFSET_BITS_8;
1324*9a0e4156SSadaf Ebrahimi 			break;
1325*9a0e4156SSadaf Ebrahimi 
1326*9a0e4156SSadaf Ebrahimi 		case 0x1d: // [n16,PCR]
1327*9a0e4156SSadaf Ebrahimi 		case 0x0d: // n16,PCR
1328*9a0e4156SSadaf Ebrahimi 			op->idx.base_reg = M680X_REG_PC;
1329*9a0e4156SSadaf Ebrahimi 			read_word(info, &offset, *address);
1330*9a0e4156SSadaf Ebrahimi 			*address += 2;
1331*9a0e4156SSadaf Ebrahimi 			op->idx.offset_addr = offset + *address;
1332*9a0e4156SSadaf Ebrahimi 			op->idx.offset = (int16_t)offset;
1333*9a0e4156SSadaf Ebrahimi 			op->idx.offset_bits = M680X_OFFSET_BITS_16;
1334*9a0e4156SSadaf Ebrahimi 			break;
1335*9a0e4156SSadaf Ebrahimi 
1336*9a0e4156SSadaf Ebrahimi 		case 0x19: // [n16,R]
1337*9a0e4156SSadaf Ebrahimi 		case 0x09: // n16,R
1338*9a0e4156SSadaf Ebrahimi 			read_word(info, &offset, *address);
1339*9a0e4156SSadaf Ebrahimi 			*address += 2;
1340*9a0e4156SSadaf Ebrahimi 			op->idx.offset = (int16_t)offset;
1341*9a0e4156SSadaf Ebrahimi 			op->idx.offset_bits = M680X_OFFSET_BITS_16;
1342*9a0e4156SSadaf Ebrahimi 			break;
1343*9a0e4156SSadaf Ebrahimi 
1344*9a0e4156SSadaf Ebrahimi 		case 0x1b: // [D,R]
1345*9a0e4156SSadaf Ebrahimi 		case 0x0b: // D,R
1346*9a0e4156SSadaf Ebrahimi 			op->idx.offset_reg = M680X_REG_D;
1347*9a0e4156SSadaf Ebrahimi 			break;
1348*9a0e4156SSadaf Ebrahimi 
1349*9a0e4156SSadaf Ebrahimi 		case 0x1f: // [n16]
1350*9a0e4156SSadaf Ebrahimi 			op->type = M680X_OP_EXTENDED;
1351*9a0e4156SSadaf Ebrahimi 			op->ext.indirect = true;
1352*9a0e4156SSadaf Ebrahimi 			read_word(info, &op->ext.address, *address);
1353*9a0e4156SSadaf Ebrahimi 			*address += 2;
1354*9a0e4156SSadaf Ebrahimi 			break;
1355*9a0e4156SSadaf Ebrahimi 
1356*9a0e4156SSadaf Ebrahimi 		default:
1357*9a0e4156SSadaf Ebrahimi 			op->idx.base_reg = M680X_REG_INVALID;
1358*9a0e4156SSadaf Ebrahimi 			break;
1359*9a0e4156SSadaf Ebrahimi 		}
1360*9a0e4156SSadaf Ebrahimi 	}
1361*9a0e4156SSadaf Ebrahimi 
1362*9a0e4156SSadaf Ebrahimi 	if (((info->insn == M680X_INS_LEAU) ||
1363*9a0e4156SSadaf Ebrahimi 			(info->insn == M680X_INS_LEAS) ||
1364*9a0e4156SSadaf Ebrahimi 			(info->insn == M680X_INS_LEAX) ||
1365*9a0e4156SSadaf Ebrahimi 			(info->insn == M680X_INS_LEAY)) &&
1366*9a0e4156SSadaf Ebrahimi 		(m680x->operands[0].reg == M680X_REG_X ||
1367*9a0e4156SSadaf Ebrahimi 			(m680x->operands[0].reg == M680X_REG_Y)))
1368*9a0e4156SSadaf Ebrahimi 		// Only LEAX and LEAY modify CC register
1369*9a0e4156SSadaf Ebrahimi 		add_reg_to_rw_list(MI, M680X_REG_CC, MODIFY);
1370*9a0e4156SSadaf Ebrahimi }
1371*9a0e4156SSadaf Ebrahimi 
1372*9a0e4156SSadaf Ebrahimi 
1373*9a0e4156SSadaf Ebrahimi m680x_reg g_idx12_to_reg_ids[4] = {
1374*9a0e4156SSadaf Ebrahimi 	M680X_REG_X, M680X_REG_Y, M680X_REG_S, M680X_REG_PC,
1375*9a0e4156SSadaf Ebrahimi };
1376*9a0e4156SSadaf Ebrahimi 
1377*9a0e4156SSadaf Ebrahimi m680x_reg g_or12_to_reg_ids[3] = {
1378*9a0e4156SSadaf Ebrahimi 	M680X_REG_A, M680X_REG_B, M680X_REG_D
1379*9a0e4156SSadaf Ebrahimi };
1380*9a0e4156SSadaf Ebrahimi 
1381*9a0e4156SSadaf Ebrahimi // CPU12 indexed mode handler
indexed12_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1382*9a0e4156SSadaf Ebrahimi static void indexed12_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1383*9a0e4156SSadaf Ebrahimi {
1384*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1385*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1386*9a0e4156SSadaf Ebrahimi 	uint8_t post_byte = 0;
1387*9a0e4156SSadaf Ebrahimi 	uint8_t offset8 = 0;
1388*9a0e4156SSadaf Ebrahimi 
1389*9a0e4156SSadaf Ebrahimi 	read_byte(info, &post_byte, (*address)++);
1390*9a0e4156SSadaf Ebrahimi 
1391*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_INDEXED;
1392*9a0e4156SSadaf Ebrahimi 	set_operand_size(info, op, 1);
1393*9a0e4156SSadaf Ebrahimi 	op->idx.offset_reg = M680X_REG_INVALID;
1394*9a0e4156SSadaf Ebrahimi 
1395*9a0e4156SSadaf Ebrahimi 	if (!(post_byte & 0x20)) {
1396*9a0e4156SSadaf Ebrahimi 		// n5,R      n5 is a 5-bit signed offset
1397*9a0e4156SSadaf Ebrahimi 		op->idx.base_reg = g_idx12_to_reg_ids[(post_byte >> 6) & 0x03];
1398*9a0e4156SSadaf Ebrahimi 
1399*9a0e4156SSadaf Ebrahimi 		if ((post_byte & 0x10) == 0x10)
1400*9a0e4156SSadaf Ebrahimi 			op->idx.offset = post_byte | 0xfff0;
1401*9a0e4156SSadaf Ebrahimi 		else
1402*9a0e4156SSadaf Ebrahimi 			op->idx.offset = post_byte & 0x0f;
1403*9a0e4156SSadaf Ebrahimi 
1404*9a0e4156SSadaf Ebrahimi 		op->idx.offset_addr = op->idx.offset + *address;
1405*9a0e4156SSadaf Ebrahimi 		op->idx.offset_bits = M680X_OFFSET_BITS_5;
1406*9a0e4156SSadaf Ebrahimi 	}
1407*9a0e4156SSadaf Ebrahimi 	else {
1408*9a0e4156SSadaf Ebrahimi 		if ((post_byte & 0xe0) == 0xe0)
1409*9a0e4156SSadaf Ebrahimi 			op->idx.base_reg =
1410*9a0e4156SSadaf Ebrahimi 				g_idx12_to_reg_ids[(post_byte >> 3) & 0x03];
1411*9a0e4156SSadaf Ebrahimi 
1412*9a0e4156SSadaf Ebrahimi 		switch (post_byte & 0xe7) {
1413*9a0e4156SSadaf Ebrahimi 		case 0xe0:
1414*9a0e4156SSadaf Ebrahimi 		case 0xe1: // n9,R
1415*9a0e4156SSadaf Ebrahimi 			read_byte(info, &offset8, (*address)++);
1416*9a0e4156SSadaf Ebrahimi 			op->idx.offset = offset8;
1417*9a0e4156SSadaf Ebrahimi 
1418*9a0e4156SSadaf Ebrahimi 			if (post_byte & 0x01) // sign extension
1419*9a0e4156SSadaf Ebrahimi 				op->idx.offset |= 0xff00;
1420*9a0e4156SSadaf Ebrahimi 
1421*9a0e4156SSadaf Ebrahimi 			op->idx.offset_bits = M680X_OFFSET_BITS_9;
1422*9a0e4156SSadaf Ebrahimi 
1423*9a0e4156SSadaf Ebrahimi 			if (op->idx.base_reg == M680X_REG_PC)
1424*9a0e4156SSadaf Ebrahimi 				op->idx.offset_addr = op->idx.offset + *address;
1425*9a0e4156SSadaf Ebrahimi 
1426*9a0e4156SSadaf Ebrahimi 			break;
1427*9a0e4156SSadaf Ebrahimi 
1428*9a0e4156SSadaf Ebrahimi 		case 0xe3: // [n16,R]
1429*9a0e4156SSadaf Ebrahimi 			op->idx.flags |= M680X_IDX_INDIRECT;
1430*9a0e4156SSadaf Ebrahimi 
1431*9a0e4156SSadaf Ebrahimi 		// intentionally fall through
1432*9a0e4156SSadaf Ebrahimi 		case 0xe2: // n16,R
1433*9a0e4156SSadaf Ebrahimi 			read_word(info, (uint16_t *)&op->idx.offset, *address);
1434*9a0e4156SSadaf Ebrahimi 			(*address) += 2;
1435*9a0e4156SSadaf Ebrahimi 			op->idx.offset_bits = M680X_OFFSET_BITS_16;
1436*9a0e4156SSadaf Ebrahimi 
1437*9a0e4156SSadaf Ebrahimi 			if (op->idx.base_reg == M680X_REG_PC)
1438*9a0e4156SSadaf Ebrahimi 				op->idx.offset_addr = op->idx.offset + *address;
1439*9a0e4156SSadaf Ebrahimi 
1440*9a0e4156SSadaf Ebrahimi 			break;
1441*9a0e4156SSadaf Ebrahimi 
1442*9a0e4156SSadaf Ebrahimi 		case 0xe4: // A,R
1443*9a0e4156SSadaf Ebrahimi 		case 0xe5: // B,R
1444*9a0e4156SSadaf Ebrahimi 		case 0xe6: // D,R
1445*9a0e4156SSadaf Ebrahimi 			op->idx.offset_reg =
1446*9a0e4156SSadaf Ebrahimi 				g_or12_to_reg_ids[post_byte & 0x03];
1447*9a0e4156SSadaf Ebrahimi 			break;
1448*9a0e4156SSadaf Ebrahimi 
1449*9a0e4156SSadaf Ebrahimi 		case 0xe7: // [D,R]
1450*9a0e4156SSadaf Ebrahimi 			op->idx.offset_reg = M680X_REG_D;
1451*9a0e4156SSadaf Ebrahimi 			op->idx.flags |= M680X_IDX_INDIRECT;
1452*9a0e4156SSadaf Ebrahimi 			break;
1453*9a0e4156SSadaf Ebrahimi 
1454*9a0e4156SSadaf Ebrahimi 		default: // n,-r n,+r n,r- n,r+
1455*9a0e4156SSadaf Ebrahimi 			// PC is not allowed in this mode
1456*9a0e4156SSadaf Ebrahimi 			op->idx.base_reg =
1457*9a0e4156SSadaf Ebrahimi 				g_idx12_to_reg_ids[(post_byte >> 6) & 0x03];
1458*9a0e4156SSadaf Ebrahimi 			op->idx.inc_dec = post_byte & 0x0f;
1459*9a0e4156SSadaf Ebrahimi 
1460*9a0e4156SSadaf Ebrahimi 			if (op->idx.inc_dec & 0x08) // evtl. sign extend value
1461*9a0e4156SSadaf Ebrahimi 				op->idx.inc_dec |= 0xf0;
1462*9a0e4156SSadaf Ebrahimi 
1463*9a0e4156SSadaf Ebrahimi 			if (op->idx.inc_dec >= 0)
1464*9a0e4156SSadaf Ebrahimi 				op->idx.inc_dec++;
1465*9a0e4156SSadaf Ebrahimi 
1466*9a0e4156SSadaf Ebrahimi 			if (post_byte & 0x10)
1467*9a0e4156SSadaf Ebrahimi 				op->idx.flags |= M680X_IDX_POST_INC_DEC;
1468*9a0e4156SSadaf Ebrahimi 
1469*9a0e4156SSadaf Ebrahimi 			break;
1470*9a0e4156SSadaf Ebrahimi 
1471*9a0e4156SSadaf Ebrahimi 		}
1472*9a0e4156SSadaf Ebrahimi 	}
1473*9a0e4156SSadaf Ebrahimi }
1474*9a0e4156SSadaf Ebrahimi 
index_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1475*9a0e4156SSadaf Ebrahimi static void index_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1476*9a0e4156SSadaf Ebrahimi {
1477*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1478*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1479*9a0e4156SSadaf Ebrahimi 
1480*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_CONSTANT;
1481*9a0e4156SSadaf Ebrahimi 	read_byte(info, &op->const_val, (*address)++);
1482*9a0e4156SSadaf Ebrahimi };
1483*9a0e4156SSadaf Ebrahimi 
direct_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1484*9a0e4156SSadaf Ebrahimi static void direct_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1485*9a0e4156SSadaf Ebrahimi {
1486*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1487*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1488*9a0e4156SSadaf Ebrahimi 
1489*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_DIRECT;
1490*9a0e4156SSadaf Ebrahimi 	set_operand_size(info, op, 1);
1491*9a0e4156SSadaf Ebrahimi 	read_byte(info, &op->direct_addr, (*address)++);
1492*9a0e4156SSadaf Ebrahimi };
1493*9a0e4156SSadaf Ebrahimi 
extended_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1494*9a0e4156SSadaf Ebrahimi static void extended_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1495*9a0e4156SSadaf Ebrahimi {
1496*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1497*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1498*9a0e4156SSadaf Ebrahimi 
1499*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_EXTENDED;
1500*9a0e4156SSadaf Ebrahimi 	set_operand_size(info, op, 1);
1501*9a0e4156SSadaf Ebrahimi 	read_word(info, &op->ext.address, *address);
1502*9a0e4156SSadaf Ebrahimi 	*address += 2;
1503*9a0e4156SSadaf Ebrahimi }
1504*9a0e4156SSadaf Ebrahimi 
immediate_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1505*9a0e4156SSadaf Ebrahimi static void immediate_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1506*9a0e4156SSadaf Ebrahimi {
1507*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1508*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1509*9a0e4156SSadaf Ebrahimi 	uint16_t word = 0;
1510*9a0e4156SSadaf Ebrahimi 	int16_t sword = 0;
1511*9a0e4156SSadaf Ebrahimi 
1512*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_IMMEDIATE;
1513*9a0e4156SSadaf Ebrahimi 	set_operand_size(info, op, 1);
1514*9a0e4156SSadaf Ebrahimi 
1515*9a0e4156SSadaf Ebrahimi 	switch (op->size) {
1516*9a0e4156SSadaf Ebrahimi 	case 1:
1517*9a0e4156SSadaf Ebrahimi 		read_byte_sign_extended(info, &sword, *address);
1518*9a0e4156SSadaf Ebrahimi 		op->imm = sword;
1519*9a0e4156SSadaf Ebrahimi 		break;
1520*9a0e4156SSadaf Ebrahimi 
1521*9a0e4156SSadaf Ebrahimi 	case 2:
1522*9a0e4156SSadaf Ebrahimi 		read_word(info, &word, *address);
1523*9a0e4156SSadaf Ebrahimi 		op->imm = (int16_t)word;
1524*9a0e4156SSadaf Ebrahimi 		break;
1525*9a0e4156SSadaf Ebrahimi 
1526*9a0e4156SSadaf Ebrahimi 	case 4:
1527*9a0e4156SSadaf Ebrahimi 		read_sdword(info, &op->imm, *address);
1528*9a0e4156SSadaf Ebrahimi 		break;
1529*9a0e4156SSadaf Ebrahimi 
1530*9a0e4156SSadaf Ebrahimi 	default:
1531*9a0e4156SSadaf Ebrahimi 		op->imm = 0;
1532*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Unexpected immediate byte "
1533*9a0e4156SSadaf Ebrahimi 			"size %d.\n", op->size);
1534*9a0e4156SSadaf Ebrahimi 	}
1535*9a0e4156SSadaf Ebrahimi 
1536*9a0e4156SSadaf Ebrahimi 	*address += op->size;
1537*9a0e4156SSadaf Ebrahimi }
1538*9a0e4156SSadaf Ebrahimi 
1539*9a0e4156SSadaf Ebrahimi // handler for bit move instructions, e.g: BAND A,5,1,$40  Used by HD6309
bit_move_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1540*9a0e4156SSadaf Ebrahimi static void bit_move_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1541*9a0e4156SSadaf Ebrahimi {
1542*9a0e4156SSadaf Ebrahimi 	static const m680x_reg m680x_reg[] = {
1543*9a0e4156SSadaf Ebrahimi 		M680X_REG_CC, M680X_REG_A, M680X_REG_B, M680X_REG_INVALID,
1544*9a0e4156SSadaf Ebrahimi 	};
1545*9a0e4156SSadaf Ebrahimi 
1546*9a0e4156SSadaf Ebrahimi 	uint8_t post_byte = 0;
1547*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1548*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op;
1549*9a0e4156SSadaf Ebrahimi 
1550*9a0e4156SSadaf Ebrahimi 	read_byte(info, &post_byte, *address);
1551*9a0e4156SSadaf Ebrahimi 	(*address)++;
1552*9a0e4156SSadaf Ebrahimi 
1553*9a0e4156SSadaf Ebrahimi 	// operand[0] = register
1554*9a0e4156SSadaf Ebrahimi 	add_reg_operand(info, m680x_reg[post_byte >> 6]);
1555*9a0e4156SSadaf Ebrahimi 
1556*9a0e4156SSadaf Ebrahimi 	// operand[1] = bit index in source operand
1557*9a0e4156SSadaf Ebrahimi 	op = &m680x->operands[m680x->op_count++];
1558*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_CONSTANT;
1559*9a0e4156SSadaf Ebrahimi 	op->const_val = (post_byte >> 3) & 0x07;
1560*9a0e4156SSadaf Ebrahimi 
1561*9a0e4156SSadaf Ebrahimi 	// operand[2] = bit index in destination operand
1562*9a0e4156SSadaf Ebrahimi 	op = &m680x->operands[m680x->op_count++];
1563*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_CONSTANT;
1564*9a0e4156SSadaf Ebrahimi 	op->const_val = post_byte & 0x07;
1565*9a0e4156SSadaf Ebrahimi 
1566*9a0e4156SSadaf Ebrahimi 	direct_hdlr(MI, info, address);
1567*9a0e4156SSadaf Ebrahimi }
1568*9a0e4156SSadaf Ebrahimi 
1569*9a0e4156SSadaf Ebrahimi // handler for TFM instruction, e.g: TFM X+,Y+  Used by HD6309
tfm_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1570*9a0e4156SSadaf Ebrahimi static void tfm_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1571*9a0e4156SSadaf Ebrahimi {
1572*9a0e4156SSadaf Ebrahimi 	static const uint8_t inc_dec_r0[] = {
1573*9a0e4156SSadaf Ebrahimi 		1, -1, 1, 0,
1574*9a0e4156SSadaf Ebrahimi 	};
1575*9a0e4156SSadaf Ebrahimi 	static const uint8_t inc_dec_r1[] = {
1576*9a0e4156SSadaf Ebrahimi 		1, -1, 0, 1,
1577*9a0e4156SSadaf Ebrahimi 	};
1578*9a0e4156SSadaf Ebrahimi 	uint8_t regs = 0;
1579*9a0e4156SSadaf Ebrahimi 	uint8_t index = (MI->Opcode & 0xff) - 0x38;
1580*9a0e4156SSadaf Ebrahimi 
1581*9a0e4156SSadaf Ebrahimi 	read_byte(info, &regs, *address);
1582*9a0e4156SSadaf Ebrahimi 
1583*9a0e4156SSadaf Ebrahimi 	add_indexed_operand(info, g_tfr_exg_reg_ids[regs >> 4], true,
1584*9a0e4156SSadaf Ebrahimi 		inc_dec_r0[index], M680X_OFFSET_NONE, 0, true);
1585*9a0e4156SSadaf Ebrahimi 	add_indexed_operand(info, g_tfr_exg_reg_ids[regs & 0x0f], true,
1586*9a0e4156SSadaf Ebrahimi 		inc_dec_r1[index], M680X_OFFSET_NONE, 0, true);
1587*9a0e4156SSadaf Ebrahimi 
1588*9a0e4156SSadaf Ebrahimi 	add_reg_to_rw_list(MI, M680X_REG_W, READ | WRITE);
1589*9a0e4156SSadaf Ebrahimi }
1590*9a0e4156SSadaf Ebrahimi 
opidx_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1591*9a0e4156SSadaf Ebrahimi static void opidx_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1592*9a0e4156SSadaf Ebrahimi {
1593*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1594*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1595*9a0e4156SSadaf Ebrahimi 
1596*9a0e4156SSadaf Ebrahimi 	// bit index is coded in Opcode
1597*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_CONSTANT;
1598*9a0e4156SSadaf Ebrahimi 	op->const_val = (MI->Opcode & 0x0e) >> 1;
1599*9a0e4156SSadaf Ebrahimi }
1600*9a0e4156SSadaf Ebrahimi 
1601*9a0e4156SSadaf Ebrahimi // handler for bit test and branch instruction. Used by M6805.
1602*9a0e4156SSadaf Ebrahimi // The bit index is part of the opcode.
1603*9a0e4156SSadaf Ebrahimi // Example: BRSET 3,<$40,LOOP
opidx_dir_rel_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1604*9a0e4156SSadaf Ebrahimi static void opidx_dir_rel_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1605*9a0e4156SSadaf Ebrahimi {
1606*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1607*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1608*9a0e4156SSadaf Ebrahimi 
1609*9a0e4156SSadaf Ebrahimi 	// bit index is coded in Opcode
1610*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_CONSTANT;
1611*9a0e4156SSadaf Ebrahimi 	op->const_val = (MI->Opcode & 0x0e) >> 1;
1612*9a0e4156SSadaf Ebrahimi 	direct_hdlr(MI, info, address);
1613*9a0e4156SSadaf Ebrahimi 	relative8_hdlr(MI, info, address);
1614*9a0e4156SSadaf Ebrahimi 
1615*9a0e4156SSadaf Ebrahimi 	add_reg_to_rw_list(MI, M680X_REG_CC, MODIFY);
1616*9a0e4156SSadaf Ebrahimi }
1617*9a0e4156SSadaf Ebrahimi 
indexedX0_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1618*9a0e4156SSadaf Ebrahimi static void indexedX0_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1619*9a0e4156SSadaf Ebrahimi {
1620*9a0e4156SSadaf Ebrahimi 	add_indexed_operand(info, M680X_REG_X, false, 0, M680X_OFFSET_NONE,
1621*9a0e4156SSadaf Ebrahimi 		0, false);
1622*9a0e4156SSadaf Ebrahimi }
1623*9a0e4156SSadaf Ebrahimi 
indexedX16_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1624*9a0e4156SSadaf Ebrahimi static void indexedX16_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1625*9a0e4156SSadaf Ebrahimi {
1626*9a0e4156SSadaf Ebrahimi 	uint16_t offset = 0;
1627*9a0e4156SSadaf Ebrahimi 
1628*9a0e4156SSadaf Ebrahimi 	read_word(info, &offset, *address);
1629*9a0e4156SSadaf Ebrahimi 	*address += 2;
1630*9a0e4156SSadaf Ebrahimi 	add_indexed_operand(info, M680X_REG_X, false, 0, M680X_OFFSET_BITS_16,
1631*9a0e4156SSadaf Ebrahimi 		offset, false);
1632*9a0e4156SSadaf Ebrahimi }
1633*9a0e4156SSadaf Ebrahimi 
imm_rel_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1634*9a0e4156SSadaf Ebrahimi static void imm_rel_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1635*9a0e4156SSadaf Ebrahimi {
1636*9a0e4156SSadaf Ebrahimi 	immediate_hdlr(MI, info, address);
1637*9a0e4156SSadaf Ebrahimi 	relative8_hdlr(MI, info, address);
1638*9a0e4156SSadaf Ebrahimi }
1639*9a0e4156SSadaf Ebrahimi 
indexedS_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1640*9a0e4156SSadaf Ebrahimi static void indexedS_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1641*9a0e4156SSadaf Ebrahimi {
1642*9a0e4156SSadaf Ebrahimi 	uint8_t offset = 0;
1643*9a0e4156SSadaf Ebrahimi 
1644*9a0e4156SSadaf Ebrahimi 	read_byte(info, &offset, (*address)++);
1645*9a0e4156SSadaf Ebrahimi 
1646*9a0e4156SSadaf Ebrahimi 	add_indexed_operand(info, M680X_REG_S, false, 0, M680X_OFFSET_BITS_8,
1647*9a0e4156SSadaf Ebrahimi 		(uint16_t)offset, false);
1648*9a0e4156SSadaf Ebrahimi }
1649*9a0e4156SSadaf Ebrahimi 
indexedS16_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1650*9a0e4156SSadaf Ebrahimi static void indexedS16_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1651*9a0e4156SSadaf Ebrahimi {
1652*9a0e4156SSadaf Ebrahimi 	uint16_t offset = 0;
1653*9a0e4156SSadaf Ebrahimi 
1654*9a0e4156SSadaf Ebrahimi 	read_word(info, &offset, *address);
1655*9a0e4156SSadaf Ebrahimi 	address += 2;
1656*9a0e4156SSadaf Ebrahimi 
1657*9a0e4156SSadaf Ebrahimi 	add_indexed_operand(info, M680X_REG_S, false, 0, M680X_OFFSET_BITS_16,
1658*9a0e4156SSadaf Ebrahimi 		offset, false);
1659*9a0e4156SSadaf Ebrahimi }
1660*9a0e4156SSadaf Ebrahimi 
indexedX0p_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1661*9a0e4156SSadaf Ebrahimi static void indexedX0p_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1662*9a0e4156SSadaf Ebrahimi {
1663*9a0e4156SSadaf Ebrahimi 	add_indexed_operand(info, M680X_REG_X, true, 1, M680X_OFFSET_NONE,
1664*9a0e4156SSadaf Ebrahimi 		0, true);
1665*9a0e4156SSadaf Ebrahimi }
1666*9a0e4156SSadaf Ebrahimi 
indexedXp_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1667*9a0e4156SSadaf Ebrahimi static void indexedXp_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1668*9a0e4156SSadaf Ebrahimi {
1669*9a0e4156SSadaf Ebrahimi 	uint8_t offset = 0;
1670*9a0e4156SSadaf Ebrahimi 
1671*9a0e4156SSadaf Ebrahimi 	read_byte(info, &offset, (*address)++);
1672*9a0e4156SSadaf Ebrahimi 
1673*9a0e4156SSadaf Ebrahimi 	add_indexed_operand(info, M680X_REG_X, true, 1, M680X_OFFSET_BITS_8,
1674*9a0e4156SSadaf Ebrahimi 		(uint16_t)offset, false);
1675*9a0e4156SSadaf Ebrahimi }
1676*9a0e4156SSadaf Ebrahimi 
imm_idx12_x_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1677*9a0e4156SSadaf Ebrahimi static void imm_idx12_x_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1678*9a0e4156SSadaf Ebrahimi {
1679*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1680*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1681*9a0e4156SSadaf Ebrahimi 
1682*9a0e4156SSadaf Ebrahimi 	indexed12_hdlr(MI, info, address);
1683*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_IMMEDIATE;
1684*9a0e4156SSadaf Ebrahimi 
1685*9a0e4156SSadaf Ebrahimi 	if (info->insn == M680X_INS_MOVW) {
1686*9a0e4156SSadaf Ebrahimi 		uint16_t imm16 = 0;
1687*9a0e4156SSadaf Ebrahimi 
1688*9a0e4156SSadaf Ebrahimi 		read_word(info, &imm16, *address);
1689*9a0e4156SSadaf Ebrahimi 		op->imm = (int16_t)imm16;
1690*9a0e4156SSadaf Ebrahimi 		op->size = 2;
1691*9a0e4156SSadaf Ebrahimi 	}
1692*9a0e4156SSadaf Ebrahimi 	else {
1693*9a0e4156SSadaf Ebrahimi 		uint8_t imm8 = 0;
1694*9a0e4156SSadaf Ebrahimi 
1695*9a0e4156SSadaf Ebrahimi 		read_byte(info, &imm8, *address);
1696*9a0e4156SSadaf Ebrahimi 		op->imm = (int8_t)imm8;
1697*9a0e4156SSadaf Ebrahimi 		op->size = 1;
1698*9a0e4156SSadaf Ebrahimi 	}
1699*9a0e4156SSadaf Ebrahimi 
1700*9a0e4156SSadaf Ebrahimi 	set_operand_size(info, op, 1);
1701*9a0e4156SSadaf Ebrahimi }
1702*9a0e4156SSadaf Ebrahimi 
ext_idx12_x_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1703*9a0e4156SSadaf Ebrahimi static void ext_idx12_x_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1704*9a0e4156SSadaf Ebrahimi {
1705*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1706*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op0 = &m680x->operands[m680x->op_count++];
1707*9a0e4156SSadaf Ebrahimi 	uint16_t imm16 = 0;
1708*9a0e4156SSadaf Ebrahimi 
1709*9a0e4156SSadaf Ebrahimi 	indexed12_hdlr(MI, info, address);
1710*9a0e4156SSadaf Ebrahimi 	read_word(info, &imm16, *address);
1711*9a0e4156SSadaf Ebrahimi 	op0->type = M680X_OP_EXTENDED;
1712*9a0e4156SSadaf Ebrahimi 	op0->ext.address = (int16_t)imm16;
1713*9a0e4156SSadaf Ebrahimi 	set_operand_size(info, op0, 1);
1714*9a0e4156SSadaf Ebrahimi }
1715*9a0e4156SSadaf Ebrahimi 
1716*9a0e4156SSadaf Ebrahimi // handler for CPU12 DBEQ/DNBE/IBEQ/IBNE/TBEQ/TBNE instructions.
1717*9a0e4156SSadaf Ebrahimi // Example: DBNE X,$1000
loop_hdlr(MCInst * MI,m680x_info * info,uint16_t * address)1718*9a0e4156SSadaf Ebrahimi static void loop_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1719*9a0e4156SSadaf Ebrahimi {
1720*9a0e4156SSadaf Ebrahimi 	static const m680x_reg index_to_reg_id[] = {
1721*9a0e4156SSadaf Ebrahimi 		M680X_REG_A, M680X_REG_B, M680X_REG_INVALID, M680X_REG_INVALID,
1722*9a0e4156SSadaf Ebrahimi 		M680X_REG_D, M680X_REG_X, M680X_REG_Y, M680X_REG_S,
1723*9a0e4156SSadaf Ebrahimi 	};
1724*9a0e4156SSadaf Ebrahimi 	static const m680x_insn index_to_insn_id[] = {
1725*9a0e4156SSadaf Ebrahimi 		M680X_INS_DBEQ, M680X_INS_DBNE, M680X_INS_TBEQ, M680X_INS_TBNE,
1726*9a0e4156SSadaf Ebrahimi 		M680X_INS_IBEQ, M680X_INS_IBNE, M680X_INS_ILLGL, M680X_INS_ILLGL
1727*9a0e4156SSadaf Ebrahimi 	};
1728*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1729*9a0e4156SSadaf Ebrahimi 	uint8_t post_byte = 0;
1730*9a0e4156SSadaf Ebrahimi 	uint8_t rel = 0;
1731*9a0e4156SSadaf Ebrahimi 	cs_m680x_op *op;
1732*9a0e4156SSadaf Ebrahimi 
1733*9a0e4156SSadaf Ebrahimi 	read_byte(info, &post_byte, (*address)++);
1734*9a0e4156SSadaf Ebrahimi 
1735*9a0e4156SSadaf Ebrahimi 	info->insn = index_to_insn_id[(post_byte >> 5) & 0x07];
1736*9a0e4156SSadaf Ebrahimi 
1737*9a0e4156SSadaf Ebrahimi 	if (info->insn == M680X_INS_ILLGL) {
1738*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Unexpected post byte "
1739*9a0e4156SSadaf Ebrahimi 			"in loop instruction %02X.\n", post_byte);
1740*9a0e4156SSadaf Ebrahimi 		illegal_hdlr(MI, info, address);
1741*9a0e4156SSadaf Ebrahimi 	};
1742*9a0e4156SSadaf Ebrahimi 
1743*9a0e4156SSadaf Ebrahimi 	read_byte(info, &rel, (*address)++);
1744*9a0e4156SSadaf Ebrahimi 
1745*9a0e4156SSadaf Ebrahimi 	add_reg_operand(info, index_to_reg_id[post_byte & 0x07]);
1746*9a0e4156SSadaf Ebrahimi 
1747*9a0e4156SSadaf Ebrahimi 	op = &m680x->operands[m680x->op_count++];
1748*9a0e4156SSadaf Ebrahimi 
1749*9a0e4156SSadaf Ebrahimi 	op->type = M680X_OP_RELATIVE;
1750*9a0e4156SSadaf Ebrahimi 
1751*9a0e4156SSadaf Ebrahimi 	op->rel.offset = (post_byte & 0x10) ? 0xff00 | rel : rel;
1752*9a0e4156SSadaf Ebrahimi 
1753*9a0e4156SSadaf Ebrahimi 	op->rel.address = *address + op->rel.offset;
1754*9a0e4156SSadaf Ebrahimi 
1755*9a0e4156SSadaf Ebrahimi 	add_insn_group(MI->flat_insn->detail, M680X_GRP_BRAREL);
1756*9a0e4156SSadaf Ebrahimi }
1757*9a0e4156SSadaf Ebrahimi 
1758*9a0e4156SSadaf Ebrahimi static void (*const g_insn_handler[])(MCInst *, m680x_info *, uint16_t *) = {
1759*9a0e4156SSadaf Ebrahimi 	illegal_hdlr,
1760*9a0e4156SSadaf Ebrahimi 	relative8_hdlr,
1761*9a0e4156SSadaf Ebrahimi 	relative16_hdlr,
1762*9a0e4156SSadaf Ebrahimi 	immediate_hdlr, // 8-bit
1763*9a0e4156SSadaf Ebrahimi 	immediate_hdlr, // 16-bit
1764*9a0e4156SSadaf Ebrahimi 	immediate_hdlr, // 32-bit
1765*9a0e4156SSadaf Ebrahimi 	direct_hdlr,
1766*9a0e4156SSadaf Ebrahimi 	extended_hdlr,
1767*9a0e4156SSadaf Ebrahimi 	indexedX_hdlr,
1768*9a0e4156SSadaf Ebrahimi 	indexedY_hdlr,
1769*9a0e4156SSadaf Ebrahimi 	indexed09_hdlr,
1770*9a0e4156SSadaf Ebrahimi 	inherent_hdlr,
1771*9a0e4156SSadaf Ebrahimi 	reg_reg09_hdlr,
1772*9a0e4156SSadaf Ebrahimi 	reg_bits_hdlr,
1773*9a0e4156SSadaf Ebrahimi 	bit_move_hdlr,
1774*9a0e4156SSadaf Ebrahimi 	tfm_hdlr,
1775*9a0e4156SSadaf Ebrahimi 	opidx_hdlr,
1776*9a0e4156SSadaf Ebrahimi 	opidx_dir_rel_hdlr,
1777*9a0e4156SSadaf Ebrahimi 	indexedX0_hdlr,
1778*9a0e4156SSadaf Ebrahimi 	indexedX16_hdlr,
1779*9a0e4156SSadaf Ebrahimi 	imm_rel_hdlr,
1780*9a0e4156SSadaf Ebrahimi 	indexedS_hdlr,
1781*9a0e4156SSadaf Ebrahimi 	indexedS16_hdlr,
1782*9a0e4156SSadaf Ebrahimi 	indexedXp_hdlr,
1783*9a0e4156SSadaf Ebrahimi 	indexedX0p_hdlr,
1784*9a0e4156SSadaf Ebrahimi 	indexed12_hdlr,
1785*9a0e4156SSadaf Ebrahimi 	indexed12_hdlr, // subset of indexed12
1786*9a0e4156SSadaf Ebrahimi 	reg_reg12_hdlr,
1787*9a0e4156SSadaf Ebrahimi 	loop_hdlr,
1788*9a0e4156SSadaf Ebrahimi 	index_hdlr,
1789*9a0e4156SSadaf Ebrahimi 	imm_idx12_x_hdlr,
1790*9a0e4156SSadaf Ebrahimi 	imm_idx12_x_hdlr,
1791*9a0e4156SSadaf Ebrahimi 	ext_idx12_x_hdlr,
1792*9a0e4156SSadaf Ebrahimi }; /* handler function pointers */
1793*9a0e4156SSadaf Ebrahimi 
1794*9a0e4156SSadaf Ebrahimi /* Disasemble one instruction at address and store in str_buff */
m680x_disassemble(MCInst * MI,m680x_info * info,uint16_t address)1795*9a0e4156SSadaf Ebrahimi static unsigned int m680x_disassemble(MCInst *MI, m680x_info *info,
1796*9a0e4156SSadaf Ebrahimi 	uint16_t address)
1797*9a0e4156SSadaf Ebrahimi {
1798*9a0e4156SSadaf Ebrahimi 	cs_m680x *m680x = &info->m680x;
1799*9a0e4156SSadaf Ebrahimi 	cs_detail *detail = MI->flat_insn->detail;
1800*9a0e4156SSadaf Ebrahimi 	uint16_t base_address = address;
1801*9a0e4156SSadaf Ebrahimi 	insn_desc insn_description;
1802*9a0e4156SSadaf Ebrahimi 	e_access_mode access_mode;
1803*9a0e4156SSadaf Ebrahimi 
1804*9a0e4156SSadaf Ebrahimi 	if (detail != NULL) {
1805*9a0e4156SSadaf Ebrahimi 		memset(detail, 0, offsetof(cs_detail, m680x)+sizeof(cs_m680x));
1806*9a0e4156SSadaf Ebrahimi 	}
1807*9a0e4156SSadaf Ebrahimi 
1808*9a0e4156SSadaf Ebrahimi 	memset(&insn_description, 0, sizeof(insn_description));
1809*9a0e4156SSadaf Ebrahimi 	memset(m680x, 0, sizeof(*m680x));
1810*9a0e4156SSadaf Ebrahimi 	info->insn_size = 1;
1811*9a0e4156SSadaf Ebrahimi 
1812*9a0e4156SSadaf Ebrahimi 	if (decode_insn(info, address, &insn_description)) {
1813*9a0e4156SSadaf Ebrahimi 		m680x_reg reg;
1814*9a0e4156SSadaf Ebrahimi 
1815*9a0e4156SSadaf Ebrahimi 		if (insn_description.opcode > 0xff)
1816*9a0e4156SSadaf Ebrahimi 			address += 2; // 8-bit opcode + page prefix
1817*9a0e4156SSadaf Ebrahimi 		else
1818*9a0e4156SSadaf Ebrahimi 			address++; // 8-bit opcode only
1819*9a0e4156SSadaf Ebrahimi 
1820*9a0e4156SSadaf Ebrahimi 		info->insn = insn_description.insn;
1821*9a0e4156SSadaf Ebrahimi 
1822*9a0e4156SSadaf Ebrahimi 		MCInst_setOpcode(MI, insn_description.opcode);
1823*9a0e4156SSadaf Ebrahimi 
1824*9a0e4156SSadaf Ebrahimi 		reg = g_insn_props[info->insn].reg0;
1825*9a0e4156SSadaf Ebrahimi 
1826*9a0e4156SSadaf Ebrahimi 		if (reg != M680X_REG_INVALID) {
1827*9a0e4156SSadaf Ebrahimi 			if (reg == M680X_REG_HX &&
1828*9a0e4156SSadaf Ebrahimi 				(!info->cpu->reg_byte_size[reg]))
1829*9a0e4156SSadaf Ebrahimi 				reg = M680X_REG_X;
1830*9a0e4156SSadaf Ebrahimi 
1831*9a0e4156SSadaf Ebrahimi 			add_reg_operand(info, reg);
1832*9a0e4156SSadaf Ebrahimi 			// First (or second) operand is a register which is
1833*9a0e4156SSadaf Ebrahimi 			// part of the mnemonic
1834*9a0e4156SSadaf Ebrahimi 			m680x->flags |= M680X_FIRST_OP_IN_MNEM;
1835*9a0e4156SSadaf Ebrahimi 			reg = g_insn_props[info->insn].reg1;
1836*9a0e4156SSadaf Ebrahimi 
1837*9a0e4156SSadaf Ebrahimi 			if (reg != M680X_REG_INVALID) {
1838*9a0e4156SSadaf Ebrahimi 				if (reg == M680X_REG_HX &&
1839*9a0e4156SSadaf Ebrahimi 					(!info->cpu->reg_byte_size[reg]))
1840*9a0e4156SSadaf Ebrahimi 					reg = M680X_REG_X;
1841*9a0e4156SSadaf Ebrahimi 
1842*9a0e4156SSadaf Ebrahimi 				add_reg_operand(info, reg);
1843*9a0e4156SSadaf Ebrahimi 				m680x->flags |= M680X_SECOND_OP_IN_MNEM;
1844*9a0e4156SSadaf Ebrahimi 			}
1845*9a0e4156SSadaf Ebrahimi 		}
1846*9a0e4156SSadaf Ebrahimi 
1847*9a0e4156SSadaf Ebrahimi 		// Call addressing mode specific instruction handler
1848*9a0e4156SSadaf Ebrahimi 		(g_insn_handler[insn_description.hid[0]])(MI, info,
1849*9a0e4156SSadaf Ebrahimi 			&address);
1850*9a0e4156SSadaf Ebrahimi 		(g_insn_handler[insn_description.hid[1]])(MI, info,
1851*9a0e4156SSadaf Ebrahimi 			&address);
1852*9a0e4156SSadaf Ebrahimi 
1853*9a0e4156SSadaf Ebrahimi 		add_insn_group(detail, g_insn_props[info->insn].group);
1854*9a0e4156SSadaf Ebrahimi 
1855*9a0e4156SSadaf Ebrahimi 		if (g_insn_props[info->insn].cc_modified &&
1856*9a0e4156SSadaf Ebrahimi 			(info->cpu->insn_cc_not_modified[0] != info->insn) &&
1857*9a0e4156SSadaf Ebrahimi 			(info->cpu->insn_cc_not_modified[1] != info->insn))
1858*9a0e4156SSadaf Ebrahimi 			add_reg_to_rw_list(MI, M680X_REG_CC, MODIFY);
1859*9a0e4156SSadaf Ebrahimi 
1860*9a0e4156SSadaf Ebrahimi 		access_mode = g_insn_props[info->insn].access_mode;
1861*9a0e4156SSadaf Ebrahimi 
1862*9a0e4156SSadaf Ebrahimi 		// Fix for M6805 BSET/BCLR. It has a differnt operand order
1863*9a0e4156SSadaf Ebrahimi 		// in comparison to the M6811
1864*9a0e4156SSadaf Ebrahimi 		if ((info->cpu->insn_cc_not_modified[0] == info->insn) ||
1865*9a0e4156SSadaf Ebrahimi 			(info->cpu->insn_cc_not_modified[1] == info->insn))
1866*9a0e4156SSadaf Ebrahimi 			access_mode = rmmm;
1867*9a0e4156SSadaf Ebrahimi 
1868*9a0e4156SSadaf Ebrahimi 		build_regs_read_write_counts(MI, info, access_mode);
1869*9a0e4156SSadaf Ebrahimi 		add_operators_access(MI, info, access_mode);
1870*9a0e4156SSadaf Ebrahimi 
1871*9a0e4156SSadaf Ebrahimi 		if (g_insn_props[info->insn].update_reg_access)
1872*9a0e4156SSadaf Ebrahimi 			set_changed_regs_read_write_counts(MI, info);
1873*9a0e4156SSadaf Ebrahimi 
1874*9a0e4156SSadaf Ebrahimi 		info->insn_size = insn_description.insn_size;
1875*9a0e4156SSadaf Ebrahimi 
1876*9a0e4156SSadaf Ebrahimi 		return info->insn_size;
1877*9a0e4156SSadaf Ebrahimi 	}
1878*9a0e4156SSadaf Ebrahimi 	else
1879*9a0e4156SSadaf Ebrahimi 		MCInst_setOpcode(MI, insn_description.opcode);
1880*9a0e4156SSadaf Ebrahimi 
1881*9a0e4156SSadaf Ebrahimi 	// Illegal instruction
1882*9a0e4156SSadaf Ebrahimi 	address = base_address;
1883*9a0e4156SSadaf Ebrahimi 	illegal_hdlr(MI, info, &address);
1884*9a0e4156SSadaf Ebrahimi 	return 1;
1885*9a0e4156SSadaf Ebrahimi }
1886*9a0e4156SSadaf Ebrahimi 
1887*9a0e4156SSadaf Ebrahimi // Tables to get the byte size of a register on the CPU
1888*9a0e4156SSadaf Ebrahimi // based on an enum m680x_reg value.
1889*9a0e4156SSadaf Ebrahimi // Invalid registers return 0.
1890*9a0e4156SSadaf Ebrahimi static const uint8_t g_m6800_reg_byte_size[22] = {
1891*9a0e4156SSadaf Ebrahimi 	// A  B  E  F  0  D  W  CC DP MD HX H  X  Y  S  U  V  Q  PC T2 T3
1892*9a0e4156SSadaf Ebrahimi 	0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0
1893*9a0e4156SSadaf Ebrahimi };
1894*9a0e4156SSadaf Ebrahimi 
1895*9a0e4156SSadaf Ebrahimi static const uint8_t g_m6805_reg_byte_size[22] = {
1896*9a0e4156SSadaf Ebrahimi 	// A  B  E  F  0  D  W  CC DP MD HX H  X  Y  S  U  V  Q  PC T2 T3
1897*9a0e4156SSadaf Ebrahimi 	0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 2, 0, 0
1898*9a0e4156SSadaf Ebrahimi };
1899*9a0e4156SSadaf Ebrahimi 
1900*9a0e4156SSadaf Ebrahimi static const uint8_t g_m6808_reg_byte_size[22] = {
1901*9a0e4156SSadaf Ebrahimi 	// A  B  E  F  0  D  W  CC DP MD HX H  X  Y  S  U  V  Q  PC T2 T3
1902*9a0e4156SSadaf Ebrahimi 	0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 1, 0, 2, 0, 0, 0, 2, 0, 0
1903*9a0e4156SSadaf Ebrahimi };
1904*9a0e4156SSadaf Ebrahimi 
1905*9a0e4156SSadaf Ebrahimi static const uint8_t g_m6801_reg_byte_size[22] = {
1906*9a0e4156SSadaf Ebrahimi 	// A  B  E  F  0  D  W  CC DP MD HX H  X  Y  S  U  V  Q  PC T2 T3
1907*9a0e4156SSadaf Ebrahimi 	0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0
1908*9a0e4156SSadaf Ebrahimi };
1909*9a0e4156SSadaf Ebrahimi 
1910*9a0e4156SSadaf Ebrahimi static const uint8_t g_m6811_reg_byte_size[22] = {
1911*9a0e4156SSadaf Ebrahimi 	// A  B  E  F  0  D  W  CC DP MD HX H  X  Y  S  U  V  Q  PC T2 T3
1912*9a0e4156SSadaf Ebrahimi 	0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 0, 0
1913*9a0e4156SSadaf Ebrahimi };
1914*9a0e4156SSadaf Ebrahimi 
1915*9a0e4156SSadaf Ebrahimi static const uint8_t g_cpu12_reg_byte_size[22] = {
1916*9a0e4156SSadaf Ebrahimi 	// A  B  E  F  0  D  W  CC DP MD HX H  X  Y  S  U  V  Q  PC T2 T3
1917*9a0e4156SSadaf Ebrahimi 	0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 2, 2
1918*9a0e4156SSadaf Ebrahimi };
1919*9a0e4156SSadaf Ebrahimi 
1920*9a0e4156SSadaf Ebrahimi static const uint8_t g_m6809_reg_byte_size[22] = {
1921*9a0e4156SSadaf Ebrahimi 	// A  B  E  F  0  D  W  CC DP MD HX H  X  Y  S  U  V  Q  PC T2 T3
1922*9a0e4156SSadaf Ebrahimi 	0, 1, 1, 0, 0, 0, 2, 0, 1, 1, 0, 0, 0, 2, 2, 2, 2, 0, 0, 2, 0, 0
1923*9a0e4156SSadaf Ebrahimi };
1924*9a0e4156SSadaf Ebrahimi 
1925*9a0e4156SSadaf Ebrahimi static const uint8_t g_hd6309_reg_byte_size[22] = {
1926*9a0e4156SSadaf Ebrahimi 	// A  B  E  F  0  D  W  CC DP MD HX H  X  Y  S  U  V  Q  PC T2 T3
1927*9a0e4156SSadaf Ebrahimi 	0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 4, 2, 0, 0
1928*9a0e4156SSadaf Ebrahimi };
1929*9a0e4156SSadaf Ebrahimi 
1930*9a0e4156SSadaf Ebrahimi // Table to check for a valid register nibble on the M6809 CPU
1931*9a0e4156SSadaf Ebrahimi // used for TFR and EXG instruction.
1932*9a0e4156SSadaf Ebrahimi static const bool m6809_tfr_reg_valid[16] = {
1933*9a0e4156SSadaf Ebrahimi 	true, true, true, true, true,  true,  false, false,
1934*9a0e4156SSadaf Ebrahimi 	true, true, true, true, false, false, false, false,
1935*9a0e4156SSadaf Ebrahimi };
1936*9a0e4156SSadaf Ebrahimi 
1937*9a0e4156SSadaf Ebrahimi static const cpu_tables g_cpu_tables[] = {
1938*9a0e4156SSadaf Ebrahimi 	{
1939*9a0e4156SSadaf Ebrahimi 		// M680X_CPU_TYPE_INVALID
1940*9a0e4156SSadaf Ebrahimi 		NULL,
1941*9a0e4156SSadaf Ebrahimi 		{ NULL, NULL },
1942*9a0e4156SSadaf Ebrahimi 		{ 0, 0 },
1943*9a0e4156SSadaf Ebrahimi 		{ 0x00, 0x00, 0x00 },
1944*9a0e4156SSadaf Ebrahimi 		{ NULL, NULL, NULL },
1945*9a0e4156SSadaf Ebrahimi 		{ 0, 0, 0 },
1946*9a0e4156SSadaf Ebrahimi 		NULL,
1947*9a0e4156SSadaf Ebrahimi 		NULL,
1948*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_INVLD, M680X_INS_INVLD }
1949*9a0e4156SSadaf Ebrahimi 	},
1950*9a0e4156SSadaf Ebrahimi 	{
1951*9a0e4156SSadaf Ebrahimi 		// M680X_CPU_TYPE_6301
1952*9a0e4156SSadaf Ebrahimi 		&g_m6800_inst_page1_table[0],
1953*9a0e4156SSadaf Ebrahimi 		{ &g_m6801_inst_overlay_table[0], &g_hd6301_inst_overlay_table[0] },
1954*9a0e4156SSadaf Ebrahimi 		{
1955*9a0e4156SSadaf Ebrahimi 			ARR_SIZE(g_m6801_inst_overlay_table),
1956*9a0e4156SSadaf Ebrahimi 			ARR_SIZE(g_hd6301_inst_overlay_table)
1957*9a0e4156SSadaf Ebrahimi 		},
1958*9a0e4156SSadaf Ebrahimi 		{ 0x00, 0x00, 0x00 },
1959*9a0e4156SSadaf Ebrahimi 		{ NULL, NULL, NULL },
1960*9a0e4156SSadaf Ebrahimi 		{ 0, 0, 0 },
1961*9a0e4156SSadaf Ebrahimi 		&g_m6801_reg_byte_size[0],
1962*9a0e4156SSadaf Ebrahimi 		NULL,
1963*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_INVLD, M680X_INS_INVLD }
1964*9a0e4156SSadaf Ebrahimi 	},
1965*9a0e4156SSadaf Ebrahimi 	{
1966*9a0e4156SSadaf Ebrahimi 		// M680X_CPU_TYPE_6309
1967*9a0e4156SSadaf Ebrahimi 		&g_m6809_inst_page1_table[0],
1968*9a0e4156SSadaf Ebrahimi 		{ &g_hd6309_inst_overlay_table[0], NULL },
1969*9a0e4156SSadaf Ebrahimi 		{ ARR_SIZE(g_hd6309_inst_overlay_table), 0 },
1970*9a0e4156SSadaf Ebrahimi 		{ 0x10, 0x11, 0x00 },
1971*9a0e4156SSadaf Ebrahimi 		{ &g_hd6309_inst_page2_table[0], &g_hd6309_inst_page3_table[0], NULL },
1972*9a0e4156SSadaf Ebrahimi 		{
1973*9a0e4156SSadaf Ebrahimi 			ARR_SIZE(g_hd6309_inst_page2_table),
1974*9a0e4156SSadaf Ebrahimi 			ARR_SIZE(g_hd6309_inst_page3_table),
1975*9a0e4156SSadaf Ebrahimi 			0
1976*9a0e4156SSadaf Ebrahimi 		},
1977*9a0e4156SSadaf Ebrahimi 		&g_hd6309_reg_byte_size[0],
1978*9a0e4156SSadaf Ebrahimi 		NULL,
1979*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_INVLD, M680X_INS_INVLD }
1980*9a0e4156SSadaf Ebrahimi 	},
1981*9a0e4156SSadaf Ebrahimi 	{
1982*9a0e4156SSadaf Ebrahimi 		// M680X_CPU_TYPE_6800
1983*9a0e4156SSadaf Ebrahimi 		&g_m6800_inst_page1_table[0],
1984*9a0e4156SSadaf Ebrahimi 		{ NULL, NULL },
1985*9a0e4156SSadaf Ebrahimi 		{ 0, 0 },
1986*9a0e4156SSadaf Ebrahimi 		{ 0x00, 0x00, 0x00 },
1987*9a0e4156SSadaf Ebrahimi 		{ NULL, NULL, NULL },
1988*9a0e4156SSadaf Ebrahimi 		{ 0, 0, 0 },
1989*9a0e4156SSadaf Ebrahimi 		&g_m6800_reg_byte_size[0],
1990*9a0e4156SSadaf Ebrahimi 		NULL,
1991*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_INVLD, M680X_INS_INVLD }
1992*9a0e4156SSadaf Ebrahimi 	},
1993*9a0e4156SSadaf Ebrahimi 	{
1994*9a0e4156SSadaf Ebrahimi 		// M680X_CPU_TYPE_6801
1995*9a0e4156SSadaf Ebrahimi 		&g_m6800_inst_page1_table[0],
1996*9a0e4156SSadaf Ebrahimi 		{ &g_m6801_inst_overlay_table[0], NULL },
1997*9a0e4156SSadaf Ebrahimi 		{ ARR_SIZE(g_m6801_inst_overlay_table), 0 },
1998*9a0e4156SSadaf Ebrahimi 		{ 0x00, 0x00, 0x00 },
1999*9a0e4156SSadaf Ebrahimi 		{ NULL, NULL, NULL },
2000*9a0e4156SSadaf Ebrahimi 		{ 0, 0, 0 },
2001*9a0e4156SSadaf Ebrahimi 		&g_m6801_reg_byte_size[0],
2002*9a0e4156SSadaf Ebrahimi 		NULL,
2003*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_INVLD, M680X_INS_INVLD }
2004*9a0e4156SSadaf Ebrahimi 	},
2005*9a0e4156SSadaf Ebrahimi 	{
2006*9a0e4156SSadaf Ebrahimi 		// M680X_CPU_TYPE_6805
2007*9a0e4156SSadaf Ebrahimi 		&g_m6805_inst_page1_table[0],
2008*9a0e4156SSadaf Ebrahimi 		{ NULL, NULL },
2009*9a0e4156SSadaf Ebrahimi 		{ 0, 0 },
2010*9a0e4156SSadaf Ebrahimi 		{ 0x00, 0x00, 0x00 },
2011*9a0e4156SSadaf Ebrahimi 		{ NULL, NULL, NULL },
2012*9a0e4156SSadaf Ebrahimi 		{ 0, 0, 0 },
2013*9a0e4156SSadaf Ebrahimi 		&g_m6805_reg_byte_size[0],
2014*9a0e4156SSadaf Ebrahimi 		NULL,
2015*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_BCLR, M680X_INS_BSET }
2016*9a0e4156SSadaf Ebrahimi 	},
2017*9a0e4156SSadaf Ebrahimi 	{
2018*9a0e4156SSadaf Ebrahimi 		// M680X_CPU_TYPE_6808
2019*9a0e4156SSadaf Ebrahimi 		&g_m6805_inst_page1_table[0],
2020*9a0e4156SSadaf Ebrahimi 		{ &g_m6808_inst_overlay_table[0], NULL },
2021*9a0e4156SSadaf Ebrahimi 		{ ARR_SIZE(g_m6808_inst_overlay_table), 0 },
2022*9a0e4156SSadaf Ebrahimi 		{ 0x9E, 0x00, 0x00 },
2023*9a0e4156SSadaf Ebrahimi 		{ &g_m6808_inst_page2_table[0], NULL, NULL },
2024*9a0e4156SSadaf Ebrahimi 		{ ARR_SIZE(g_m6808_inst_page2_table), 0, 0 },
2025*9a0e4156SSadaf Ebrahimi 		&g_m6808_reg_byte_size[0],
2026*9a0e4156SSadaf Ebrahimi 		NULL,
2027*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_BCLR, M680X_INS_BSET }
2028*9a0e4156SSadaf Ebrahimi 	},
2029*9a0e4156SSadaf Ebrahimi 	{
2030*9a0e4156SSadaf Ebrahimi 		// M680X_CPU_TYPE_6809
2031*9a0e4156SSadaf Ebrahimi 		&g_m6809_inst_page1_table[0],
2032*9a0e4156SSadaf Ebrahimi 		{ NULL, NULL },
2033*9a0e4156SSadaf Ebrahimi 		{ 0, 0 },
2034*9a0e4156SSadaf Ebrahimi 		{ 0x10, 0x11, 0x00 },
2035*9a0e4156SSadaf Ebrahimi 		{
2036*9a0e4156SSadaf Ebrahimi 			&g_m6809_inst_page2_table[0],
2037*9a0e4156SSadaf Ebrahimi 			&g_m6809_inst_page3_table[0],
2038*9a0e4156SSadaf Ebrahimi 			NULL
2039*9a0e4156SSadaf Ebrahimi 		},
2040*9a0e4156SSadaf Ebrahimi 		{
2041*9a0e4156SSadaf Ebrahimi 			ARR_SIZE(g_m6809_inst_page2_table),
2042*9a0e4156SSadaf Ebrahimi 			ARR_SIZE(g_m6809_inst_page3_table),
2043*9a0e4156SSadaf Ebrahimi 			0
2044*9a0e4156SSadaf Ebrahimi 		},
2045*9a0e4156SSadaf Ebrahimi 		&g_m6809_reg_byte_size[0],
2046*9a0e4156SSadaf Ebrahimi 		&m6809_tfr_reg_valid[0],
2047*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_INVLD, M680X_INS_INVLD }
2048*9a0e4156SSadaf Ebrahimi 	},
2049*9a0e4156SSadaf Ebrahimi 	{
2050*9a0e4156SSadaf Ebrahimi 		// M680X_CPU_TYPE_6811
2051*9a0e4156SSadaf Ebrahimi 		&g_m6800_inst_page1_table[0],
2052*9a0e4156SSadaf Ebrahimi 		{
2053*9a0e4156SSadaf Ebrahimi 			&g_m6801_inst_overlay_table[0],
2054*9a0e4156SSadaf Ebrahimi 			&g_m6811_inst_overlay_table[0]
2055*9a0e4156SSadaf Ebrahimi 		},
2056*9a0e4156SSadaf Ebrahimi 		{
2057*9a0e4156SSadaf Ebrahimi 			ARR_SIZE(g_m6801_inst_overlay_table),
2058*9a0e4156SSadaf Ebrahimi 			ARR_SIZE(g_m6811_inst_overlay_table)
2059*9a0e4156SSadaf Ebrahimi 		},
2060*9a0e4156SSadaf Ebrahimi 		{ 0x18, 0x1A, 0xCD },
2061*9a0e4156SSadaf Ebrahimi 		{
2062*9a0e4156SSadaf Ebrahimi 			&g_m6811_inst_page2_table[0],
2063*9a0e4156SSadaf Ebrahimi 			&g_m6811_inst_page3_table[0],
2064*9a0e4156SSadaf Ebrahimi 			&g_m6811_inst_page4_table[0]
2065*9a0e4156SSadaf Ebrahimi 		},
2066*9a0e4156SSadaf Ebrahimi 		{
2067*9a0e4156SSadaf Ebrahimi 			ARR_SIZE(g_m6811_inst_page2_table),
2068*9a0e4156SSadaf Ebrahimi 			ARR_SIZE(g_m6811_inst_page3_table),
2069*9a0e4156SSadaf Ebrahimi 			ARR_SIZE(g_m6811_inst_page4_table)
2070*9a0e4156SSadaf Ebrahimi 		},
2071*9a0e4156SSadaf Ebrahimi 		&g_m6811_reg_byte_size[0],
2072*9a0e4156SSadaf Ebrahimi 		NULL,
2073*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_INVLD, M680X_INS_INVLD }
2074*9a0e4156SSadaf Ebrahimi 	},
2075*9a0e4156SSadaf Ebrahimi 	{
2076*9a0e4156SSadaf Ebrahimi 		// M680X_CPU_TYPE_CPU12
2077*9a0e4156SSadaf Ebrahimi 		&g_cpu12_inst_page1_table[0],
2078*9a0e4156SSadaf Ebrahimi 		{ NULL, NULL },
2079*9a0e4156SSadaf Ebrahimi 		{ 0, 0 },
2080*9a0e4156SSadaf Ebrahimi 		{ 0x18, 0x00, 0x00 },
2081*9a0e4156SSadaf Ebrahimi 		{ &g_cpu12_inst_page2_table[0], NULL, NULL },
2082*9a0e4156SSadaf Ebrahimi 		{ ARR_SIZE(g_cpu12_inst_page2_table), 0, 0 },
2083*9a0e4156SSadaf Ebrahimi 		&g_cpu12_reg_byte_size[0],
2084*9a0e4156SSadaf Ebrahimi 		NULL,
2085*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_INVLD, M680X_INS_INVLD }
2086*9a0e4156SSadaf Ebrahimi 	},
2087*9a0e4156SSadaf Ebrahimi 	{
2088*9a0e4156SSadaf Ebrahimi 		// M680X_CPU_TYPE_HCS08
2089*9a0e4156SSadaf Ebrahimi 		&g_m6805_inst_page1_table[0],
2090*9a0e4156SSadaf Ebrahimi 		{
2091*9a0e4156SSadaf Ebrahimi 			&g_m6808_inst_overlay_table[0],
2092*9a0e4156SSadaf Ebrahimi 			&g_hcs08_inst_overlay_table[0]
2093*9a0e4156SSadaf Ebrahimi 		},
2094*9a0e4156SSadaf Ebrahimi 		{
2095*9a0e4156SSadaf Ebrahimi 			ARR_SIZE(g_m6808_inst_overlay_table),
2096*9a0e4156SSadaf Ebrahimi 			ARR_SIZE(g_hcs08_inst_overlay_table)
2097*9a0e4156SSadaf Ebrahimi 		},
2098*9a0e4156SSadaf Ebrahimi 		{ 0x9E, 0x00, 0x00 },
2099*9a0e4156SSadaf Ebrahimi 		{ &g_hcs08_inst_page2_table[0], NULL, NULL },
2100*9a0e4156SSadaf Ebrahimi 		{ ARR_SIZE(g_hcs08_inst_page2_table), 0, 0 },
2101*9a0e4156SSadaf Ebrahimi 		&g_m6808_reg_byte_size[0],
2102*9a0e4156SSadaf Ebrahimi 		NULL,
2103*9a0e4156SSadaf Ebrahimi 		{ M680X_INS_BCLR, M680X_INS_BSET }
2104*9a0e4156SSadaf Ebrahimi 	},
2105*9a0e4156SSadaf Ebrahimi };
2106*9a0e4156SSadaf Ebrahimi 
2107*9a0e4156SSadaf Ebrahimi static const char *s_cpu_type[] = {
2108*9a0e4156SSadaf Ebrahimi 	"INVALID", "6301", "6309", "6800", "6801", "6805", "6808",
2109*9a0e4156SSadaf Ebrahimi 	"6809", "6811", "CPU12", "HCS08",
2110*9a0e4156SSadaf Ebrahimi };
2111*9a0e4156SSadaf Ebrahimi 
m680x_setup_internals(m680x_info * info,e_cpu_type cpu_type,uint16_t address,const uint8_t * code,uint16_t code_len)2112*9a0e4156SSadaf Ebrahimi static bool m680x_setup_internals(m680x_info *info, e_cpu_type cpu_type,
2113*9a0e4156SSadaf Ebrahimi 	uint16_t address,
2114*9a0e4156SSadaf Ebrahimi 	const uint8_t *code, uint16_t code_len)
2115*9a0e4156SSadaf Ebrahimi {
2116*9a0e4156SSadaf Ebrahimi 	if (cpu_type == M680X_CPU_TYPE_INVALID) {
2117*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "M680X_CPU_TYPE_%s is not suppported\n",
2118*9a0e4156SSadaf Ebrahimi 			s_cpu_type[cpu_type]);
2119*9a0e4156SSadaf Ebrahimi 		return false;
2120*9a0e4156SSadaf Ebrahimi 	}
2121*9a0e4156SSadaf Ebrahimi 
2122*9a0e4156SSadaf Ebrahimi 	info->code = code;
2123*9a0e4156SSadaf Ebrahimi 	info->size = code_len;
2124*9a0e4156SSadaf Ebrahimi 	info->offset = address;
2125*9a0e4156SSadaf Ebrahimi 	info->cpu_type = cpu_type;
2126*9a0e4156SSadaf Ebrahimi 
2127*9a0e4156SSadaf Ebrahimi 	info->cpu = &g_cpu_tables[info->cpu_type];
2128*9a0e4156SSadaf Ebrahimi 
2129*9a0e4156SSadaf Ebrahimi 	return true;
2130*9a0e4156SSadaf Ebrahimi }
2131*9a0e4156SSadaf Ebrahimi 
M680X_getInstruction(csh ud,const uint8_t * code,size_t code_len,MCInst * MI,uint16_t * size,uint64_t address,void * inst_info)2132*9a0e4156SSadaf Ebrahimi bool M680X_getInstruction(csh ud, const uint8_t *code, size_t code_len,
2133*9a0e4156SSadaf Ebrahimi 	MCInst *MI, uint16_t *size, uint64_t address, void *inst_info)
2134*9a0e4156SSadaf Ebrahimi {
2135*9a0e4156SSadaf Ebrahimi 	unsigned int insn_size = 0;
2136*9a0e4156SSadaf Ebrahimi 	e_cpu_type cpu_type = M680X_CPU_TYPE_INVALID; // No default CPU type
2137*9a0e4156SSadaf Ebrahimi 	cs_struct *handle = (cs_struct *)ud;
2138*9a0e4156SSadaf Ebrahimi 	m680x_info *info = (m680x_info *)handle->printer_info;
2139*9a0e4156SSadaf Ebrahimi 
2140*9a0e4156SSadaf Ebrahimi 	MCInst_clear(MI);
2141*9a0e4156SSadaf Ebrahimi 
2142*9a0e4156SSadaf Ebrahimi 	if (handle->mode & CS_MODE_M680X_6800)
2143*9a0e4156SSadaf Ebrahimi 		cpu_type = M680X_CPU_TYPE_6800;
2144*9a0e4156SSadaf Ebrahimi 
2145*9a0e4156SSadaf Ebrahimi 	else if (handle->mode & CS_MODE_M680X_6801)
2146*9a0e4156SSadaf Ebrahimi 		cpu_type = M680X_CPU_TYPE_6801;
2147*9a0e4156SSadaf Ebrahimi 
2148*9a0e4156SSadaf Ebrahimi 	else if (handle->mode & CS_MODE_M680X_6805)
2149*9a0e4156SSadaf Ebrahimi 		cpu_type = M680X_CPU_TYPE_6805;
2150*9a0e4156SSadaf Ebrahimi 
2151*9a0e4156SSadaf Ebrahimi 	else if (handle->mode & CS_MODE_M680X_6808)
2152*9a0e4156SSadaf Ebrahimi 		cpu_type = M680X_CPU_TYPE_6808;
2153*9a0e4156SSadaf Ebrahimi 
2154*9a0e4156SSadaf Ebrahimi 	else if (handle->mode & CS_MODE_M680X_HCS08)
2155*9a0e4156SSadaf Ebrahimi 		cpu_type = M680X_CPU_TYPE_HCS08;
2156*9a0e4156SSadaf Ebrahimi 
2157*9a0e4156SSadaf Ebrahimi 	else if (handle->mode & CS_MODE_M680X_6809)
2158*9a0e4156SSadaf Ebrahimi 		cpu_type = M680X_CPU_TYPE_6809;
2159*9a0e4156SSadaf Ebrahimi 
2160*9a0e4156SSadaf Ebrahimi 	else if (handle->mode & CS_MODE_M680X_6301)
2161*9a0e4156SSadaf Ebrahimi 		cpu_type = M680X_CPU_TYPE_6301;
2162*9a0e4156SSadaf Ebrahimi 
2163*9a0e4156SSadaf Ebrahimi 	else if (handle->mode & CS_MODE_M680X_6309)
2164*9a0e4156SSadaf Ebrahimi 		cpu_type = M680X_CPU_TYPE_6309;
2165*9a0e4156SSadaf Ebrahimi 
2166*9a0e4156SSadaf Ebrahimi 	else if (handle->mode & CS_MODE_M680X_6811)
2167*9a0e4156SSadaf Ebrahimi 		cpu_type = M680X_CPU_TYPE_6811;
2168*9a0e4156SSadaf Ebrahimi 
2169*9a0e4156SSadaf Ebrahimi 	else if (handle->mode & CS_MODE_M680X_CPU12)
2170*9a0e4156SSadaf Ebrahimi 		cpu_type = M680X_CPU_TYPE_CPU12;
2171*9a0e4156SSadaf Ebrahimi 
2172*9a0e4156SSadaf Ebrahimi 	if (cpu_type != M680X_CPU_TYPE_INVALID &&
2173*9a0e4156SSadaf Ebrahimi 		m680x_setup_internals(info, cpu_type, (uint16_t)address, code,
2174*9a0e4156SSadaf Ebrahimi 			code_len))
2175*9a0e4156SSadaf Ebrahimi 		insn_size = m680x_disassemble(MI, info, (uint16_t)address);
2176*9a0e4156SSadaf Ebrahimi 
2177*9a0e4156SSadaf Ebrahimi 	if (insn_size == 0) {
2178*9a0e4156SSadaf Ebrahimi 		*size = 1;
2179*9a0e4156SSadaf Ebrahimi 		return false;
2180*9a0e4156SSadaf Ebrahimi 	}
2181*9a0e4156SSadaf Ebrahimi 
2182*9a0e4156SSadaf Ebrahimi 	// Make sure we always stay within range
2183*9a0e4156SSadaf Ebrahimi 	if (insn_size > code_len) {
2184*9a0e4156SSadaf Ebrahimi 		*size = (uint16_t)code_len;
2185*9a0e4156SSadaf Ebrahimi 		return false;
2186*9a0e4156SSadaf Ebrahimi 	}
2187*9a0e4156SSadaf Ebrahimi 	else
2188*9a0e4156SSadaf Ebrahimi 		*size = (uint16_t)insn_size;
2189*9a0e4156SSadaf Ebrahimi 
2190*9a0e4156SSadaf Ebrahimi 	return true;
2191*9a0e4156SSadaf Ebrahimi }
2192*9a0e4156SSadaf Ebrahimi 
M680X_disassembler_init(cs_struct * ud)2193*9a0e4156SSadaf Ebrahimi cs_err M680X_disassembler_init(cs_struct *ud)
2194*9a0e4156SSadaf Ebrahimi {
2195*9a0e4156SSadaf Ebrahimi 	if (M680X_REG_ENDING != ARR_SIZE(g_m6800_reg_byte_size)) {
2196*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Size mismatch in enum "
2197*9a0e4156SSadaf Ebrahimi 			"m680x_reg and g_m6800_reg_byte_size\n");
2198*9a0e4156SSadaf Ebrahimi 
2199*9a0e4156SSadaf Ebrahimi 		return CS_ERR_MODE;
2200*9a0e4156SSadaf Ebrahimi 	}
2201*9a0e4156SSadaf Ebrahimi 
2202*9a0e4156SSadaf Ebrahimi 	if (M680X_REG_ENDING != ARR_SIZE(g_m6801_reg_byte_size)) {
2203*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Size mismatch in enum "
2204*9a0e4156SSadaf Ebrahimi 			"m680x_reg and g_m6801_reg_byte_size\n");
2205*9a0e4156SSadaf Ebrahimi 
2206*9a0e4156SSadaf Ebrahimi 		return CS_ERR_MODE;
2207*9a0e4156SSadaf Ebrahimi 	}
2208*9a0e4156SSadaf Ebrahimi 
2209*9a0e4156SSadaf Ebrahimi 	if (M680X_REG_ENDING != ARR_SIZE(g_m6805_reg_byte_size)) {
2210*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Size mismatch in enum "
2211*9a0e4156SSadaf Ebrahimi 			"m680x_reg and g_m6805_reg_byte_size\n");
2212*9a0e4156SSadaf Ebrahimi 
2213*9a0e4156SSadaf Ebrahimi 		return CS_ERR_MODE;
2214*9a0e4156SSadaf Ebrahimi 	}
2215*9a0e4156SSadaf Ebrahimi 
2216*9a0e4156SSadaf Ebrahimi 	if (M680X_REG_ENDING != ARR_SIZE(g_m6808_reg_byte_size)) {
2217*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Size mismatch in enum "
2218*9a0e4156SSadaf Ebrahimi 			"m680x_reg and g_m6808_reg_byte_size\n");
2219*9a0e4156SSadaf Ebrahimi 
2220*9a0e4156SSadaf Ebrahimi 		return CS_ERR_MODE;
2221*9a0e4156SSadaf Ebrahimi 	}
2222*9a0e4156SSadaf Ebrahimi 
2223*9a0e4156SSadaf Ebrahimi 	if (M680X_REG_ENDING != ARR_SIZE(g_m6811_reg_byte_size)) {
2224*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Size mismatch in enum "
2225*9a0e4156SSadaf Ebrahimi 			"m680x_reg and g_m6811_reg_byte_size\n");
2226*9a0e4156SSadaf Ebrahimi 
2227*9a0e4156SSadaf Ebrahimi 		return CS_ERR_MODE;
2228*9a0e4156SSadaf Ebrahimi 	}
2229*9a0e4156SSadaf Ebrahimi 
2230*9a0e4156SSadaf Ebrahimi 	if (M680X_REG_ENDING != ARR_SIZE(g_cpu12_reg_byte_size)) {
2231*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Size mismatch in enum "
2232*9a0e4156SSadaf Ebrahimi 			"m680x_reg and g_cpu12_reg_byte_size\n");
2233*9a0e4156SSadaf Ebrahimi 
2234*9a0e4156SSadaf Ebrahimi 		return CS_ERR_MODE;
2235*9a0e4156SSadaf Ebrahimi 	}
2236*9a0e4156SSadaf Ebrahimi 
2237*9a0e4156SSadaf Ebrahimi 	if (M680X_REG_ENDING != ARR_SIZE(g_m6809_reg_byte_size)) {
2238*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Size mismatch in enum "
2239*9a0e4156SSadaf Ebrahimi 			"m680x_reg and g_m6809_reg_byte_size\n");
2240*9a0e4156SSadaf Ebrahimi 
2241*9a0e4156SSadaf Ebrahimi 		return CS_ERR_MODE;
2242*9a0e4156SSadaf Ebrahimi 	}
2243*9a0e4156SSadaf Ebrahimi 
2244*9a0e4156SSadaf Ebrahimi 	if (M680X_INS_ENDING != ARR_SIZE(g_insn_props)) {
2245*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Size mismatch in enum "
2246*9a0e4156SSadaf Ebrahimi 			"m680x_insn and g_insn_props\n");
2247*9a0e4156SSadaf Ebrahimi 
2248*9a0e4156SSadaf Ebrahimi 		return CS_ERR_MODE;
2249*9a0e4156SSadaf Ebrahimi 	}
2250*9a0e4156SSadaf Ebrahimi 
2251*9a0e4156SSadaf Ebrahimi 	if (M680X_CPU_TYPE_ENDING != ARR_SIZE(s_cpu_type)) {
2252*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Size mismatch in enum "
2253*9a0e4156SSadaf Ebrahimi 			"e_cpu_type and s_cpu_type\n");
2254*9a0e4156SSadaf Ebrahimi 
2255*9a0e4156SSadaf Ebrahimi 		return CS_ERR_MODE;
2256*9a0e4156SSadaf Ebrahimi 	}
2257*9a0e4156SSadaf Ebrahimi 
2258*9a0e4156SSadaf Ebrahimi 	if (M680X_CPU_TYPE_ENDING != ARR_SIZE(g_cpu_tables)) {
2259*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Size mismatch in enum "
2260*9a0e4156SSadaf Ebrahimi 			"e_cpu_type and g_cpu_tables\n");
2261*9a0e4156SSadaf Ebrahimi 
2262*9a0e4156SSadaf Ebrahimi 		return CS_ERR_MODE;
2263*9a0e4156SSadaf Ebrahimi 	}
2264*9a0e4156SSadaf Ebrahimi 
2265*9a0e4156SSadaf Ebrahimi 	if (HANDLER_ID_ENDING != ARR_SIZE(g_insn_handler)) {
2266*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Size mismatch in enum "
2267*9a0e4156SSadaf Ebrahimi 			"insn_hdlr_id and g_insn_handler\n");
2268*9a0e4156SSadaf Ebrahimi 
2269*9a0e4156SSadaf Ebrahimi 		return CS_ERR_MODE;
2270*9a0e4156SSadaf Ebrahimi 	}
2271*9a0e4156SSadaf Ebrahimi 
2272*9a0e4156SSadaf Ebrahimi 	if (ACCESS_MODE_ENDING !=  MATRIX_SIZE(g_access_mode_to_access)) {
2273*9a0e4156SSadaf Ebrahimi 		fprintf(stderr, "Internal error: Size mismatch in enum "
2274*9a0e4156SSadaf Ebrahimi 			"e_access_mode and g_access_mode_to_access\n");
2275*9a0e4156SSadaf Ebrahimi 
2276*9a0e4156SSadaf Ebrahimi 		return CS_ERR_MODE;
2277*9a0e4156SSadaf Ebrahimi 	}
2278*9a0e4156SSadaf Ebrahimi 
2279*9a0e4156SSadaf Ebrahimi 	return CS_ERR_OK;
2280*9a0e4156SSadaf Ebrahimi }
2281*9a0e4156SSadaf Ebrahimi 
2282*9a0e4156SSadaf Ebrahimi #ifndef CAPSTONE_DIET
M680X_reg_access(const cs_insn * insn,cs_regs regs_read,uint8_t * regs_read_count,cs_regs regs_write,uint8_t * regs_write_count)2283*9a0e4156SSadaf Ebrahimi void M680X_reg_access(const cs_insn *insn,
2284*9a0e4156SSadaf Ebrahimi 	cs_regs regs_read, uint8_t *regs_read_count,
2285*9a0e4156SSadaf Ebrahimi 	cs_regs regs_write, uint8_t *regs_write_count)
2286*9a0e4156SSadaf Ebrahimi {
2287*9a0e4156SSadaf Ebrahimi 	if (insn->detail == NULL) {
2288*9a0e4156SSadaf Ebrahimi 		*regs_read_count = 0;
2289*9a0e4156SSadaf Ebrahimi 		*regs_write_count = 0;
2290*9a0e4156SSadaf Ebrahimi 	}
2291*9a0e4156SSadaf Ebrahimi 	else {
2292*9a0e4156SSadaf Ebrahimi 		*regs_read_count = insn->detail->regs_read_count;
2293*9a0e4156SSadaf Ebrahimi 		*regs_write_count = insn->detail->regs_write_count;
2294*9a0e4156SSadaf Ebrahimi 
2295*9a0e4156SSadaf Ebrahimi 		memcpy(regs_read, insn->detail->regs_read,
2296*9a0e4156SSadaf Ebrahimi 			*regs_read_count * sizeof(insn->detail->regs_read[0]));
2297*9a0e4156SSadaf Ebrahimi 		memcpy(regs_write, insn->detail->regs_write,
2298*9a0e4156SSadaf Ebrahimi 			*regs_write_count *
2299*9a0e4156SSadaf Ebrahimi 			sizeof(insn->detail->regs_write[0]));
2300*9a0e4156SSadaf Ebrahimi 	}
2301*9a0e4156SSadaf Ebrahimi }
2302*9a0e4156SSadaf Ebrahimi #endif
2303*9a0e4156SSadaf Ebrahimi 
2304*9a0e4156SSadaf Ebrahimi #endif
2305*9a0e4156SSadaf Ebrahimi 
2306