1 /* ======================================================================== */
2 /* ========================= LICENSING & COPYRIGHT ======================== */
3 /* ======================================================================== */
4 /*
5  *                                  MUSASHI
6  *                                Version 3.4
7  *
8  * A portable Motorola M680x0 processor emulation engine.
9  * Copyright 1998-2001 Karl Stenerud.  All rights reserved.
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this software and associated documentation files (the "Software"), to deal
13  * in the Software without restriction, including without limitation the rights
14  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  * copies of the Software, and to permit persons to whom the Software is
16  * furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20 
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27  * THE SOFTWARE.
28  */
29 
30 /* The code bellow is based on MUSASHI but has been heavily modified for capstore by
31  * Daniel Collin <daniel@collin.com> 2015-2016 */
32 
33 /* ======================================================================== */
34 /* ================================ INCLUDES ============================== */
35 /* ======================================================================== */
36 
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
40 
41 #include "../../cs_priv.h"
42 #include "../../utils.h"
43 
44 #include "../../MCInst.h"
45 #include "../../MCInstrDesc.h"
46 #include "../../MCRegisterInfo.h"
47 #include "M68KInstPrinter.h"
48 #include "M68KDisassembler.h"
49 
50 #ifndef DECL_SPEC
51 #ifdef _MSC_VER
52 #define DECL_SPEC __cdecl
53 #else
54 #define DECL_SPEC
55 #endif	// _MSC_VER
56 #endif	// DECL_SPEC
57 
58 /* ======================================================================== */
59 /* ============================ GENERAL DEFINES =========================== */
60 /* ======================================================================== */
61 
62 /* unsigned int and int must be at least 32 bits wide */
63 #undef uint
64 #define uint unsigned int
65 
66 /* Bit Isolation Functions */
67 #define BIT_0(A)  ((A) & 0x00000001)
68 #define BIT_1(A)  ((A) & 0x00000002)
69 #define BIT_2(A)  ((A) & 0x00000004)
70 #define BIT_3(A)  ((A) & 0x00000008)
71 #define BIT_4(A)  ((A) & 0x00000010)
72 #define BIT_5(A)  ((A) & 0x00000020)
73 #define BIT_6(A)  ((A) & 0x00000040)
74 #define BIT_7(A)  ((A) & 0x00000080)
75 #define BIT_8(A)  ((A) & 0x00000100)
76 #define BIT_9(A)  ((A) & 0x00000200)
77 #define BIT_A(A)  ((A) & 0x00000400)
78 #define BIT_B(A)  ((A) & 0x00000800)
79 #define BIT_C(A)  ((A) & 0x00001000)
80 #define BIT_D(A)  ((A) & 0x00002000)
81 #define BIT_E(A)  ((A) & 0x00004000)
82 #define BIT_F(A)  ((A) & 0x00008000)
83 #define BIT_10(A) ((A) & 0x00010000)
84 #define BIT_11(A) ((A) & 0x00020000)
85 #define BIT_12(A) ((A) & 0x00040000)
86 #define BIT_13(A) ((A) & 0x00080000)
87 #define BIT_14(A) ((A) & 0x00100000)
88 #define BIT_15(A) ((A) & 0x00200000)
89 #define BIT_16(A) ((A) & 0x00400000)
90 #define BIT_17(A) ((A) & 0x00800000)
91 #define BIT_18(A) ((A) & 0x01000000)
92 #define BIT_19(A) ((A) & 0x02000000)
93 #define BIT_1A(A) ((A) & 0x04000000)
94 #define BIT_1B(A) ((A) & 0x08000000)
95 #define BIT_1C(A) ((A) & 0x10000000)
96 #define BIT_1D(A) ((A) & 0x20000000)
97 #define BIT_1E(A) ((A) & 0x40000000)
98 #define BIT_1F(A) ((A) & 0x80000000)
99 
100 /* These are the CPU types understood by this disassembler */
101 #define TYPE_68000 1
102 #define TYPE_68010 2
103 #define TYPE_68020 4
104 #define TYPE_68030 8
105 #define TYPE_68040 16
106 
107 #define M68000_ONLY		TYPE_68000
108 
109 #define M68010_ONLY		TYPE_68010
110 #define M68010_LESS		(TYPE_68000 | TYPE_68010)
111 #define M68010_PLUS		(TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68040)
112 
113 #define M68020_ONLY 	TYPE_68020
114 #define M68020_LESS 	(TYPE_68010 | TYPE_68020)
115 #define M68020_PLUS		(TYPE_68020 | TYPE_68030 | TYPE_68040)
116 
117 #define M68030_ONLY 	TYPE_68030
118 #define M68030_LESS 	(TYPE_68010 | TYPE_68020 | TYPE_68030)
119 #define M68030_PLUS		(TYPE_68030 | TYPE_68040)
120 
121 #define M68040_PLUS		TYPE_68040
122 
123 enum {
124 	M68K_CPU_TYPE_INVALID,
125 	M68K_CPU_TYPE_68000,
126 	M68K_CPU_TYPE_68010,
127 	M68K_CPU_TYPE_68EC020,
128 	M68K_CPU_TYPE_68020,
129 	M68K_CPU_TYPE_68030,	/* Supported by disassembler ONLY */
130 	M68K_CPU_TYPE_68040		/* Supported by disassembler ONLY */
131 };
132 
133 /* Extension word formats */
134 #define EXT_8BIT_DISPLACEMENT(A)          ((A)&0xff)
135 #define EXT_FULL(A)                       BIT_8(A)
136 #define EXT_EFFECTIVE_ZERO(A)             (((A)&0xe4) == 0xc4 || ((A)&0xe2) == 0xc0)
137 #define EXT_BASE_REGISTER_PRESENT(A)      (!BIT_7(A))
138 #define EXT_INDEX_REGISTER_PRESENT(A)     (!BIT_6(A))
139 #define EXT_INDEX_REGISTER(A)             (((A)>>12)&7)
140 #define EXT_INDEX_PRE_POST(A)             (EXT_INDEX_PRESENT(A) && (A)&3)
141 #define EXT_INDEX_PRE(A)                  (EXT_INDEX_PRESENT(A) && ((A)&7) < 4 && ((A)&7) != 0)
142 #define EXT_INDEX_POST(A)                 (EXT_INDEX_PRESENT(A) && ((A)&7) > 4)
143 #define EXT_INDEX_SCALE(A)                (((A)>>9)&3)
144 #define EXT_INDEX_LONG(A)                 BIT_B(A)
145 #define EXT_INDEX_AR(A)                   BIT_F(A)
146 #define EXT_BASE_DISPLACEMENT_PRESENT(A)  (((A)&0x30) > 0x10)
147 #define EXT_BASE_DISPLACEMENT_WORD(A)     (((A)&0x30) == 0x20)
148 #define EXT_BASE_DISPLACEMENT_LONG(A)     (((A)&0x30) == 0x30)
149 #define EXT_OUTER_DISPLACEMENT_PRESENT(A) (((A)&3) > 1 && ((A)&0x47) < 0x44)
150 #define EXT_OUTER_DISPLACEMENT_WORD(A)    (((A)&3) == 2 && ((A)&0x47) < 0x44)
151 #define EXT_OUTER_DISPLACEMENT_LONG(A)    (((A)&3) == 3 && ((A)&0x47) < 0x44)
152 
153 #define IS_BITSET(val,b) ((val) & (1 << (b)))
154 #define BITFIELD_MASK(sb,eb)  (((1 << ((sb) + 1))-1) & (~((1 << (eb))-1)))
155 #define BITFIELD(val,sb,eb) ((BITFIELD_MASK(sb,eb) & (val)) >> (eb))
156 
157 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
158 
m68k_read_disassembler_16(const m68k_info * info,const uint64_t addr)159 static unsigned int m68k_read_disassembler_16(const m68k_info *info, const uint64_t addr)
160 {
161 	const uint16_t v0 = info->code[addr + 0];
162 	const uint16_t v1 = info->code[addr + 1];
163 	return (v0 << 8) | v1;
164 }
165 
m68k_read_disassembler_32(const m68k_info * info,const uint64_t addr)166 static unsigned int m68k_read_disassembler_32(const m68k_info *info, const uint64_t addr)
167 {
168 	const uint32_t v0 = info->code[addr + 0];
169 	const uint32_t v1 = info->code[addr + 1];
170 	const uint32_t v2 = info->code[addr + 2];
171 	const uint32_t v3 = info->code[addr + 3];
172 	return (v0 << 24) | (v1 << 16) | (v2 << 8) | v3;
173 }
174 
m68k_read_disassembler_64(const m68k_info * info,const uint64_t addr)175 static uint64_t m68k_read_disassembler_64(const m68k_info *info, const uint64_t addr)
176 {
177 	const uint64_t v0 = info->code[addr + 0];
178 	const uint64_t v1 = info->code[addr + 1];
179 	const uint64_t v2 = info->code[addr + 2];
180 	const uint64_t v3 = info->code[addr + 3];
181 	const uint64_t v4 = info->code[addr + 4];
182 	const uint64_t v5 = info->code[addr + 5];
183 	const uint64_t v6 = info->code[addr + 6];
184 	const uint64_t v7 = info->code[addr + 7];
185 	return (v0 << 56) | (v1 << 48) | (v2 << 40) | (v3 << 32) | (v4 << 24) | (v5 << 16) | (v6 << 8) | v7;
186 }
187 
m68k_read_safe_16(const m68k_info * info,const uint64_t address)188 static unsigned int m68k_read_safe_16(const m68k_info *info, const uint64_t address)
189 {
190 	const uint64_t addr = (address - info->baseAddress) & info->address_mask;
191 	if (info->code_len < addr + 2) {
192 		return 0xaaaa;
193 	}
194 	return m68k_read_disassembler_16(info, addr);
195 }
196 
m68k_read_safe_32(const m68k_info * info,const uint64_t address)197 static unsigned int m68k_read_safe_32(const m68k_info *info, const uint64_t address)
198 {
199 	const uint64_t addr = (address - info->baseAddress) & info->address_mask;
200 	if (info->code_len < addr + 4) {
201 		return 0xaaaaaaaa;
202 	}
203 	return m68k_read_disassembler_32(info, addr);
204 }
205 
m68k_read_safe_64(const m68k_info * info,const uint64_t address)206 static uint64_t m68k_read_safe_64(const m68k_info *info, const uint64_t address)
207 {
208 	const uint64_t addr = (address - info->baseAddress) & info->address_mask;
209 	if (info->code_len < addr + 8) {
210 		return 0xaaaaaaaaaaaaaaaaLL;
211 	}
212 	return m68k_read_disassembler_64(info, addr);
213 }
214 
215 /* ======================================================================== */
216 /* =============================== PROTOTYPES ============================= */
217 /* ======================================================================== */
218 
219 /* make signed integers 100% portably */
220 static int make_int_8(int value);
221 static int make_int_16(int value);
222 
223 /* Stuff to build the opcode handler jump table */
224 static void build_opcode_table(void);
225 static int valid_ea(uint opcode, uint mask);
226 static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr);
227 static void d68000_invalid(m68k_info *info);
228 static int instruction_is_valid(m68k_info *info, const unsigned int word_check);
229 
230 /* used to build opcode handler jump table */
231 typedef struct {
232 	void (*opcode_handler)(m68k_info *info); /* handler function */
233 	uint mask;                    /* mask on opcode */
234 	uint match;                   /* what to match after masking */
235 	uint ea_mask;                 /* what ea modes are allowed */
236 	uint mask2;                   /* mask the 2nd word */
237 	uint match2;                  /* what to match after masking */
238 } opcode_struct;
239 
240 typedef struct {
241 	void (*instruction)(m68k_info *info);    /* handler function */
242 	uint word2_mask;              /* mask the 2nd word */
243 	uint word2_match;             /* what to match after masking */
244 } instruction_struct;
245 
246 /* ======================================================================== */
247 /* ================================= DATA ================================= */
248 /* ======================================================================== */
249 
250 /* Opcode handler jump table */
251 static instruction_struct g_instruction_table[0x10000];
252 
253 /* used by ops like asr, ror, addq, etc */
254 static uint g_3bit_qdata_table[8] = {8, 1, 2, 3, 4, 5, 6, 7};
255 
256 static uint g_5bit_data_table[32] = {
257 	32,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
258 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
259 };
260 
261 static m68k_insn s_branch_lut[] = {
262 	M68K_INS_INVALID, M68K_INS_INVALID, M68K_INS_BHI, M68K_INS_BLS,
263 	M68K_INS_BCC, M68K_INS_BCS, M68K_INS_BNE, M68K_INS_BEQ,
264 	M68K_INS_BVC, M68K_INS_BVS, M68K_INS_BPL, M68K_INS_BMI,
265 	M68K_INS_BGE, M68K_INS_BLT, M68K_INS_BGT, M68K_INS_BLE,
266 };
267 
268 static m68k_insn s_dbcc_lut[] = {
269 	M68K_INS_DBT, M68K_INS_DBF, M68K_INS_DBHI, M68K_INS_DBLS,
270 	M68K_INS_DBCC, M68K_INS_DBCS, M68K_INS_DBNE, M68K_INS_DBEQ,
271 	M68K_INS_DBVC, M68K_INS_DBVS, M68K_INS_DBPL, M68K_INS_DBMI,
272 	M68K_INS_DBGE, M68K_INS_DBLT, M68K_INS_DBGT, M68K_INS_DBLE,
273 };
274 
275 static m68k_insn s_scc_lut[] = {
276 	M68K_INS_ST, M68K_INS_SF, M68K_INS_SHI, M68K_INS_SLS,
277 	M68K_INS_SCC, M68K_INS_SCS, M68K_INS_SNE, M68K_INS_SEQ,
278 	M68K_INS_SVC, M68K_INS_SVS, M68K_INS_SPL, M68K_INS_SMI,
279 	M68K_INS_SGE, M68K_INS_SLT, M68K_INS_SGT, M68K_INS_SLE,
280 };
281 
282 static m68k_insn s_trap_lut[] = {
283 	M68K_INS_TRAPT, M68K_INS_TRAPF, M68K_INS_TRAPHI, M68K_INS_TRAPLS,
284 	M68K_INS_TRAPCC, M68K_INS_TRAPCS, M68K_INS_TRAPNE, M68K_INS_TRAPEQ,
285 	M68K_INS_TRAPVC, M68K_INS_TRAPVS, M68K_INS_TRAPPL, M68K_INS_TRAPMI,
286 	M68K_INS_TRAPGE, M68K_INS_TRAPLT, M68K_INS_TRAPGT, M68K_INS_TRAPLE,
287 };
288 
289 /* ======================================================================== */
290 /* =========================== UTILITY FUNCTIONS ========================== */
291 /* ======================================================================== */
292 
293 #define LIMIT_CPU_TYPES(info, ALLOWED_CPU_TYPES)	\
294 	do {						\
295 		if (!(info->type & ALLOWED_CPU_TYPES)) {	\
296 			d68000_invalid(info);		\
297 			return;				\
298 		}					\
299 	} while (0)
300 
peek_imm_8(const m68k_info * info)301 static unsigned int peek_imm_8(const m68k_info *info)  { return (m68k_read_safe_16((info), (info)->pc)&0xff); }
peek_imm_16(const m68k_info * info)302 static unsigned int peek_imm_16(const m68k_info *info) { return m68k_read_safe_16((info), (info)->pc); }
peek_imm_32(const m68k_info * info)303 static unsigned int peek_imm_32(const m68k_info *info) { return m68k_read_safe_32((info), (info)->pc); }
peek_imm_64(const m68k_info * info)304 static unsigned int peek_imm_64(const m68k_info *info) { return (unsigned int)m68k_read_safe_64((info), (info)->pc); }
305 
read_imm_8(m68k_info * info)306 static unsigned int read_imm_8(m68k_info *info)  { const unsigned int value = peek_imm_8(info);  (info)->pc+=2; return value; }
read_imm_16(m68k_info * info)307 static unsigned int read_imm_16(m68k_info *info) { const unsigned int value = peek_imm_16(info); (info)->pc+=2; return value; }
read_imm_32(m68k_info * info)308 static unsigned int read_imm_32(m68k_info *info) { const unsigned int value = peek_imm_32(info); (info)->pc+=4; return value; }
read_imm_64(m68k_info * info)309 static unsigned int read_imm_64(m68k_info *info) { const unsigned int value = peek_imm_64(info); (info)->pc+=8; return value; }
310 
311 /* Fake a split interface */
312 #define get_ea_mode_str_8(instruction) get_ea_mode_str(instruction, 0)
313 #define get_ea_mode_str_16(instruction) get_ea_mode_str(instruction, 1)
314 #define get_ea_mode_str_32(instruction) get_ea_mode_str(instruction, 2)
315 
316 #define get_imm_str_s8() get_imm_str_s(0)
317 #define get_imm_str_s16() get_imm_str_s(1)
318 #define get_imm_str_s32() get_imm_str_s(2)
319 
320 #define get_imm_str_u8() get_imm_str_u(0)
321 #define get_imm_str_u16() get_imm_str_u(1)
322 #define get_imm_str_u32() get_imm_str_u(2)
323 
324 
325 /* 100% portable signed int generators */
make_int_8(int value)326 static int make_int_8(int value)
327 {
328 	return (value & 0x80) ? value | ~0xff : value & 0xff;
329 }
330 
make_int_16(int value)331 static int make_int_16(int value)
332 {
333 	return (value & 0x8000) ? value | ~0xffff : value & 0xffff;
334 }
335 
get_with_index_address_mode(m68k_info * info,cs_m68k_op * op,uint instruction,uint size,bool is_pc)336 static void get_with_index_address_mode(m68k_info *info, cs_m68k_op* op, uint instruction, uint size, bool is_pc)
337 {
338 	uint extension = read_imm_16(info);
339 
340 	op->address_mode = M68K_AM_AREGI_INDEX_BASE_DISP;
341 
342 	if (EXT_FULL(extension)) {
343 		uint preindex;
344 		uint postindex;
345 
346 		op->mem.base_reg = M68K_REG_INVALID;
347 		op->mem.index_reg = M68K_REG_INVALID;
348 
349 		/* Not sure how to deal with this?
350 		   if (EXT_EFFECTIVE_ZERO(extension)) {
351 		   strcpy(mode, "0");
352 		   break;
353 		   }
354 		 */
355 
356 		op->mem.in_disp = EXT_BASE_DISPLACEMENT_PRESENT(extension) ? (EXT_BASE_DISPLACEMENT_LONG(extension) ? read_imm_32(info) : read_imm_16(info)) : 0;
357 		op->mem.out_disp = EXT_OUTER_DISPLACEMENT_PRESENT(extension) ? (EXT_OUTER_DISPLACEMENT_LONG(extension) ? read_imm_32(info) : read_imm_16(info)) : 0;
358 
359 		if (EXT_BASE_REGISTER_PRESENT(extension)) {
360 			if (is_pc) {
361 				op->mem.base_reg = M68K_REG_PC;
362 			} else {
363 				op->mem.base_reg = M68K_REG_A0 + (instruction & 7);
364 			}
365 		}
366 
367 		if (EXT_INDEX_REGISTER_PRESENT(extension)) {
368 			if (EXT_INDEX_AR(extension)) {
369 				op->mem.index_reg = M68K_REG_A0 + EXT_INDEX_REGISTER(extension);
370 			} else {
371 				op->mem.index_reg = M68K_REG_D0 + EXT_INDEX_REGISTER(extension);
372 			}
373 
374 			op->mem.index_size = EXT_INDEX_LONG(extension) ? 1 : 0;
375 
376 			if (EXT_INDEX_SCALE(extension)) {
377 				op->mem.scale = 1 << EXT_INDEX_SCALE(extension);
378 			}
379 		}
380 
381 		preindex = (extension & 7) > 0 && (extension & 7) < 4;
382 		postindex = (extension & 7) > 4;
383 
384 		if (preindex) {
385 			op->address_mode = is_pc ? M68K_AM_PC_MEMI_PRE_INDEX : M68K_AM_MEMI_PRE_INDEX;
386 		} else if (postindex) {
387 			op->address_mode = is_pc ? M68K_AM_PC_MEMI_POST_INDEX : M68K_AM_MEMI_POST_INDEX;
388 		}
389 
390 		return;
391 	}
392 
393 	op->mem.index_reg = (EXT_INDEX_AR(extension) ? M68K_REG_A0 : M68K_REG_D0) + EXT_INDEX_REGISTER(extension);
394 	op->mem.index_size = EXT_INDEX_LONG(extension) ? 1 : 0;
395 
396 	if (EXT_8BIT_DISPLACEMENT(extension) == 0) {
397 		if (is_pc) {
398 			op->mem.base_reg = M68K_REG_PC;
399 			op->address_mode = M68K_AM_PCI_INDEX_BASE_DISP;
400 		} else {
401 			op->mem.base_reg = M68K_REG_A0 + (instruction & 7);
402 		}
403 	} else {
404 		if (is_pc) {
405 			op->mem.base_reg = M68K_REG_PC;
406 			op->address_mode = M68K_AM_PCI_INDEX_8_BIT_DISP;
407 		} else {
408 			op->mem.base_reg = M68K_REG_A0 + (instruction & 7);
409 			op->address_mode = M68K_AM_AREGI_INDEX_8_BIT_DISP;
410 		}
411 
412 		op->mem.disp = (int8_t)(extension & 0xff);
413 	}
414 
415 	if (EXT_INDEX_SCALE(extension)) {
416 		op->mem.scale = 1 << EXT_INDEX_SCALE(extension);
417 	}
418 }
419 
420 /* Make string of effective address mode */
get_ea_mode_op(m68k_info * info,cs_m68k_op * op,uint instruction,uint size)421 void get_ea_mode_op(m68k_info *info, cs_m68k_op* op, uint instruction, uint size)
422 {
423 	// default to memory
424 
425 	op->type = M68K_OP_MEM;
426 
427 	switch (instruction & 0x3f) {
428 		case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
429 			/* data register direct */
430 			op->address_mode = M68K_AM_REG_DIRECT_DATA;
431 			op->reg = M68K_REG_D0 + (instruction & 7);
432 			op->type = M68K_OP_REG;
433 			break;
434 
435 		case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
436 			/* address register direct */
437 			op->address_mode = M68K_AM_REG_DIRECT_ADDR;
438 			op->reg = M68K_REG_A0 + (instruction & 7);
439 			op->type = M68K_OP_REG;
440 			break;
441 
442 		case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
443 			/* address register indirect */
444 			op->address_mode = M68K_AM_REGI_ADDR;
445 			op->reg = M68K_REG_A0 + (instruction & 7);
446 			break;
447 
448 		case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
449 			/* address register indirect with postincrement */
450 			op->address_mode = M68K_AM_REGI_ADDR_POST_INC;
451 			op->reg = M68K_REG_A0 + (instruction & 7);
452 			break;
453 
454 		case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
455 			/* address register indirect with predecrement */
456 			op->address_mode = M68K_AM_REGI_ADDR_PRE_DEC;
457 			op->reg = M68K_REG_A0 + (instruction & 7);
458 			break;
459 
460 		case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
461 			/* address register indirect with displacement*/
462 			op->address_mode = M68K_AM_REGI_ADDR_DISP;
463 			op->mem.base_reg = M68K_REG_A0 + (instruction & 7);
464 			op->mem.disp = (int16_t)read_imm_16(info);
465 			break;
466 
467 		case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
468 			/* address register indirect with index */
469 			get_with_index_address_mode(info, op, instruction, size, false);
470 			break;
471 
472 		case 0x38:
473 			/* absolute short address */
474 			op->address_mode = M68K_AM_ABSOLUTE_DATA_SHORT;
475 			op->imm = read_imm_16(info);
476 			break;
477 
478 		case 0x39:
479 			/* absolute long address */
480 			op->address_mode = M68K_AM_ABSOLUTE_DATA_LONG;
481 			op->imm = read_imm_32(info);
482 			break;
483 
484 		case 0x3a:
485 			/* program counter with displacement */
486 			op->address_mode = M68K_AM_PCI_DISP;
487 			op->mem.disp = (int16_t)read_imm_16(info);
488 			break;
489 
490 		case 0x3b:
491 			/* program counter with index */
492 			get_with_index_address_mode(info, op, instruction, size, true);
493 			break;
494 
495 		case 0x3c:
496 			op->address_mode = M68K_AM_IMMEDIATE;
497 			op->type = M68K_OP_IMM;
498 
499 			if (size == 1)
500 				op->imm = read_imm_8(info) & 0xff;
501 			else if (size == 2)
502 				op->imm = read_imm_16(info) & 0xffff;
503 			else if (size == 4)
504 				op->imm = read_imm_32(info);
505 			else
506 				op->imm = read_imm_64(info);
507 
508 			break;
509 
510 		default:
511 			break;
512 	}
513 }
514 
set_insn_group(m68k_info * info,m68k_group_type group)515 static void set_insn_group(m68k_info *info, m68k_group_type group)
516 {
517 	info->groups[info->groups_count++] = (uint8_t)group;
518 }
519 
build_init_op(m68k_info * info,int opcode,int count,int size)520 static cs_m68k* build_init_op(m68k_info *info, int opcode, int count, int size)
521 {
522 	cs_m68k* ext;
523 
524 	MCInst_setOpcode(info->inst, opcode);
525 
526 	ext = &info->extension;
527 
528 	ext->op_count = (uint8_t)count;
529 	ext->op_size.type = M68K_SIZE_TYPE_CPU;
530 	ext->op_size.cpu_size = size;
531 
532 	return ext;
533 }
534 
build_re_gen_1(m68k_info * info,bool isDreg,int opcode,uint8_t size)535 static void build_re_gen_1(m68k_info *info, bool isDreg, int opcode, uint8_t size)
536 {
537 	cs_m68k_op* op0;
538 	cs_m68k_op* op1;
539 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
540 
541 	op0 = &ext->operands[0];
542 	op1 = &ext->operands[1];
543 
544 	if (isDreg) {
545 		op0->address_mode = M68K_AM_REG_DIRECT_DATA;
546 		op0->reg = M68K_REG_D0 + ((info->ir >> 9 ) & 7);
547 	} else {
548 		op0->address_mode = M68K_AM_REG_DIRECT_ADDR;
549 		op0->reg = M68K_REG_A0 + ((info->ir >> 9 ) & 7);
550 	}
551 
552 	get_ea_mode_op(info, op1, info->ir, size);
553 }
554 
build_re_1(m68k_info * info,int opcode,uint8_t size)555 static void build_re_1(m68k_info *info, int opcode, uint8_t size)
556 {
557 	build_re_gen_1(info, true, opcode, size);
558 }
559 
build_er_gen_1(m68k_info * info,bool isDreg,int opcode,uint8_t size)560 static void build_er_gen_1(m68k_info *info, bool isDreg, int opcode, uint8_t size)
561 {
562 	cs_m68k_op* op0;
563 	cs_m68k_op* op1;
564 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
565 
566 	op0 = &ext->operands[0];
567 	op1 = &ext->operands[1];
568 
569 	get_ea_mode_op(info, op0, info->ir, size);
570 
571 	if (isDreg) {
572 		op1->address_mode = M68K_AM_REG_DIRECT_DATA;
573 		op1->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
574 	} else {
575 		op1->address_mode = M68K_AM_REG_DIRECT_ADDR;
576 		op1->reg = M68K_REG_A0 + ((info->ir >> 9) & 7);
577 	}
578 }
579 
build_rr(m68k_info * info,int opcode,uint8_t size,int imm)580 static void build_rr(m68k_info *info, int opcode, uint8_t size, int imm)
581 {
582 	cs_m68k_op* op0;
583 	cs_m68k_op* op1;
584 	cs_m68k_op* op2;
585 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
586 
587 	op0 = &ext->operands[0];
588 	op1 = &ext->operands[1];
589 	op2 = &ext->operands[2];
590 
591 	op0->address_mode = M68K_AM_REG_DIRECT_DATA;
592 	op0->reg = M68K_REG_D0 + (info->ir & 7);
593 
594 	op1->address_mode = M68K_AM_REG_DIRECT_DATA;
595 	op1->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
596 
597 	if (imm > 0) {
598 		ext->op_count = 3;
599 		op2->type = M68K_OP_IMM;
600 		op2->address_mode = M68K_AM_IMMEDIATE;
601 		op2->imm = imm;
602 	}
603 }
604 
build_r(m68k_info * info,int opcode,uint8_t size)605 static void build_r(m68k_info *info, int opcode, uint8_t size)
606 {
607 	cs_m68k_op* op0;
608 	cs_m68k_op* op1;
609 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
610 
611 	op0 = &ext->operands[0];
612 	op1 = &ext->operands[1];
613 
614 	op0->address_mode = M68K_AM_REG_DIRECT_DATA;
615 	op0->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
616 
617 	op1->address_mode = M68K_AM_REG_DIRECT_DATA;
618 	op1->reg = M68K_REG_D0 + (info->ir & 7);
619 }
620 
build_imm_ea(m68k_info * info,int opcode,uint8_t size,int imm)621 static void build_imm_ea(m68k_info *info, int opcode, uint8_t size, int imm)
622 {
623 	cs_m68k_op* op0;
624 	cs_m68k_op* op1;
625 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
626 
627 	op0 = &ext->operands[0];
628 	op1 = &ext->operands[1];
629 
630 	op0->type = M68K_OP_IMM;
631 	op0->address_mode = M68K_AM_IMMEDIATE;
632 	op0->imm = imm;
633 
634 	get_ea_mode_op(info, op1, info->ir, size);
635 }
636 
build_3bit_d(m68k_info * info,int opcode,int size)637 static void build_3bit_d(m68k_info *info, int opcode, int size)
638 {
639 	cs_m68k_op* op0;
640 	cs_m68k_op* op1;
641 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
642 
643 	op0 = &ext->operands[0];
644 	op1 = &ext->operands[1];
645 
646 	op0->type = M68K_OP_IMM;
647 	op0->address_mode = M68K_AM_IMMEDIATE;
648 	op0->imm = g_3bit_qdata_table[(info->ir >> 9) & 7];
649 
650 	op1->address_mode = M68K_AM_REG_DIRECT_DATA;
651 	op1->reg = M68K_REG_D0 + (info->ir & 7);
652 }
653 
build_3bit_ea(m68k_info * info,int opcode,int size)654 static void build_3bit_ea(m68k_info *info, int opcode, int size)
655 {
656 	cs_m68k_op* op0;
657 	cs_m68k_op* op1;
658 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
659 
660 	op0 = &ext->operands[0];
661 	op1 = &ext->operands[1];
662 
663 	op0->type = M68K_OP_IMM;
664 	op0->address_mode = M68K_AM_IMMEDIATE;
665 	op0->imm = g_3bit_qdata_table[(info->ir >> 9) & 7];
666 
667 	get_ea_mode_op(info, op1, info->ir, size);
668 }
669 
build_mm(m68k_info * info,int opcode,uint8_t size,int imm)670 static void build_mm(m68k_info *info, int opcode, uint8_t size, int imm)
671 {
672 	cs_m68k_op* op0;
673 	cs_m68k_op* op1;
674 	cs_m68k_op* op2;
675 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
676 
677 	op0 = &ext->operands[0];
678 	op1 = &ext->operands[1];
679 	op2 = &ext->operands[2];
680 
681 	op0->address_mode = M68K_AM_REGI_ADDR_PRE_DEC;
682 	op0->reg = M68K_REG_A0 + (info->ir & 7);
683 
684 	op1->address_mode = M68K_AM_REGI_ADDR_PRE_DEC;
685 	op1->reg = M68K_REG_A0 + ((info->ir >> 9) & 7);
686 
687 	if (imm > 0) {
688 		ext->op_count = 3;
689 		op2->type = M68K_OP_IMM;
690 		op2->address_mode = M68K_AM_IMMEDIATE;
691 		op2->imm = imm;
692 	}
693 }
694 
build_ea(m68k_info * info,int opcode,uint8_t size)695 static void build_ea(m68k_info *info, int opcode, uint8_t size)
696 {
697 	cs_m68k* ext = build_init_op(info, opcode, 1, size);
698 	get_ea_mode_op(info, &ext->operands[0], info->ir, size);
699 }
700 
build_ea_a(m68k_info * info,int opcode,uint8_t size)701 static void build_ea_a(m68k_info *info, int opcode, uint8_t size)
702 {
703 	cs_m68k_op* op0;
704 	cs_m68k_op* op1;
705 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
706 
707 	op0 = &ext->operands[0];
708 	op1 = &ext->operands[1];
709 
710 	get_ea_mode_op(info, op0, info->ir, size);
711 
712 	op1->address_mode = M68K_AM_REG_DIRECT_ADDR;
713 	op1->reg = M68K_REG_A0 + ((info->ir >> 9) & 7);
714 }
715 
build_ea_ea(m68k_info * info,int opcode,int size)716 static void build_ea_ea(m68k_info *info, int opcode, int size)
717 {
718 	cs_m68k_op* op0;
719 	cs_m68k_op* op1;
720 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
721 
722 	op0 = &ext->operands[0];
723 	op1 = &ext->operands[1];
724 
725 	get_ea_mode_op(info, op0, info->ir, size);
726 	get_ea_mode_op(info, op1, (((info->ir>>9) & 7) | ((info->ir>>3) & 0x38)), size);
727 }
728 
build_pi_pi(m68k_info * info,int opcode,int size)729 static void build_pi_pi(m68k_info *info, int opcode, int size)
730 {
731 	cs_m68k_op* op0;
732 	cs_m68k_op* op1;
733 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
734 
735 	op0 = &ext->operands[0];
736 	op1 = &ext->operands[1];
737 
738 	op0->address_mode = M68K_AM_REGI_ADDR_POST_INC;
739 	op0->reg = M68K_REG_A0 + (info->ir & 7);
740 
741 	op1->address_mode = M68K_AM_REGI_ADDR_POST_INC;
742 	op1->reg = M68K_REG_A0 + ((info->ir >> 9) & 7);
743 }
744 
build_imm_special_reg(m68k_info * info,int opcode,int imm,int size,m68k_reg reg)745 static void build_imm_special_reg(m68k_info *info, int opcode, int imm, int size, m68k_reg reg)
746 {
747 	cs_m68k_op* op0;
748 	cs_m68k_op* op1;
749 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
750 
751 	op0 = &ext->operands[0];
752 	op1 = &ext->operands[1];
753 
754 	op0->type = M68K_OP_IMM;
755 	op0->address_mode = M68K_AM_IMMEDIATE;
756 	op0->imm = imm;
757 
758 	op1->address_mode = M68K_AM_NONE;
759 	op1->reg = reg;
760 }
761 
build_relative_branch(m68k_info * info,int opcode,int size,int displacement)762 static void build_relative_branch(m68k_info *info, int opcode, int size, int displacement)
763 {
764 	cs_m68k_op* op;
765 	cs_m68k* ext = build_init_op(info, opcode, 1, size);
766 
767 	op = &ext->operands[0];
768 
769 	op->type = M68K_OP_BR_DISP;
770 	op->address_mode = M68K_AM_BRANCH_DISPLACEMENT;
771 	op->br_disp.disp = displacement;
772 	op->br_disp.disp_size = size;
773 
774 	set_insn_group(info, M68K_GRP_JUMP);
775 	set_insn_group(info, M68K_GRP_BRANCH_RELATIVE);
776 }
777 
build_absolute_jump_with_immediate(m68k_info * info,int opcode,int size,int immediate)778 static void build_absolute_jump_with_immediate(m68k_info *info, int opcode, int size, int immediate)
779 {
780 	cs_m68k_op* op;
781 	cs_m68k* ext = build_init_op(info, opcode, 1, size);
782 
783 	op = &ext->operands[0];
784 
785 	op->type = M68K_OP_IMM;
786 	op->address_mode = M68K_AM_IMMEDIATE;
787 	op->imm = immediate;
788 
789 	set_insn_group(info, M68K_GRP_JUMP);
790 }
791 
build_bcc(m68k_info * info,int size,int displacement)792 static void build_bcc(m68k_info *info, int size, int displacement)
793 {
794 	build_relative_branch(info, s_branch_lut[(info->ir >> 8) & 0xf], size, displacement);
795 }
796 
build_trap(m68k_info * info,int size,int immediate)797 static void build_trap(m68k_info *info, int size, int immediate)
798 {
799 	build_absolute_jump_with_immediate(info, s_trap_lut[(info->ir >> 8) & 0xf], size, immediate);
800 }
801 
build_dbxx(m68k_info * info,int opcode,int size,int displacement)802 static void build_dbxx(m68k_info *info, int opcode, int size, int displacement)
803 {
804 	cs_m68k_op* op0;
805 	cs_m68k_op* op1;
806 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
807 
808 	op0 = &ext->operands[0];
809 	op1 = &ext->operands[1];
810 
811 	op0->address_mode = M68K_AM_REG_DIRECT_DATA;
812 	op0->reg = M68K_REG_D0 + (info->ir & 7);
813 
814 	op1->type = M68K_OP_BR_DISP;
815 	op1->address_mode = M68K_AM_BRANCH_DISPLACEMENT;
816 	op1->br_disp.disp = displacement;
817 	op1->br_disp.disp_size = M68K_OP_BR_DISP_SIZE_LONG;
818 
819 	set_insn_group(info, M68K_GRP_JUMP);
820 	set_insn_group(info, M68K_GRP_BRANCH_RELATIVE);
821 }
822 
build_dbcc(m68k_info * info,int size,int displacement)823 static void build_dbcc(m68k_info *info, int size, int displacement)
824 {
825 	build_dbxx(info, s_dbcc_lut[(info->ir >> 8) & 0xf], size, displacement);
826 }
827 
build_d_d_ea(m68k_info * info,int opcode,int size)828 static void build_d_d_ea(m68k_info *info, int opcode, int size)
829 {
830 	cs_m68k_op* op0;
831 	cs_m68k_op* op1;
832 	cs_m68k_op* op2;
833 	uint extension = read_imm_16(info);
834 	cs_m68k* ext = build_init_op(info, opcode, 3, size);
835 
836 	op0 = &ext->operands[0];
837 	op1 = &ext->operands[1];
838 	op2 = &ext->operands[2];
839 
840 	op0->address_mode = M68K_AM_REG_DIRECT_DATA;
841 	op0->reg = M68K_REG_D0 + (extension & 7);
842 
843 	op1->address_mode = M68K_AM_REG_DIRECT_DATA;
844 	op1->reg = M68K_REG_D0 + ((extension >> 6) & 7);
845 
846 	get_ea_mode_op(info, op2, info->ir, size);
847 }
848 
build_bitfield_ins(m68k_info * info,int opcode,int has_d_arg)849 static void build_bitfield_ins(m68k_info *info, int opcode, int has_d_arg)
850 {
851 	uint8_t offset;
852 	uint8_t width;
853 	cs_m68k_op* op_ea;
854 	cs_m68k_op* op1;
855 	cs_m68k* ext = build_init_op(info, opcode, 1, 0);
856 	uint extension = read_imm_16(info);
857 
858 	op_ea = &ext->operands[0];
859 	op1 = &ext->operands[1];
860 
861 	if (BIT_B(extension))
862 		offset = (extension >> 6) & 7;
863 	else
864 		offset = (extension >> 6) & 31;
865 
866 	if (BIT_5(extension))
867 		width = extension & 7;
868 	else
869 		width = (uint8_t)g_5bit_data_table[extension & 31];
870 
871 	if (has_d_arg) {
872 		ext->op_count = 2;
873 		op1->address_mode = M68K_AM_REG_DIRECT_DATA;
874 		op1->reg = M68K_REG_D0 + ((extension >> 12) & 7);
875 	}
876 
877 	get_ea_mode_op(info, op_ea, info->ir, 1);
878 
879 	op_ea->mem.bitfield = 1;
880 	op_ea->mem.width = width;
881 	op_ea->mem.offset = offset;
882 }
883 
build_d(m68k_info * info,int opcode,int size)884 static void build_d(m68k_info *info, int opcode, int size)
885 {
886 	cs_m68k* ext = build_init_op(info, opcode, 1, size);
887 	cs_m68k_op* op;
888 
889 	op = &ext->operands[0];
890 
891 	op->address_mode = M68K_AM_REG_DIRECT_DATA;
892 	op->reg = M68K_REG_D0 + (info->ir & 7);
893 }
894 
reverse_bits(uint v)895 static uint16_t reverse_bits(uint v)
896 {
897 	uint r = v; // r will be reversed bits of v; first get LSB of v
898 	uint s = 16 - 1; // extra shift needed at end
899 
900 	for (v >>= 1; v; v >>= 1) {
901 		r <<= 1;
902 		r |= v & 1;
903 		s--;
904 	}
905 
906 	return r <<= s; // shift when v's highest bits are zero
907 }
908 
reverse_bits_8(uint v)909 static uint8_t reverse_bits_8(uint v)
910 {
911 	uint r = v; // r will be reversed bits of v; first get LSB of v
912 	uint s = 8 - 1; // extra shift needed at end
913 
914 	for (v >>= 1; v; v >>= 1) {
915 		r <<= 1;
916 		r |= v & 1;
917 		s--;
918 	}
919 
920 	return r <<= s; // shift when v's highest bits are zero
921 }
922 
923 
build_movem_re(m68k_info * info,int opcode,int size)924 static void build_movem_re(m68k_info *info, int opcode, int size)
925 {
926 	cs_m68k_op* op0;
927 	cs_m68k_op* op1;
928 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
929 
930 	op0 = &ext->operands[0];
931 	op1 = &ext->operands[1];
932 
933 	op0->type = M68K_OP_REG_BITS;
934 	op0->register_bits = read_imm_16(info);
935 
936 	get_ea_mode_op(info, op1, info->ir, size);
937 
938 	if (op1->address_mode == M68K_AM_REGI_ADDR_PRE_DEC)
939 		op0->register_bits = reverse_bits(op0->register_bits);
940 }
941 
build_movem_er(m68k_info * info,int opcode,int size)942 static void build_movem_er(m68k_info *info, int opcode, int size)
943 {
944 	cs_m68k_op* op0;
945 	cs_m68k_op* op1;
946 	cs_m68k* ext = build_init_op(info, opcode, 2, size);
947 
948 	op0 = &ext->operands[0];
949 	op1 = &ext->operands[1];
950 
951 	op1->type = M68K_OP_REG_BITS;
952 	op1->register_bits = read_imm_16(info);
953 
954 	get_ea_mode_op(info, op0, info->ir, size);
955 }
956 
build_imm(m68k_info * info,int opcode,int data)957 static void build_imm(m68k_info *info, int opcode, int data)
958 {
959 	cs_m68k_op* op;
960 	cs_m68k* ext = build_init_op(info, opcode, 1, 0);
961 
962 	MCInst_setOpcode(info->inst, opcode);
963 
964 	op = &ext->operands[0];
965 
966 	op->type = M68K_OP_IMM;
967 	op->address_mode = M68K_AM_IMMEDIATE;
968 	op->imm = data;
969 }
970 
build_illegal(m68k_info * info,int data)971 static void build_illegal(m68k_info *info, int data)
972 {
973 	build_imm(info, M68K_INS_ILLEGAL, data);
974 }
975 
build_invalid(m68k_info * info,int data)976 static void build_invalid(m68k_info *info, int data)
977 {
978 	build_imm(info, M68K_INS_INVALID, data);
979 }
980 
build_cas2(m68k_info * info,int size)981 static void build_cas2(m68k_info *info, int size)
982 {
983 	uint word3;
984 	uint extension;
985 	cs_m68k_op* op0;
986 	cs_m68k_op* op1;
987 	cs_m68k_op* op2;
988 	cs_m68k* ext = build_init_op(info, M68K_INS_CAS2, 3, size);
989 	int reg_0, reg_1;
990 
991 	/* cas2 is the only 3 words instruction, word2 and word3 have the same motif bits to check */
992 	word3 = peek_imm_32(info) & 0xffff;
993 	if (!instruction_is_valid(info, word3))
994 		return;
995 
996 	op0 = &ext->operands[0];
997 	op1 = &ext->operands[1];
998 	op2 = &ext->operands[2];
999 
1000 	extension = read_imm_32(info);
1001 
1002 	op0->address_mode = M68K_AM_NONE;
1003 	op0->type = M68K_OP_REG_PAIR;
1004 	op0->reg_pair.reg_0 = (extension >> 16) & 7;
1005 	op0->reg_pair.reg_1 = extension & 7;
1006 
1007 	op1->address_mode = M68K_AM_NONE;
1008 	op1->type = M68K_OP_REG_PAIR;
1009 	op1->reg_pair.reg_0 = (extension >> 22) & 7;
1010 	op1->reg_pair.reg_1 = (extension >> 6) & 7;
1011 
1012 	reg_0 = (extension >> 28) & 7;
1013 	reg_1 = (extension >> 12) & 7;
1014 
1015 	op2->address_mode = M68K_AM_NONE;
1016 	op2->type = M68K_OP_REG_PAIR;
1017 	op2->reg_pair.reg_0 = reg_0 + (BIT_1F(extension) ? 8 : 0);
1018 	op2->reg_pair.reg_1 = reg_1 + (BIT_F(extension) ? 8 : 0);
1019 }
1020 
build_chk2_cmp2(m68k_info * info,int size)1021 static void build_chk2_cmp2(m68k_info *info, int size)
1022 {
1023 	cs_m68k_op* op0;
1024 	cs_m68k_op* op1;
1025 	cs_m68k* ext = build_init_op(info, M68K_INS_CHK2, 2, size);
1026 
1027 	uint extension = read_imm_16(info);
1028 
1029 	if (BIT_B(extension))
1030 		MCInst_setOpcode(info->inst, M68K_INS_CHK2);
1031 	else
1032 		MCInst_setOpcode(info->inst, M68K_INS_CMP2);
1033 
1034 	op0 = &ext->operands[0];
1035 	op1 = &ext->operands[1];
1036 
1037 	get_ea_mode_op(info, op0, info->ir, size);
1038 
1039 	op1->address_mode = M68K_AM_NONE;
1040 	op1->type = M68K_OP_REG;
1041 	op1->reg = (BIT_F(extension) ? M68K_REG_A0 : M68K_REG_D0) + ((extension >> 12) & 7);
1042 }
1043 
build_move16(m68k_info * info,int data[2],int modes[2])1044 static void build_move16(m68k_info *info, int data[2], int modes[2])
1045 {
1046 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVE16, 2, 0);
1047 	int i;
1048 
1049 	for (i = 0; i < 2; ++i) {
1050 		cs_m68k_op* op = &ext->operands[i];
1051 		const int d = data[i];
1052 		const int m = modes[i];
1053 
1054 		op->type = M68K_OP_MEM;
1055 
1056 		if (m == M68K_AM_REGI_ADDR_POST_INC || m == M68K_AM_REG_DIRECT_ADDR) {
1057 			op->address_mode = m;
1058 			op->reg = M68K_REG_A0 + d;
1059 		} else {
1060 			op->address_mode = m;
1061 			op->imm = d;
1062 		}
1063 	}
1064 }
1065 
build_link(m68k_info * info,int disp,int size)1066 static void build_link(m68k_info *info, int disp, int size)
1067 {
1068 	cs_m68k_op* op0;
1069 	cs_m68k_op* op1;
1070 	cs_m68k* ext = build_init_op(info, M68K_INS_LINK, 2, size);
1071 
1072 	op0 = &ext->operands[0];
1073 	op1 = &ext->operands[1];
1074 
1075 	op0->address_mode = M68K_AM_NONE;
1076 	op0->reg = M68K_REG_A0 + (info->ir & 7);
1077 
1078 	op1->address_mode = M68K_AM_IMMEDIATE;
1079 	op1->type = M68K_OP_IMM;
1080 	op1->imm = disp;
1081 }
1082 
build_cpush_cinv(m68k_info * info,int op_offset)1083 static void build_cpush_cinv(m68k_info *info, int op_offset)
1084 {
1085 	cs_m68k_op* op0;
1086 	cs_m68k_op* op1;
1087 	cs_m68k* ext = build_init_op(info, M68K_INS_INVALID, 2, 0);
1088 
1089 	switch ((info->ir >> 3) & 3) { // scope
1090 		// Invalid
1091 		case 0:
1092 			d68000_invalid(info);
1093 			return;
1094 			// Line
1095 		case 1:
1096 			MCInst_setOpcode(info->inst, op_offset + 0);
1097 			break;
1098 			// Page
1099 		case 2:
1100 			MCInst_setOpcode(info->inst, op_offset + 1);
1101 			break;
1102 			// All
1103 		case 3:
1104 			ext->op_count = 1;
1105 			MCInst_setOpcode(info->inst, op_offset + 2);
1106 			break;
1107 	}
1108 
1109 	op0 = &ext->operands[0];
1110 	op1 = &ext->operands[1];
1111 
1112 	op0->address_mode = M68K_AM_IMMEDIATE;
1113 	op0->type = M68K_OP_IMM;
1114 	op0->imm = (info->ir >> 6) & 3;
1115 
1116 	op1->type = M68K_OP_MEM;
1117 	op1->address_mode = M68K_AM_REG_DIRECT_ADDR;
1118 	op1->imm = M68K_REG_A0 + (info->ir & 7);
1119 }
1120 
build_movep_re(m68k_info * info,int size)1121 static void build_movep_re(m68k_info *info, int size)
1122 {
1123 	cs_m68k_op* op0;
1124 	cs_m68k_op* op1;
1125 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVEP, 2, size);
1126 
1127 	op0 = &ext->operands[0];
1128 	op1 = &ext->operands[1];
1129 
1130 	op0->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
1131 
1132 	op1->address_mode = M68K_AM_REGI_ADDR_DISP;
1133 	op1->type = M68K_OP_MEM;
1134 	op1->mem.base_reg = M68K_REG_A0 + (info->ir & 7);
1135 	op1->mem.disp = (int16_t)read_imm_16(info);
1136 }
1137 
build_movep_er(m68k_info * info,int size)1138 static void build_movep_er(m68k_info *info, int size)
1139 {
1140 	cs_m68k_op* op0;
1141 	cs_m68k_op* op1;
1142 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVEP, 2, size);
1143 
1144 	op0 = &ext->operands[0];
1145 	op1 = &ext->operands[1];
1146 
1147 	op0->address_mode = M68K_AM_REGI_ADDR_DISP;
1148 	op0->type = M68K_OP_MEM;
1149 	op0->mem.base_reg = M68K_REG_A0 + (info->ir & 7);
1150 	op0->mem.disp = (int16_t)read_imm_16(info);
1151 
1152 	op1->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
1153 }
1154 
build_moves(m68k_info * info,int size)1155 static void build_moves(m68k_info *info, int size)
1156 {
1157 	cs_m68k_op* op0;
1158 	cs_m68k_op* op1;
1159 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVES, 2, size);
1160 	uint extension = read_imm_16(info);
1161 
1162 	op0 = &ext->operands[0];
1163 	op1 = &ext->operands[1];
1164 
1165 	if (BIT_B(extension)) {
1166 		op0->reg = (BIT_F(extension) ? M68K_REG_A0 : M68K_REG_D0) + ((extension >> 12) & 7);
1167 		get_ea_mode_op(info, op1, info->ir, size);
1168 	} else {
1169 		get_ea_mode_op(info, op0, info->ir, size);
1170 		op1->reg = (BIT_F(extension) ? M68K_REG_A0 : M68K_REG_D0) + ((extension >> 12) & 7);
1171 	}
1172 }
1173 
build_er_1(m68k_info * info,int opcode,uint8_t size)1174 static void build_er_1(m68k_info *info, int opcode, uint8_t size)
1175 {
1176 	build_er_gen_1(info, true, opcode, size);
1177 }
1178 
1179 /* ======================================================================== */
1180 /* ========================= INSTRUCTION HANDLERS ========================= */
1181 /* ======================================================================== */
1182 /* Instruction handler function names follow this convention:
1183  *
1184  * d68000_NAME_EXTENSIONS(void)
1185  * where NAME is the name of the opcode it handles and EXTENSIONS are any
1186  * extensions for special instances of that opcode.
1187  *
1188  * Examples:
1189  *   d68000_add_er_8(): add opcode, from effective address to register,
1190  *                      size = byte
1191  *
1192  *   d68000_asr_s_8(): arithmetic shift right, static count, size = byte
1193  *
1194  *
1195  * Common extensions:
1196  * 8   : size = byte
1197  * 16  : size = word
1198  * 32  : size = long
1199  * rr  : register to register
1200  * mm  : memory to memory
1201  * r   : register
1202  * s   : static
1203  * er  : effective address -> register
1204  * re  : register -> effective address
1205  * ea  : using effective address mode of operation
1206  * d   : data register direct
1207  * a   : address register direct
1208  * ai  : address register indirect
1209  * pi  : address register indirect with postincrement
1210  * pd  : address register indirect with predecrement
1211  * di  : address register indirect with displacement
1212  * ix  : address register indirect with index
1213  * aw  : absolute word
1214  * al  : absolute long
1215  */
1216 
1217 
d68000_invalid(m68k_info * info)1218 static void d68000_invalid(m68k_info *info)
1219 {
1220 	build_invalid(info, info->ir);
1221 }
1222 
d68000_illegal(m68k_info * info)1223 static void d68000_illegal(m68k_info *info)
1224 {
1225 	build_illegal(info, info->ir);
1226 }
1227 
d68000_1010(m68k_info * info)1228 static void d68000_1010(m68k_info *info)
1229 {
1230 	build_invalid(info, info->ir);
1231 }
1232 
d68000_1111(m68k_info * info)1233 static void d68000_1111(m68k_info *info)
1234 {
1235 	build_invalid(info, info->ir);
1236 }
1237 
d68000_abcd_rr(m68k_info * info)1238 static void d68000_abcd_rr(m68k_info *info)
1239 {
1240 	build_rr(info, M68K_INS_ABCD, 1, 0);
1241 }
1242 
d68000_abcd_mm(m68k_info * info)1243 static void d68000_abcd_mm(m68k_info *info)
1244 {
1245 	build_mm(info, M68K_INS_ABCD, 1, 0);
1246 }
1247 
d68000_add_er_8(m68k_info * info)1248 static void d68000_add_er_8(m68k_info *info)
1249 {
1250 	build_er_1(info, M68K_INS_ADD, 1);
1251 }
1252 
d68000_add_er_16(m68k_info * info)1253 static void d68000_add_er_16(m68k_info *info)
1254 {
1255 	build_er_1(info, M68K_INS_ADD, 2);
1256 }
1257 
d68000_add_er_32(m68k_info * info)1258 static void d68000_add_er_32(m68k_info *info)
1259 {
1260 	build_er_1(info, M68K_INS_ADD, 4);
1261 }
1262 
d68000_add_re_8(m68k_info * info)1263 static void d68000_add_re_8(m68k_info *info)
1264 {
1265 	build_re_1(info, M68K_INS_ADD, 1);
1266 }
1267 
d68000_add_re_16(m68k_info * info)1268 static void d68000_add_re_16(m68k_info *info)
1269 {
1270 	build_re_1(info, M68K_INS_ADD, 2);
1271 }
1272 
d68000_add_re_32(m68k_info * info)1273 static void d68000_add_re_32(m68k_info *info)
1274 {
1275 	build_re_1(info, M68K_INS_ADD, 4);
1276 }
1277 
d68000_adda_16(m68k_info * info)1278 static void d68000_adda_16(m68k_info *info)
1279 {
1280 	build_ea_a(info, M68K_INS_ADDA, 2);
1281 }
1282 
d68000_adda_32(m68k_info * info)1283 static void d68000_adda_32(m68k_info *info)
1284 {
1285 	build_ea_a(info, M68K_INS_ADDA, 4);
1286 }
1287 
d68000_addi_8(m68k_info * info)1288 static void d68000_addi_8(m68k_info *info)
1289 {
1290 	build_imm_ea(info, M68K_INS_ADDI, 1, read_imm_8(info));
1291 }
1292 
d68000_addi_16(m68k_info * info)1293 static void d68000_addi_16(m68k_info *info)
1294 {
1295 	build_imm_ea(info, M68K_INS_ADDI, 2, read_imm_16(info));
1296 }
1297 
d68000_addi_32(m68k_info * info)1298 static void d68000_addi_32(m68k_info *info)
1299 {
1300 	build_imm_ea(info, M68K_INS_ADDI, 4, read_imm_32(info));
1301 }
1302 
d68000_addq_8(m68k_info * info)1303 static void d68000_addq_8(m68k_info *info)
1304 {
1305 	build_3bit_ea(info, M68K_INS_ADDQ, 1);
1306 }
1307 
d68000_addq_16(m68k_info * info)1308 static void d68000_addq_16(m68k_info *info)
1309 {
1310 	build_3bit_ea(info, M68K_INS_ADDQ, 2);
1311 }
1312 
d68000_addq_32(m68k_info * info)1313 static void d68000_addq_32(m68k_info *info)
1314 {
1315 	build_3bit_ea(info, M68K_INS_ADDQ, 4);
1316 }
1317 
d68000_addx_rr_8(m68k_info * info)1318 static void d68000_addx_rr_8(m68k_info *info)
1319 {
1320 	build_rr(info, M68K_INS_ADDX, 1, 0);
1321 }
1322 
d68000_addx_rr_16(m68k_info * info)1323 static void d68000_addx_rr_16(m68k_info *info)
1324 {
1325 	build_rr(info, M68K_INS_ADDX, 2, 0);
1326 }
1327 
d68000_addx_rr_32(m68k_info * info)1328 static void d68000_addx_rr_32(m68k_info *info)
1329 {
1330 	build_rr(info, M68K_INS_ADDX, 4, 0);
1331 }
1332 
d68000_addx_mm_8(m68k_info * info)1333 static void d68000_addx_mm_8(m68k_info *info)
1334 {
1335 	build_mm(info, M68K_INS_ADDX, 1, 0);
1336 }
1337 
d68000_addx_mm_16(m68k_info * info)1338 static void d68000_addx_mm_16(m68k_info *info)
1339 {
1340 	build_mm(info, M68K_INS_ADDX, 2, 0);
1341 }
1342 
d68000_addx_mm_32(m68k_info * info)1343 static void d68000_addx_mm_32(m68k_info *info)
1344 {
1345 	build_mm(info, M68K_INS_ADDX, 4, 0);
1346 }
1347 
d68000_and_er_8(m68k_info * info)1348 static void d68000_and_er_8(m68k_info *info)
1349 {
1350 	build_er_1(info, M68K_INS_AND, 1);
1351 }
1352 
d68000_and_er_16(m68k_info * info)1353 static void d68000_and_er_16(m68k_info *info)
1354 {
1355 	build_er_1(info, M68K_INS_AND, 2);
1356 }
1357 
d68000_and_er_32(m68k_info * info)1358 static void d68000_and_er_32(m68k_info *info)
1359 {
1360 	build_er_1(info, M68K_INS_AND, 4);
1361 }
1362 
d68000_and_re_8(m68k_info * info)1363 static void d68000_and_re_8(m68k_info *info)
1364 {
1365 	build_re_1(info, M68K_INS_AND, 1);
1366 }
1367 
d68000_and_re_16(m68k_info * info)1368 static void d68000_and_re_16(m68k_info *info)
1369 {
1370 	build_re_1(info, M68K_INS_AND, 2);
1371 }
1372 
d68000_and_re_32(m68k_info * info)1373 static void d68000_and_re_32(m68k_info *info)
1374 {
1375 	build_re_1(info, M68K_INS_AND, 4);
1376 }
1377 
d68000_andi_8(m68k_info * info)1378 static void d68000_andi_8(m68k_info *info)
1379 {
1380 	build_imm_ea(info, M68K_INS_ANDI, 1, read_imm_8(info));
1381 }
1382 
d68000_andi_16(m68k_info * info)1383 static void d68000_andi_16(m68k_info *info)
1384 {
1385 	build_imm_ea(info, M68K_INS_ANDI, 2, read_imm_16(info));
1386 }
1387 
d68000_andi_32(m68k_info * info)1388 static void d68000_andi_32(m68k_info *info)
1389 {
1390 	build_imm_ea(info, M68K_INS_ANDI, 4, read_imm_32(info));
1391 }
1392 
d68000_andi_to_ccr(m68k_info * info)1393 static void d68000_andi_to_ccr(m68k_info *info)
1394 {
1395 	build_imm_special_reg(info, M68K_INS_ANDI, read_imm_8(info), 1, M68K_REG_CCR);
1396 }
1397 
d68000_andi_to_sr(m68k_info * info)1398 static void d68000_andi_to_sr(m68k_info *info)
1399 {
1400 	build_imm_special_reg(info, M68K_INS_ANDI, read_imm_16(info), 2, M68K_REG_SR);
1401 }
1402 
d68000_asr_s_8(m68k_info * info)1403 static void d68000_asr_s_8(m68k_info *info)
1404 {
1405 	build_3bit_d(info, M68K_INS_ASR, 1);
1406 }
1407 
d68000_asr_s_16(m68k_info * info)1408 static void d68000_asr_s_16(m68k_info *info)
1409 {
1410 	build_3bit_d(info, M68K_INS_ASR, 2);
1411 }
1412 
d68000_asr_s_32(m68k_info * info)1413 static void d68000_asr_s_32(m68k_info *info)
1414 {
1415 	build_3bit_d(info, M68K_INS_ASR, 4);
1416 }
1417 
d68000_asr_r_8(m68k_info * info)1418 static void d68000_asr_r_8(m68k_info *info)
1419 {
1420 	build_r(info, M68K_INS_ASR, 1);
1421 }
1422 
d68000_asr_r_16(m68k_info * info)1423 static void d68000_asr_r_16(m68k_info *info)
1424 {
1425 	build_r(info, M68K_INS_ASR, 2);
1426 }
1427 
d68000_asr_r_32(m68k_info * info)1428 static void d68000_asr_r_32(m68k_info *info)
1429 {
1430 	build_r(info, M68K_INS_ASR, 4);
1431 }
1432 
d68000_asr_ea(m68k_info * info)1433 static void d68000_asr_ea(m68k_info *info)
1434 {
1435 	build_ea(info, M68K_INS_ASR, 2);
1436 }
1437 
d68000_asl_s_8(m68k_info * info)1438 static void d68000_asl_s_8(m68k_info *info)
1439 {
1440 	build_3bit_d(info, M68K_INS_ASL, 1);
1441 }
1442 
d68000_asl_s_16(m68k_info * info)1443 static void d68000_asl_s_16(m68k_info *info)
1444 {
1445 	build_3bit_d(info, M68K_INS_ASL, 2);
1446 }
1447 
d68000_asl_s_32(m68k_info * info)1448 static void d68000_asl_s_32(m68k_info *info)
1449 {
1450 	build_3bit_d(info, M68K_INS_ASL, 4);
1451 }
1452 
d68000_asl_r_8(m68k_info * info)1453 static void d68000_asl_r_8(m68k_info *info)
1454 {
1455 	build_r(info, M68K_INS_ASL, 1);
1456 }
1457 
d68000_asl_r_16(m68k_info * info)1458 static void d68000_asl_r_16(m68k_info *info)
1459 {
1460 	build_r(info, M68K_INS_ASL, 2);
1461 }
1462 
d68000_asl_r_32(m68k_info * info)1463 static void d68000_asl_r_32(m68k_info *info)
1464 {
1465 	build_r(info, M68K_INS_ASL, 4);
1466 }
1467 
d68000_asl_ea(m68k_info * info)1468 static void d68000_asl_ea(m68k_info *info)
1469 {
1470 	build_ea(info, M68K_INS_ASL, 2);
1471 }
1472 
d68000_bcc_8(m68k_info * info)1473 static void d68000_bcc_8(m68k_info *info)
1474 {
1475 	build_bcc(info, 1, make_int_8(info->ir));
1476 }
1477 
d68000_bcc_16(m68k_info * info)1478 static void d68000_bcc_16(m68k_info *info)
1479 {
1480 	build_bcc(info, 2, make_int_16(read_imm_16(info)));
1481 }
1482 
d68020_bcc_32(m68k_info * info)1483 static void d68020_bcc_32(m68k_info *info)
1484 {
1485 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1486 	build_bcc(info, 4, read_imm_32(info));
1487 }
1488 
d68000_bchg_r(m68k_info * info)1489 static void d68000_bchg_r(m68k_info *info)
1490 {
1491 	build_re_1(info, M68K_INS_BCHG, 1);
1492 }
1493 
d68000_bchg_s(m68k_info * info)1494 static void d68000_bchg_s(m68k_info *info)
1495 {
1496 	build_imm_ea(info, M68K_INS_BCHG, 1, read_imm_8(info));
1497 }
1498 
d68000_bclr_r(m68k_info * info)1499 static void d68000_bclr_r(m68k_info *info)
1500 {
1501 	build_re_1(info, M68K_INS_BCLR, 1);
1502 }
1503 
d68000_bclr_s(m68k_info * info)1504 static void d68000_bclr_s(m68k_info *info)
1505 {
1506 	build_imm_ea(info, M68K_INS_BCLR, 1, read_imm_8(info));
1507 }
1508 
d68010_bkpt(m68k_info * info)1509 static void d68010_bkpt(m68k_info *info)
1510 {
1511 	LIMIT_CPU_TYPES(info, M68010_PLUS);
1512 	build_absolute_jump_with_immediate(info, M68K_INS_BKPT, 0, info->ir & 7);
1513 }
1514 
d68020_bfchg(m68k_info * info)1515 static void d68020_bfchg(m68k_info *info)
1516 {
1517 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1518 	build_bitfield_ins(info, M68K_INS_BFCHG, false);
1519 }
1520 
1521 
d68020_bfclr(m68k_info * info)1522 static void d68020_bfclr(m68k_info *info)
1523 {
1524 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1525 	build_bitfield_ins(info, M68K_INS_BFCLR, false);
1526 }
1527 
d68020_bfexts(m68k_info * info)1528 static void d68020_bfexts(m68k_info *info)
1529 {
1530 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1531 	build_bitfield_ins(info, M68K_INS_BFEXTS, true);
1532 }
1533 
d68020_bfextu(m68k_info * info)1534 static void d68020_bfextu(m68k_info *info)
1535 {
1536 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1537 	build_bitfield_ins(info, M68K_INS_BFEXTU, true);
1538 }
1539 
d68020_bfffo(m68k_info * info)1540 static void d68020_bfffo(m68k_info *info)
1541 {
1542 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1543 	build_bitfield_ins(info, M68K_INS_BFFFO, true);
1544 }
1545 
d68020_bfins(m68k_info * info)1546 static void d68020_bfins(m68k_info *info)
1547 {
1548 	cs_m68k* ext = &info->extension;
1549 	cs_m68k_op temp;
1550 
1551 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1552 	build_bitfield_ins(info, M68K_INS_BFINS, true);
1553 
1554 	// a bit hacky but we need to flip the args on only this instruction
1555 
1556 	temp = ext->operands[0];
1557 	ext->operands[0] = ext->operands[1];
1558 	ext->operands[1] = temp;
1559 }
1560 
d68020_bfset(m68k_info * info)1561 static void d68020_bfset(m68k_info *info)
1562 {
1563 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1564 	build_bitfield_ins(info, M68K_INS_BFSET, false);
1565 }
1566 
d68020_bftst(m68k_info * info)1567 static void d68020_bftst(m68k_info *info)
1568 {
1569 	build_bitfield_ins(info, M68K_INS_BFTST, false);
1570 }
1571 
d68000_bra_8(m68k_info * info)1572 static void d68000_bra_8(m68k_info *info)
1573 {
1574 	build_relative_branch(info, M68K_INS_BRA, 1, make_int_8(info->ir));
1575 }
1576 
d68000_bra_16(m68k_info * info)1577 static void d68000_bra_16(m68k_info *info)
1578 {
1579 	build_relative_branch(info, M68K_INS_BRA, 2, make_int_16(read_imm_16(info)));
1580 }
1581 
d68020_bra_32(m68k_info * info)1582 static void d68020_bra_32(m68k_info *info)
1583 {
1584 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1585 	build_relative_branch(info, M68K_INS_BRA, 4, read_imm_32(info));
1586 }
1587 
d68000_bset_r(m68k_info * info)1588 static void d68000_bset_r(m68k_info *info)
1589 {
1590 	build_re_1(info, M68K_INS_BSET, 1);
1591 }
1592 
d68000_bset_s(m68k_info * info)1593 static void d68000_bset_s(m68k_info *info)
1594 {
1595 	build_imm_ea(info, M68K_INS_BSET, 1, read_imm_8(info));
1596 }
1597 
d68000_bsr_8(m68k_info * info)1598 static void d68000_bsr_8(m68k_info *info)
1599 {
1600 	build_relative_branch(info, M68K_INS_BSR, 1, make_int_8(info->ir));
1601 }
1602 
d68000_bsr_16(m68k_info * info)1603 static void d68000_bsr_16(m68k_info *info)
1604 {
1605 	build_relative_branch(info, M68K_INS_BSR, 2, make_int_16(read_imm_16(info)));
1606 }
1607 
d68020_bsr_32(m68k_info * info)1608 static void d68020_bsr_32(m68k_info *info)
1609 {
1610 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1611 	build_relative_branch(info, M68K_INS_BSR, 4, peek_imm_32(info));
1612 }
1613 
d68000_btst_r(m68k_info * info)1614 static void d68000_btst_r(m68k_info *info)
1615 {
1616 	build_re_1(info, M68K_INS_BTST, 4);
1617 }
1618 
d68000_btst_s(m68k_info * info)1619 static void d68000_btst_s(m68k_info *info)
1620 {
1621 	build_imm_ea(info, M68K_INS_BTST, 1, read_imm_8(info));
1622 }
1623 
d68020_callm(m68k_info * info)1624 static void d68020_callm(m68k_info *info)
1625 {
1626 	LIMIT_CPU_TYPES(info, M68020_ONLY);
1627 	build_imm_ea(info, M68K_INS_CALLM, 0, read_imm_8(info));
1628 }
1629 
d68020_cas_8(m68k_info * info)1630 static void d68020_cas_8(m68k_info *info)
1631 {
1632 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1633 	build_d_d_ea(info, M68K_INS_CAS, 1);
1634 }
1635 
d68020_cas_16(m68k_info * info)1636 static void d68020_cas_16(m68k_info *info)
1637 {
1638 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1639 	build_d_d_ea(info, M68K_INS_CAS, 2);
1640 }
1641 
d68020_cas_32(m68k_info * info)1642 static void d68020_cas_32(m68k_info *info)
1643 {
1644 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1645 	build_d_d_ea(info, M68K_INS_CAS, 4);
1646 }
1647 
d68020_cas2_16(m68k_info * info)1648 static void d68020_cas2_16(m68k_info *info)
1649 {
1650 	build_cas2(info, 2);
1651 }
1652 
d68020_cas2_32(m68k_info * info)1653 static void d68020_cas2_32(m68k_info *info)
1654 {
1655 	build_cas2(info, 4);
1656 }
1657 
d68000_chk_16(m68k_info * info)1658 static void d68000_chk_16(m68k_info *info)
1659 {
1660 	build_er_1(info, M68K_INS_CHK, 2);
1661 }
1662 
d68020_chk_32(m68k_info * info)1663 static void d68020_chk_32(m68k_info *info)
1664 {
1665 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1666 	build_er_1(info, M68K_INS_CHK, 4);
1667 }
1668 
d68020_chk2_cmp2_8(m68k_info * info)1669 static void d68020_chk2_cmp2_8(m68k_info *info)
1670 {
1671 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1672 	build_chk2_cmp2(info, 1);
1673 }
1674 
d68020_chk2_cmp2_16(m68k_info * info)1675 static void d68020_chk2_cmp2_16(m68k_info *info)
1676 {
1677 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1678 	build_chk2_cmp2(info, 2);
1679 }
1680 
d68020_chk2_cmp2_32(m68k_info * info)1681 static void d68020_chk2_cmp2_32(m68k_info *info)
1682 {
1683 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1684 	build_chk2_cmp2(info, 4);
1685 }
1686 
d68040_cinv(m68k_info * info)1687 static void d68040_cinv(m68k_info *info)
1688 {
1689 	LIMIT_CPU_TYPES(info, M68040_PLUS);
1690 	build_cpush_cinv(info, M68K_INS_CINVL);
1691 }
1692 
d68000_clr_8(m68k_info * info)1693 static void d68000_clr_8(m68k_info *info)
1694 {
1695 	build_ea(info, M68K_INS_CLR, 1);
1696 }
1697 
d68000_clr_16(m68k_info * info)1698 static void d68000_clr_16(m68k_info *info)
1699 {
1700 	build_ea(info, M68K_INS_CLR, 2);
1701 }
1702 
d68000_clr_32(m68k_info * info)1703 static void d68000_clr_32(m68k_info *info)
1704 {
1705 	build_ea(info, M68K_INS_CLR, 4);
1706 }
1707 
d68000_cmp_8(m68k_info * info)1708 static void d68000_cmp_8(m68k_info *info)
1709 {
1710 	build_er_1(info, M68K_INS_CMP, 1);
1711 }
1712 
d68000_cmp_16(m68k_info * info)1713 static void d68000_cmp_16(m68k_info *info)
1714 {
1715 	build_er_1(info, M68K_INS_CMP, 2);
1716 }
1717 
d68000_cmp_32(m68k_info * info)1718 static void d68000_cmp_32(m68k_info *info)
1719 {
1720 	build_er_1(info, M68K_INS_CMP, 4);
1721 }
1722 
d68000_cmpa_16(m68k_info * info)1723 static void d68000_cmpa_16(m68k_info *info)
1724 {
1725 	build_ea_a(info, M68K_INS_CMPA, 2);
1726 }
1727 
d68000_cmpa_32(m68k_info * info)1728 static void d68000_cmpa_32(m68k_info *info)
1729 {
1730 	build_ea_a(info, M68K_INS_CMPA, 4);
1731 }
1732 
d68000_cmpi_8(m68k_info * info)1733 static void d68000_cmpi_8(m68k_info *info)
1734 {
1735 	build_imm_ea(info, M68K_INS_CMPI, 1, read_imm_8(info));
1736 }
1737 
d68020_cmpi_pcdi_8(m68k_info * info)1738 static void d68020_cmpi_pcdi_8(m68k_info *info)
1739 {
1740 	LIMIT_CPU_TYPES(info, M68010_PLUS);
1741 	build_imm_ea(info, M68K_INS_CMPI, 1, read_imm_8(info));
1742 }
1743 
d68020_cmpi_pcix_8(m68k_info * info)1744 static void d68020_cmpi_pcix_8(m68k_info *info)
1745 {
1746 	LIMIT_CPU_TYPES(info, M68010_PLUS);
1747 	build_imm_ea(info, M68K_INS_CMPI, 1, read_imm_8(info));
1748 }
1749 
d68000_cmpi_16(m68k_info * info)1750 static void d68000_cmpi_16(m68k_info *info)
1751 {
1752 	build_imm_ea(info, M68K_INS_CMPI, 2, read_imm_16(info));
1753 }
1754 
d68020_cmpi_pcdi_16(m68k_info * info)1755 static void d68020_cmpi_pcdi_16(m68k_info *info)
1756 {
1757 	LIMIT_CPU_TYPES(info, M68010_PLUS);
1758 	build_imm_ea(info, M68K_INS_CMPI, 2, read_imm_16(info));
1759 }
1760 
d68020_cmpi_pcix_16(m68k_info * info)1761 static void d68020_cmpi_pcix_16(m68k_info *info)
1762 {
1763 	LIMIT_CPU_TYPES(info, M68010_PLUS);
1764 	build_imm_ea(info, M68K_INS_CMPI, 2, read_imm_16(info));
1765 }
1766 
d68000_cmpi_32(m68k_info * info)1767 static void d68000_cmpi_32(m68k_info *info)
1768 {
1769 	build_imm_ea(info, M68K_INS_CMPI, 4, read_imm_32(info));
1770 }
1771 
d68020_cmpi_pcdi_32(m68k_info * info)1772 static void d68020_cmpi_pcdi_32(m68k_info *info)
1773 {
1774 	LIMIT_CPU_TYPES(info, M68010_PLUS);
1775 	build_imm_ea(info, M68K_INS_CMPI, 4, read_imm_32(info));
1776 }
1777 
d68020_cmpi_pcix_32(m68k_info * info)1778 static void d68020_cmpi_pcix_32(m68k_info *info)
1779 {
1780 	LIMIT_CPU_TYPES(info, M68010_PLUS);
1781 	build_imm_ea(info, M68K_INS_CMPI, 4, read_imm_32(info));
1782 }
1783 
d68000_cmpm_8(m68k_info * info)1784 static void d68000_cmpm_8(m68k_info *info)
1785 {
1786 	build_pi_pi(info, M68K_INS_CMPM, 1);
1787 }
1788 
d68000_cmpm_16(m68k_info * info)1789 static void d68000_cmpm_16(m68k_info *info)
1790 {
1791 	build_pi_pi(info, M68K_INS_CMPM, 2);
1792 }
1793 
d68000_cmpm_32(m68k_info * info)1794 static void d68000_cmpm_32(m68k_info *info)
1795 {
1796 	build_pi_pi(info, M68K_INS_CMPM, 4);
1797 }
1798 
make_cpbcc_operand(cs_m68k_op * op,int size,int displacement)1799 static void make_cpbcc_operand(cs_m68k_op* op, int size, int displacement)
1800 {
1801 	op->address_mode = M68K_AM_BRANCH_DISPLACEMENT;
1802 	op->type = M68K_OP_BR_DISP;
1803 	op->br_disp.disp = displacement;
1804 	op->br_disp.disp_size = size;
1805 }
1806 
d68020_cpbcc_16(m68k_info * info)1807 static void d68020_cpbcc_16(m68k_info *info)
1808 {
1809 	cs_m68k_op* op0;
1810 	cs_m68k* ext;
1811 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1812 
1813 	// these are all in row with the extension so just doing a add here is fine
1814 	info->inst->Opcode += (info->ir & 0x2f);
1815 
1816 	ext = build_init_op(info, M68K_INS_FBF, 1, 2);
1817 	op0 = &ext->operands[0];
1818 
1819 	make_cpbcc_operand(op0, M68K_OP_BR_DISP_SIZE_WORD, make_int_16(read_imm_16(info)));
1820 
1821 	set_insn_group(info, M68K_GRP_JUMP);
1822 	set_insn_group(info, M68K_GRP_BRANCH_RELATIVE);
1823 }
1824 
d68020_cpbcc_32(m68k_info * info)1825 static void d68020_cpbcc_32(m68k_info *info)
1826 {
1827 	cs_m68k* ext;
1828 	cs_m68k_op* op0;
1829 
1830 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1831 
1832 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1833 
1834 	// these are all in row with the extension so just doing a add here is fine
1835 	info->inst->Opcode += (info->ir & 0x2f);
1836 
1837 	ext = build_init_op(info, M68K_INS_FBF, 1, 4);
1838 	op0 = &ext->operands[0];
1839 
1840 	make_cpbcc_operand(op0, M68K_OP_BR_DISP_SIZE_LONG, read_imm_32(info));
1841 
1842 	set_insn_group(info, M68K_GRP_JUMP);
1843 	set_insn_group(info, M68K_GRP_BRANCH_RELATIVE);
1844 }
1845 
d68020_cpdbcc(m68k_info * info)1846 static void d68020_cpdbcc(m68k_info *info)
1847 {
1848 	cs_m68k* ext;
1849 	cs_m68k_op* op0;
1850 	cs_m68k_op* op1;
1851 	uint ext1, ext2;
1852 
1853 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1854 
1855 	ext1 = read_imm_16(info);
1856 	ext2 = read_imm_16(info);
1857 
1858 	// these are all in row with the extension so just doing a add here is fine
1859 	info->inst->Opcode += (ext1 & 0x2f);
1860 
1861 	ext = build_init_op(info, M68K_INS_FDBF, 2, 0);
1862 	op0 = &ext->operands[0];
1863 	op1 = &ext->operands[1];
1864 
1865 	op0->reg = M68K_REG_D0 + (info->ir & 7);
1866 
1867 	make_cpbcc_operand(op1, M68K_OP_BR_DISP_SIZE_WORD, make_int_16(ext2) + 2);
1868 
1869 	set_insn_group(info, M68K_GRP_JUMP);
1870 	set_insn_group(info, M68K_GRP_BRANCH_RELATIVE);
1871 }
1872 
fmove_fpcr(m68k_info * info,uint extension)1873 static void fmove_fpcr(m68k_info *info, uint extension)
1874 {
1875 	cs_m68k_op* special;
1876 	cs_m68k_op* op_ea;
1877 
1878 	int regsel = (extension >> 10) & 0x7;
1879 	int dir = (extension >> 13) & 0x1;
1880 
1881 	cs_m68k* ext = build_init_op(info, M68K_INS_FMOVE, 2, 4);
1882 
1883 	special = &ext->operands[0];
1884 	op_ea = &ext->operands[1];
1885 
1886 	if (!dir) {
1887 		cs_m68k_op* t = special;
1888 		special = op_ea;
1889 		op_ea = t;
1890 	}
1891 
1892 	get_ea_mode_op(info, op_ea, info->ir, 4);
1893 
1894 	if (regsel & 4)
1895 		special->reg = M68K_REG_FPCR;
1896 	else if (regsel & 2)
1897 		special->reg = M68K_REG_FPSR;
1898 	else if (regsel & 1)
1899 		special->reg = M68K_REG_FPIAR;
1900 }
1901 
fmovem(m68k_info * info,uint extension)1902 static void fmovem(m68k_info *info, uint extension)
1903 {
1904 	cs_m68k_op* op_reglist;
1905 	cs_m68k_op* op_ea;
1906 	int dir = (extension >> 13) & 0x1;
1907 	int mode = (extension >> 11) & 0x3;
1908 	uint reglist = extension & 0xff;
1909 	cs_m68k* ext = build_init_op(info, M68K_INS_FMOVEM, 2, 0);
1910 
1911 	op_reglist = &ext->operands[0];
1912 	op_ea = &ext->operands[1];
1913 
1914 	// flip args around
1915 
1916 	if (!dir) {
1917 		cs_m68k_op* t = op_reglist;
1918 		op_reglist = op_ea;
1919 		op_ea = t;
1920 	}
1921 
1922 	get_ea_mode_op(info, op_ea, info->ir, 0);
1923 
1924 	switch (mode) {
1925 		case 1 : // Dynamic list in dn register
1926 			op_reglist->reg = M68K_REG_D0 + ((reglist >> 4) & 7);
1927 			break;
1928 
1929 		case 0 :
1930 			op_reglist->address_mode = M68K_AM_NONE;
1931 			op_reglist->type = M68K_OP_REG_BITS;
1932 			op_reglist->register_bits = reglist << 16;
1933 			break;
1934 
1935 		case 2 : // Static list
1936 			op_reglist->address_mode = M68K_AM_NONE;
1937 			op_reglist->type = M68K_OP_REG_BITS;
1938 			op_reglist->register_bits = ((uint32_t)reverse_bits_8(reglist)) << 16;
1939 			break;
1940 	}
1941 }
1942 
d68020_cpgen(m68k_info * info)1943 static void d68020_cpgen(m68k_info *info)
1944 {
1945 	cs_m68k *ext;
1946 	cs_m68k_op* op0;
1947 	cs_m68k_op* op1;
1948 	bool supports_single_op;
1949 	uint next;
1950 	int rm, src, dst, opmode;
1951 
1952 
1953 	LIMIT_CPU_TYPES(info, M68020_PLUS);
1954 
1955 	supports_single_op = true;
1956 
1957 	next = read_imm_16(info);
1958 
1959 	rm = (next >> 14) & 0x1;
1960 	src = (next >> 10) & 0x7;
1961 	dst = (next >> 7) & 0x7;
1962 	opmode = next & 0x3f;
1963 
1964 	// special handling for fmovecr
1965 
1966 	if (BITFIELD(info->ir, 5, 0) == 0 && BITFIELD(next, 15, 10) == 0x17) {
1967 		cs_m68k_op* op0;
1968 		cs_m68k_op* op1;
1969 		cs_m68k* ext = build_init_op(info, M68K_INS_FMOVECR, 2, 0);
1970 
1971 		op0 = &ext->operands[0];
1972 		op1 = &ext->operands[1];
1973 
1974 		op0->address_mode = M68K_AM_IMMEDIATE;
1975 		op0->type = M68K_OP_IMM;
1976 		op0->imm = next & 0x3f;
1977 
1978 		op1->reg = M68K_REG_FP0 + ((next >> 7) & 7);
1979 
1980 		return;
1981 	}
1982 
1983 	// deal with extended move stuff
1984 
1985 	switch ((next >> 13) & 0x7) {
1986 		// fmovem fpcr
1987 		case 0x4:	// FMOVEM ea, FPCR
1988 		case 0x5:	// FMOVEM FPCR, ea
1989 			fmove_fpcr(info, next);
1990 			return;
1991 
1992 		// fmovem list
1993 		case 0x6:
1994 		case 0x7:
1995 			fmovem(info, next);
1996 			return;
1997 	}
1998 
1999 	// See comment bellow on why this is being done
2000 
2001 	if ((next >> 6) & 1)
2002 		opmode &= ~4;
2003 
2004 	// special handling of some instructions here
2005 
2006 	switch (opmode) {
2007 		case 0x00: MCInst_setOpcode(info->inst, M68K_INS_FMOVE); supports_single_op = false; break;
2008 		case 0x01: MCInst_setOpcode(info->inst, M68K_INS_FINT); break;
2009 		case 0x02: MCInst_setOpcode(info->inst, M68K_INS_FSINH); break;
2010 		case 0x03: MCInst_setOpcode(info->inst, M68K_INS_FINTRZ); break;
2011 		case 0x04: MCInst_setOpcode(info->inst, M68K_INS_FSQRT); break;
2012 		case 0x06: MCInst_setOpcode(info->inst, M68K_INS_FLOGNP1); break;
2013 		case 0x08: MCInst_setOpcode(info->inst, M68K_INS_FETOXM1); break;
2014 		case 0x09: MCInst_setOpcode(info->inst, M68K_INS_FATANH); break;
2015 		case 0x0a: MCInst_setOpcode(info->inst, M68K_INS_FATAN); break;
2016 		case 0x0c: MCInst_setOpcode(info->inst, M68K_INS_FASIN); break;
2017 		case 0x0d: MCInst_setOpcode(info->inst, M68K_INS_FATANH); break;
2018 		case 0x0e: MCInst_setOpcode(info->inst, M68K_INS_FSIN); break;
2019 		case 0x0f: MCInst_setOpcode(info->inst, M68K_INS_FTAN); break;
2020 		case 0x10: MCInst_setOpcode(info->inst, M68K_INS_FETOX); break;
2021 		case 0x11: MCInst_setOpcode(info->inst, M68K_INS_FTWOTOX); break;
2022 		case 0x12: MCInst_setOpcode(info->inst, M68K_INS_FTENTOX); break;
2023 		case 0x14: MCInst_setOpcode(info->inst, M68K_INS_FLOGN); break;
2024 		case 0x15: MCInst_setOpcode(info->inst, M68K_INS_FLOG10); break;
2025 		case 0x16: MCInst_setOpcode(info->inst, M68K_INS_FLOG2); break;
2026 		case 0x18: MCInst_setOpcode(info->inst, M68K_INS_FABS); break;
2027 		case 0x19: MCInst_setOpcode(info->inst, M68K_INS_FCOSH); break;
2028 		case 0x1a: MCInst_setOpcode(info->inst, M68K_INS_FNEG); break;
2029 		case 0x1c: MCInst_setOpcode(info->inst, M68K_INS_FACOS); break;
2030 		case 0x1d: MCInst_setOpcode(info->inst, M68K_INS_FCOS); break;
2031 		case 0x1e: MCInst_setOpcode(info->inst, M68K_INS_FGETEXP); break;
2032 		case 0x1f: MCInst_setOpcode(info->inst, M68K_INS_FGETMAN); break;
2033 		case 0x20: MCInst_setOpcode(info->inst, M68K_INS_FDIV); supports_single_op = false; break;
2034 		case 0x21: MCInst_setOpcode(info->inst, M68K_INS_FMOD); supports_single_op = false; break;
2035 		case 0x22: MCInst_setOpcode(info->inst, M68K_INS_FADD); supports_single_op = false; break;
2036 		case 0x23: MCInst_setOpcode(info->inst, M68K_INS_FMUL); supports_single_op = false; break;
2037 		case 0x24: MCInst_setOpcode(info->inst, M68K_INS_FSGLDIV); supports_single_op = false; break;
2038 		case 0x25: MCInst_setOpcode(info->inst, M68K_INS_FREM); break;
2039 		case 0x26: MCInst_setOpcode(info->inst, M68K_INS_FSCALE); break;
2040 		case 0x27: MCInst_setOpcode(info->inst, M68K_INS_FSGLMUL); break;
2041 		case 0x28: MCInst_setOpcode(info->inst, M68K_INS_FSUB); supports_single_op = false; break;
2042 		case 0x38: MCInst_setOpcode(info->inst, M68K_INS_FCMP); supports_single_op = false; break;
2043 		case 0x3a: MCInst_setOpcode(info->inst, M68K_INS_FTST); break;
2044 		default:
2045 			break;
2046 	}
2047 
2048 	// Some trickery here! It's not documented but if bit 6 is set this is a s/d opcode and then
2049 	// if bit 2 is set it's a d. As we already have set our opcode in the code above we can just
2050 	// offset it as the following 2 op codes (if s/d is supported) will always be directly after it
2051 
2052 	if ((next >> 6) & 1) {
2053 		if ((next >> 2) & 1)
2054 			info->inst->Opcode += 2;
2055 		else
2056 			info->inst->Opcode += 1;
2057 	}
2058 
2059 	ext = &info->extension;
2060 
2061 	ext->op_count = 2;
2062 	ext->op_size.type = M68K_SIZE_TYPE_CPU;
2063 	ext->op_size.cpu_size = 0;
2064 
2065 	op0 = &ext->operands[0];
2066 	op1 = &ext->operands[1];
2067 
2068 	if (rm == 0 && supports_single_op && src == dst) {
2069 		ext->op_count = 1;
2070 		op0->reg = M68K_REG_FP0 + dst;
2071 		return;
2072 	}
2073 
2074 	if (rm == 1) {
2075 		switch (src) {
2076 			case 0x00 :
2077 				ext->op_size.cpu_size = M68K_CPU_SIZE_LONG;
2078 				get_ea_mode_op(info, op0, info->ir, 4);
2079 				break;
2080 
2081 			case 0x06 :
2082 				ext->op_size.cpu_size = M68K_CPU_SIZE_BYTE;
2083 				get_ea_mode_op(info, op0, info->ir, 1);
2084 				break;
2085 
2086 			case 0x04 :
2087 				ext->op_size.cpu_size = M68K_CPU_SIZE_WORD;
2088 				get_ea_mode_op(info, op0, info->ir, 2);
2089 				break;
2090 
2091 			case 0x01 :
2092 				ext->op_size.type = M68K_SIZE_TYPE_FPU;
2093 				ext->op_size.fpu_size = M68K_FPU_SIZE_SINGLE;
2094 				get_ea_mode_op(info, op0, info->ir, 4);
2095 				op0->type = M68K_OP_FP_SINGLE;
2096 				break;
2097 
2098 			case 0x05:
2099 				ext->op_size.type = M68K_SIZE_TYPE_FPU;
2100 				ext->op_size.fpu_size = M68K_FPU_SIZE_DOUBLE;
2101 				get_ea_mode_op(info, op0, info->ir, 8);
2102 				op0->type = M68K_OP_FP_DOUBLE;
2103 				break;
2104 
2105 			default :
2106 				ext->op_size.type = M68K_SIZE_TYPE_FPU;
2107 				ext->op_size.fpu_size = M68K_FPU_SIZE_EXTENDED;
2108 				break;
2109 		}
2110 	} else {
2111 		op0->reg = M68K_REG_FP0 + src;
2112 	}
2113 
2114 	op1->reg = M68K_REG_FP0 + dst;
2115 }
2116 
d68020_cprestore(m68k_info * info)2117 static void d68020_cprestore(m68k_info *info)
2118 {
2119 	cs_m68k* ext;
2120 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2121 
2122 	ext = build_init_op(info, M68K_INS_FRESTORE, 1, 0);
2123 	get_ea_mode_op(info, &ext->operands[0], info->ir, 1);
2124 }
2125 
d68020_cpsave(m68k_info * info)2126 static void d68020_cpsave(m68k_info *info)
2127 {
2128 	cs_m68k* ext;
2129 
2130 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2131 
2132 	ext = build_init_op(info, M68K_INS_FSAVE, 1, 0);
2133 	get_ea_mode_op(info, &ext->operands[0], info->ir, 1);
2134 }
2135 
d68020_cpscc(m68k_info * info)2136 static void d68020_cpscc(m68k_info *info)
2137 {
2138 	cs_m68k* ext;
2139 
2140 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2141 	ext = build_init_op(info, M68K_INS_FSF, 1, 1);
2142 
2143 	// these are all in row with the extension so just doing a add here is fine
2144 	info->inst->Opcode += (read_imm_16(info) & 0x2f);
2145 
2146 	get_ea_mode_op(info, &ext->operands[0], info->ir, 1);
2147 }
2148 
d68020_cptrapcc_0(m68k_info * info)2149 static void d68020_cptrapcc_0(m68k_info *info)
2150 {
2151 	uint extension1;
2152 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2153 
2154 	extension1 = read_imm_16(info);
2155 
2156 	build_init_op(info, M68K_INS_FTRAPF, 0, 0);
2157 
2158 	// these are all in row with the extension so just doing a add here is fine
2159 	info->inst->Opcode += (extension1 & 0x2f);
2160 }
2161 
d68020_cptrapcc_16(m68k_info * info)2162 static void d68020_cptrapcc_16(m68k_info *info)
2163 {
2164 	uint extension1, extension2;
2165 	cs_m68k_op* op0;
2166 	cs_m68k* ext;
2167 
2168 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2169 
2170 	extension1 = read_imm_16(info);
2171 	extension2 = read_imm_16(info);
2172 
2173 	ext = build_init_op(info, M68K_INS_FTRAPF, 1, 2);
2174 
2175 	// these are all in row with the extension so just doing a add here is fine
2176 	info->inst->Opcode += (extension1 & 0x2f);
2177 
2178 	op0 = &ext->operands[0];
2179 
2180 	op0->address_mode = M68K_AM_IMMEDIATE;
2181 	op0->type = M68K_OP_IMM;
2182 	op0->imm = extension2;
2183 }
2184 
d68020_cptrapcc_32(m68k_info * info)2185 static void d68020_cptrapcc_32(m68k_info *info)
2186 {
2187 	uint extension1, extension2;
2188 	cs_m68k* ext;
2189 	cs_m68k_op* op0;
2190 
2191 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2192 
2193 	extension1 = read_imm_16(info);
2194 	extension2 = read_imm_32(info);
2195 
2196 	ext = build_init_op(info, M68K_INS_FTRAPF, 1, 2);
2197 
2198 	// these are all in row with the extension so just doing a add here is fine
2199 	info->inst->Opcode += (extension1 & 0x2f);
2200 
2201 	op0 = &ext->operands[0];
2202 
2203 	op0->address_mode = M68K_AM_IMMEDIATE;
2204 	op0->type = M68K_OP_IMM;
2205 	op0->imm = extension2;
2206 }
2207 
d68040_cpush(m68k_info * info)2208 static void d68040_cpush(m68k_info *info)
2209 {
2210 	LIMIT_CPU_TYPES(info, M68040_PLUS);
2211 	build_cpush_cinv(info, M68K_INS_CPUSHL);
2212 }
2213 
d68000_dbra(m68k_info * info)2214 static void d68000_dbra(m68k_info *info)
2215 {
2216 	build_dbxx(info, M68K_INS_DBRA, 0, make_int_16(read_imm_16(info)));
2217 }
2218 
d68000_dbcc(m68k_info * info)2219 static void d68000_dbcc(m68k_info *info)
2220 {
2221 	build_dbcc(info, 0, make_int_16(read_imm_16(info)));
2222 }
2223 
d68000_divs(m68k_info * info)2224 static void d68000_divs(m68k_info *info)
2225 {
2226 	build_er_1(info, M68K_INS_DIVS, 2);
2227 }
2228 
d68000_divu(m68k_info * info)2229 static void d68000_divu(m68k_info *info)
2230 {
2231 	build_er_1(info, M68K_INS_DIVU, 2);
2232 }
2233 
d68020_divl(m68k_info * info)2234 static void d68020_divl(m68k_info *info)
2235 {
2236 	uint extension, insn_signed;
2237 	cs_m68k* ext;
2238 	cs_m68k_op* op0;
2239 	cs_m68k_op* op1;
2240 	uint reg_0, reg_1;
2241 
2242 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2243 
2244 	extension = read_imm_16(info);
2245 	insn_signed = 0;
2246 
2247 	if (BIT_B((extension)))
2248 		insn_signed = 1;
2249 
2250 	ext = build_init_op(info, insn_signed ? M68K_INS_DIVS : M68K_INS_DIVU, 2, 4);
2251 
2252 	op0 = &ext->operands[0];
2253 	op1 = &ext->operands[1];
2254 
2255 	get_ea_mode_op(info, op0, info->ir, 4);
2256 
2257 	reg_0 = extension & 7;
2258 	reg_1 = (extension >> 12) & 7;
2259 
2260 	op1->address_mode = M68K_AM_NONE;
2261 	op1->type = M68K_OP_REG_PAIR;
2262 	op1->reg_pair.reg_0 = reg_0;
2263 	op1->reg_pair.reg_1 = reg_1;
2264 
2265 	if ((reg_0 == reg_1) || !BIT_A(extension)) {
2266 		op1->type = M68K_OP_REG;
2267 		op1->reg = M68K_REG_D0 + reg_1;
2268 	}
2269 }
2270 
d68000_eor_8(m68k_info * info)2271 static void d68000_eor_8(m68k_info *info)
2272 {
2273 	build_re_1(info, M68K_INS_EOR, 1);
2274 }
2275 
d68000_eor_16(m68k_info * info)2276 static void d68000_eor_16(m68k_info *info)
2277 {
2278 	build_re_1(info, M68K_INS_EOR, 2);
2279 }
2280 
d68000_eor_32(m68k_info * info)2281 static void d68000_eor_32(m68k_info *info)
2282 {
2283 	build_re_1(info, M68K_INS_EOR, 4);
2284 }
2285 
d68000_eori_8(m68k_info * info)2286 static void d68000_eori_8(m68k_info *info)
2287 {
2288 	build_imm_ea(info, M68K_INS_EORI, 1, read_imm_8(info));
2289 }
2290 
d68000_eori_16(m68k_info * info)2291 static void d68000_eori_16(m68k_info *info)
2292 {
2293 	build_imm_ea(info, M68K_INS_EORI, 2, read_imm_16(info));
2294 }
2295 
d68000_eori_32(m68k_info * info)2296 static void d68000_eori_32(m68k_info *info)
2297 {
2298 	build_imm_ea(info, M68K_INS_EORI, 4, read_imm_32(info));
2299 }
2300 
d68000_eori_to_ccr(m68k_info * info)2301 static void d68000_eori_to_ccr(m68k_info *info)
2302 {
2303 	build_imm_special_reg(info, M68K_INS_EORI, read_imm_8(info), 1, M68K_REG_CCR);
2304 }
2305 
d68000_eori_to_sr(m68k_info * info)2306 static void d68000_eori_to_sr(m68k_info *info)
2307 {
2308 	build_imm_special_reg(info, M68K_INS_EORI, read_imm_16(info), 2, M68K_REG_SR);
2309 }
2310 
d68000_exg_dd(m68k_info * info)2311 static void d68000_exg_dd(m68k_info *info)
2312 {
2313 	build_r(info, M68K_INS_EXG, 4);
2314 }
2315 
d68000_exg_aa(m68k_info * info)2316 static void d68000_exg_aa(m68k_info *info)
2317 {
2318 	cs_m68k_op* op0;
2319 	cs_m68k_op* op1;
2320 	cs_m68k* ext = build_init_op(info, M68K_INS_EXG, 2, 4);
2321 
2322 	op0 = &ext->operands[0];
2323 	op1 = &ext->operands[1];
2324 
2325 	op0->address_mode = M68K_AM_NONE;
2326 	op0->reg = M68K_REG_A0 + ((info->ir >> 9) & 7);
2327 
2328 	op1->address_mode = M68K_AM_NONE;
2329 	op1->reg = M68K_REG_A0 + (info->ir & 7);
2330 }
2331 
d68000_exg_da(m68k_info * info)2332 static void d68000_exg_da(m68k_info *info)
2333 {
2334 	cs_m68k_op* op0;
2335 	cs_m68k_op* op1;
2336 	cs_m68k* ext = build_init_op(info, M68K_INS_EXG, 2, 4);
2337 
2338 	op0 = &ext->operands[0];
2339 	op1 = &ext->operands[1];
2340 
2341 	op0->address_mode = M68K_AM_NONE;
2342 	op0->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
2343 
2344 	op1->address_mode = M68K_AM_NONE;
2345 	op1->reg = M68K_REG_A0 + (info->ir & 7);
2346 }
2347 
d68000_ext_16(m68k_info * info)2348 static void d68000_ext_16(m68k_info *info)
2349 {
2350 	build_d(info, M68K_INS_EXT, 2);
2351 }
2352 
d68000_ext_32(m68k_info * info)2353 static void d68000_ext_32(m68k_info *info)
2354 {
2355 	build_d(info, M68K_INS_EXT, 4);
2356 }
2357 
d68020_extb_32(m68k_info * info)2358 static void d68020_extb_32(m68k_info *info)
2359 {
2360 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2361 	build_d(info, M68K_INS_EXTB, 4);
2362 }
2363 
d68000_jmp(m68k_info * info)2364 static void d68000_jmp(m68k_info *info)
2365 {
2366 	cs_m68k* ext = build_init_op(info, M68K_INS_JMP, 1, 0);
2367 	set_insn_group(info, M68K_GRP_JUMP);
2368 	get_ea_mode_op(info, &ext->operands[0], info->ir, 4);
2369 }
2370 
d68000_jsr(m68k_info * info)2371 static void d68000_jsr(m68k_info *info)
2372 {
2373 	cs_m68k* ext = build_init_op(info, M68K_INS_JSR, 1, 0);
2374 	set_insn_group(info, M68K_GRP_JUMP);
2375 	get_ea_mode_op(info, &ext->operands[0], info->ir, 4);
2376 }
2377 
d68000_lea(m68k_info * info)2378 static void d68000_lea(m68k_info *info)
2379 {
2380 	build_ea_a(info, M68K_INS_LEA, 4);
2381 }
2382 
d68000_link_16(m68k_info * info)2383 static void d68000_link_16(m68k_info *info)
2384 {
2385 	build_link(info, read_imm_16(info), 2);
2386 }
2387 
d68020_link_32(m68k_info * info)2388 static void d68020_link_32(m68k_info *info)
2389 {
2390 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2391 	build_link(info, read_imm_32(info), 4);
2392 }
2393 
d68000_lsr_s_8(m68k_info * info)2394 static void d68000_lsr_s_8(m68k_info *info)
2395 {
2396 	build_3bit_d(info, M68K_INS_LSR, 1);
2397 }
2398 
d68000_lsr_s_16(m68k_info * info)2399 static void d68000_lsr_s_16(m68k_info *info)
2400 {
2401 	build_3bit_d(info, M68K_INS_LSR, 2);
2402 }
2403 
d68000_lsr_s_32(m68k_info * info)2404 static void d68000_lsr_s_32(m68k_info *info)
2405 {
2406 	build_3bit_d(info, M68K_INS_LSR, 4);
2407 }
2408 
d68000_lsr_r_8(m68k_info * info)2409 static void d68000_lsr_r_8(m68k_info *info)
2410 {
2411 	build_r(info, M68K_INS_LSR, 1);
2412 }
2413 
d68000_lsr_r_16(m68k_info * info)2414 static void d68000_lsr_r_16(m68k_info *info)
2415 {
2416 	build_r(info, M68K_INS_LSR, 2);
2417 }
2418 
d68000_lsr_r_32(m68k_info * info)2419 static void d68000_lsr_r_32(m68k_info *info)
2420 {
2421 	build_r(info, M68K_INS_LSR, 4);
2422 }
2423 
d68000_lsr_ea(m68k_info * info)2424 static void d68000_lsr_ea(m68k_info *info)
2425 {
2426 	build_ea(info, M68K_INS_LSR, 2);
2427 }
2428 
d68000_lsl_s_8(m68k_info * info)2429 static void d68000_lsl_s_8(m68k_info *info)
2430 {
2431 	build_3bit_d(info, M68K_INS_LSL, 1);
2432 }
2433 
d68000_lsl_s_16(m68k_info * info)2434 static void d68000_lsl_s_16(m68k_info *info)
2435 {
2436 	build_3bit_d(info, M68K_INS_LSL, 2);
2437 }
2438 
d68000_lsl_s_32(m68k_info * info)2439 static void d68000_lsl_s_32(m68k_info *info)
2440 {
2441 	build_3bit_d(info, M68K_INS_LSL, 4);
2442 }
2443 
d68000_lsl_r_8(m68k_info * info)2444 static void d68000_lsl_r_8(m68k_info *info)
2445 {
2446 	build_r(info, M68K_INS_LSL, 1);
2447 }
2448 
d68000_lsl_r_16(m68k_info * info)2449 static void d68000_lsl_r_16(m68k_info *info)
2450 {
2451 	build_r(info, M68K_INS_LSL, 2);
2452 }
2453 
d68000_lsl_r_32(m68k_info * info)2454 static void d68000_lsl_r_32(m68k_info *info)
2455 {
2456 	build_r(info, M68K_INS_LSL, 4);
2457 }
2458 
d68000_lsl_ea(m68k_info * info)2459 static void d68000_lsl_ea(m68k_info *info)
2460 {
2461 	build_ea(info, M68K_INS_LSL, 2);
2462 }
2463 
d68000_move_8(m68k_info * info)2464 static void d68000_move_8(m68k_info *info)
2465 {
2466 	build_ea_ea(info, M68K_INS_MOVE, 1);
2467 }
2468 
d68000_move_16(m68k_info * info)2469 static void d68000_move_16(m68k_info *info)
2470 {
2471 	build_ea_ea(info, M68K_INS_MOVE, 2);
2472 }
2473 
d68000_move_32(m68k_info * info)2474 static void d68000_move_32(m68k_info *info)
2475 {
2476 	build_ea_ea(info, M68K_INS_MOVE, 4);
2477 }
2478 
d68000_movea_16(m68k_info * info)2479 static void d68000_movea_16(m68k_info *info)
2480 {
2481 	build_ea_a(info, M68K_INS_MOVEA, 2);
2482 }
2483 
d68000_movea_32(m68k_info * info)2484 static void d68000_movea_32(m68k_info *info)
2485 {
2486 	build_ea_a(info, M68K_INS_MOVEA, 4);
2487 }
2488 
d68000_move_to_ccr(m68k_info * info)2489 static void d68000_move_to_ccr(m68k_info *info)
2490 {
2491 	cs_m68k_op* op0;
2492 	cs_m68k_op* op1;
2493 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 2);
2494 
2495 	op0 = &ext->operands[0];
2496 	op1 = &ext->operands[1];
2497 
2498 	get_ea_mode_op(info, op0, info->ir, 1);
2499 
2500 	op1->address_mode = M68K_AM_NONE;
2501 	op1->reg = M68K_REG_CCR;
2502 }
2503 
d68010_move_fr_ccr(m68k_info * info)2504 static void d68010_move_fr_ccr(m68k_info *info)
2505 {
2506 	cs_m68k_op* op0;
2507 	cs_m68k_op* op1;
2508 	cs_m68k* ext;
2509 
2510 	LIMIT_CPU_TYPES(info, M68010_PLUS);
2511 
2512 	ext = build_init_op(info, M68K_INS_MOVE, 2, 2);
2513 
2514 	op0 = &ext->operands[0];
2515 	op1 = &ext->operands[1];
2516 
2517 	op0->address_mode = M68K_AM_NONE;
2518 	op0->reg = M68K_REG_CCR;
2519 
2520 	get_ea_mode_op(info, op1, info->ir, 1);
2521 }
2522 
d68000_move_fr_sr(m68k_info * info)2523 static void d68000_move_fr_sr(m68k_info *info)
2524 {
2525 	cs_m68k_op* op0;
2526 	cs_m68k_op* op1;
2527 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 2);
2528 
2529 	op0 = &ext->operands[0];
2530 	op1 = &ext->operands[1];
2531 
2532 	op0->address_mode = M68K_AM_NONE;
2533 	op0->reg = M68K_REG_SR;
2534 
2535 	get_ea_mode_op(info, op1, info->ir, 2);
2536 }
2537 
d68000_move_to_sr(m68k_info * info)2538 static void d68000_move_to_sr(m68k_info *info)
2539 {
2540 	cs_m68k_op* op0;
2541 	cs_m68k_op* op1;
2542 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 2);
2543 
2544 	op0 = &ext->operands[0];
2545 	op1 = &ext->operands[1];
2546 
2547 	get_ea_mode_op(info, op0, info->ir, 2);
2548 
2549 	op1->address_mode = M68K_AM_NONE;
2550 	op1->reg = M68K_REG_SR;
2551 }
2552 
d68000_move_fr_usp(m68k_info * info)2553 static void d68000_move_fr_usp(m68k_info *info)
2554 {
2555 	cs_m68k_op* op0;
2556 	cs_m68k_op* op1;
2557 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 0);
2558 
2559 	op0 = &ext->operands[0];
2560 	op1 = &ext->operands[1];
2561 
2562 	op0->address_mode = M68K_AM_NONE;
2563 	op0->reg = M68K_REG_USP;
2564 
2565 	op1->address_mode = M68K_AM_NONE;
2566 	op1->reg = M68K_REG_A0 + (info->ir & 7);
2567 }
2568 
d68000_move_to_usp(m68k_info * info)2569 static void d68000_move_to_usp(m68k_info *info)
2570 {
2571 	cs_m68k_op* op0;
2572 	cs_m68k_op* op1;
2573 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 0);
2574 
2575 	op0 = &ext->operands[0];
2576 	op1 = &ext->operands[1];
2577 
2578 	op0->address_mode = M68K_AM_NONE;
2579 	op0->reg = M68K_REG_A0 + (info->ir & 7);
2580 
2581 	op1->address_mode = M68K_AM_NONE;
2582 	op1->reg = M68K_REG_USP;
2583 }
2584 
d68010_movec(m68k_info * info)2585 static void d68010_movec(m68k_info *info)
2586 {
2587 	uint extension;
2588 	m68k_reg reg;
2589 	cs_m68k* ext;
2590 	cs_m68k_op* op0;
2591 	cs_m68k_op* op1;
2592 
2593 
2594 	LIMIT_CPU_TYPES(info, M68010_PLUS);
2595 
2596 	extension = read_imm_16(info);
2597 	reg = M68K_REG_INVALID;
2598 
2599 	ext = build_init_op(info, M68K_INS_MOVEC, 2, 0);
2600 
2601 	op0 = &ext->operands[0];
2602 	op1 = &ext->operands[1];
2603 
2604 	switch (extension & 0xfff) {
2605 		case 0x000: reg = M68K_REG_SFC; break;
2606 		case 0x001: reg = M68K_REG_DFC; break;
2607 		case 0x800: reg = M68K_REG_USP; break;
2608 		case 0x801: reg = M68K_REG_VBR; break;
2609 		case 0x002: reg = M68K_REG_CACR; break;
2610 		case 0x802: reg = M68K_REG_CAAR; break;
2611 		case 0x803: reg = M68K_REG_MSP; break;
2612 		case 0x804: reg = M68K_REG_ISP; break;
2613 		case 0x003: reg = M68K_REG_TC; break;
2614 		case 0x004: reg = M68K_REG_ITT0; break;
2615 		case 0x005: reg = M68K_REG_ITT1; break;
2616 		case 0x006: reg = M68K_REG_DTT0; break;
2617 		case 0x007: reg = M68K_REG_DTT1; break;
2618 		case 0x805: reg = M68K_REG_MMUSR; break;
2619 		case 0x806: reg = M68K_REG_URP; break;
2620 		case 0x807: reg = M68K_REG_SRP; break;
2621 	}
2622 
2623 	if (BIT_1(info->ir)) {
2624 		op0->reg = (BIT_F(extension) ? M68K_REG_A0 : M68K_REG_D0) + ((extension >> 12) & 7);
2625 		op1->reg = reg;
2626 	} else {
2627 		op0->reg = reg;
2628 		op1->reg = (BIT_F(extension) ? M68K_REG_A0 : M68K_REG_D0) + ((extension >> 12) & 7);
2629 	}
2630 }
2631 
d68000_movem_pd_16(m68k_info * info)2632 static void d68000_movem_pd_16(m68k_info *info)
2633 {
2634 	build_movem_re(info, M68K_INS_MOVEM, 2);
2635 }
2636 
d68000_movem_pd_32(m68k_info * info)2637 static void d68000_movem_pd_32(m68k_info *info)
2638 {
2639 	build_movem_re(info, M68K_INS_MOVEM, 4);
2640 }
2641 
d68000_movem_er_16(m68k_info * info)2642 static void d68000_movem_er_16(m68k_info *info)
2643 {
2644 	build_movem_er(info, M68K_INS_MOVEM, 2);
2645 }
2646 
d68000_movem_er_32(m68k_info * info)2647 static void d68000_movem_er_32(m68k_info *info)
2648 {
2649 	build_movem_er(info, M68K_INS_MOVEM, 4);
2650 }
2651 
d68000_movem_re_16(m68k_info * info)2652 static void d68000_movem_re_16(m68k_info *info)
2653 {
2654 	build_movem_re(info, M68K_INS_MOVEM, 2);
2655 }
2656 
d68000_movem_re_32(m68k_info * info)2657 static void d68000_movem_re_32(m68k_info *info)
2658 {
2659 	build_movem_re(info, M68K_INS_MOVEM, 4);
2660 }
2661 
d68000_movep_re_16(m68k_info * info)2662 static void d68000_movep_re_16(m68k_info *info)
2663 {
2664 	build_movep_re(info, 2);
2665 }
2666 
d68000_movep_re_32(m68k_info * info)2667 static void d68000_movep_re_32(m68k_info *info)
2668 {
2669 	build_movep_re(info, 4);
2670 }
2671 
d68000_movep_er_16(m68k_info * info)2672 static void d68000_movep_er_16(m68k_info *info)
2673 {
2674 	build_movep_er(info, 2);
2675 }
2676 
d68000_movep_er_32(m68k_info * info)2677 static void d68000_movep_er_32(m68k_info *info)
2678 {
2679 	build_movep_er(info, 4);
2680 }
2681 
d68010_moves_8(m68k_info * info)2682 static void d68010_moves_8(m68k_info *info)
2683 {
2684 	LIMIT_CPU_TYPES(info, M68010_PLUS);
2685 	build_moves(info, 1);
2686 }
2687 
d68010_moves_16(m68k_info * info)2688 static void d68010_moves_16(m68k_info *info)
2689 {
2690 	//uint extension;
2691 	LIMIT_CPU_TYPES(info, M68010_PLUS);
2692 	build_moves(info, 2);
2693 }
2694 
d68010_moves_32(m68k_info * info)2695 static void d68010_moves_32(m68k_info *info)
2696 {
2697 	LIMIT_CPU_TYPES(info, M68010_PLUS);
2698 	build_moves(info, 4);
2699 }
2700 
d68000_moveq(m68k_info * info)2701 static void d68000_moveq(m68k_info *info)
2702 {
2703 	cs_m68k_op* op0;
2704 	cs_m68k_op* op1;
2705 
2706 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVEQ, 2, 0);
2707 
2708 	op0 = &ext->operands[0];
2709 	op1 = &ext->operands[1];
2710 
2711 	op0->type = M68K_OP_IMM;
2712 	op0->address_mode = M68K_AM_IMMEDIATE;
2713 	op0->imm = (info->ir & 0xff);
2714 
2715 	op1->address_mode = M68K_AM_REG_DIRECT_DATA;
2716 	op1->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
2717 }
2718 
d68040_move16_pi_pi(m68k_info * info)2719 static void d68040_move16_pi_pi(m68k_info *info)
2720 {
2721 	int data[] = { info->ir & 7, (read_imm_16(info) >> 12) & 7 };
2722 	int modes[] = { M68K_AM_REGI_ADDR_POST_INC, M68K_AM_REGI_ADDR_POST_INC };
2723 
2724 	LIMIT_CPU_TYPES(info, M68040_PLUS);
2725 
2726 	build_move16(info, data, modes);
2727 }
2728 
d68040_move16_pi_al(m68k_info * info)2729 static void d68040_move16_pi_al(m68k_info *info)
2730 {
2731 	int data[] = { info->ir & 7, read_imm_32(info) };
2732 	int modes[] = { M68K_AM_REGI_ADDR_POST_INC, M68K_AM_ABSOLUTE_DATA_LONG };
2733 
2734 	LIMIT_CPU_TYPES(info, M68040_PLUS);
2735 
2736 	build_move16(info, data, modes);
2737 }
2738 
d68040_move16_al_pi(m68k_info * info)2739 static void d68040_move16_al_pi(m68k_info *info)
2740 {
2741 	int data[] = { read_imm_32(info), info->ir & 7 };
2742 	int modes[] = { M68K_AM_ABSOLUTE_DATA_LONG, M68K_AM_REGI_ADDR_POST_INC };
2743 
2744 	LIMIT_CPU_TYPES(info, M68040_PLUS);
2745 
2746 	build_move16(info, data, modes);
2747 }
2748 
d68040_move16_ai_al(m68k_info * info)2749 static void d68040_move16_ai_al(m68k_info *info)
2750 {
2751 	int data[] = { info->ir & 7, read_imm_32(info) };
2752 	int modes[] = { M68K_AM_REG_DIRECT_ADDR, M68K_AM_ABSOLUTE_DATA_LONG };
2753 
2754 	LIMIT_CPU_TYPES(info, M68040_PLUS);
2755 
2756 	build_move16(info, data, modes);
2757 }
2758 
d68040_move16_al_ai(m68k_info * info)2759 static void d68040_move16_al_ai(m68k_info *info)
2760 {
2761 	int data[] = { read_imm_32(info), info->ir & 7 };
2762 	int modes[] = { M68K_AM_ABSOLUTE_DATA_LONG, M68K_AM_REG_DIRECT_ADDR };
2763 
2764 	LIMIT_CPU_TYPES(info, M68040_PLUS);
2765 
2766 	build_move16(info, data, modes);
2767 }
2768 
d68000_muls(m68k_info * info)2769 static void d68000_muls(m68k_info *info)
2770 {
2771 	build_er_1(info, M68K_INS_MULS, 2);
2772 }
2773 
d68000_mulu(m68k_info * info)2774 static void d68000_mulu(m68k_info *info)
2775 {
2776 	build_er_1(info, M68K_INS_MULU, 2);
2777 }
2778 
d68020_mull(m68k_info * info)2779 static void d68020_mull(m68k_info *info)
2780 {
2781 	uint extension, insn_signed;
2782 	cs_m68k* ext;
2783 	cs_m68k_op* op0;
2784 	cs_m68k_op* op1;
2785 	uint reg_0, reg_1;
2786 
2787 
2788 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2789 
2790 	extension = read_imm_16(info);
2791 	insn_signed = 0;
2792 
2793 	if (BIT_B((extension)))
2794 		insn_signed = 1;
2795 
2796 	ext = build_init_op(info, insn_signed ? M68K_INS_MULS : M68K_INS_MULU, 2, 4);
2797 
2798 	op0 = &ext->operands[0];
2799 	op1 = &ext->operands[1];
2800 
2801 	get_ea_mode_op(info, op0, info->ir, 4);
2802 
2803 	reg_0 = extension & 7;
2804 	reg_1 = (extension >> 12) & 7;
2805 
2806 	op1->address_mode = M68K_AM_NONE;
2807 	op1->type = M68K_OP_REG_PAIR;
2808 	op1->reg_pair.reg_0 = reg_0;
2809 	op1->reg_pair.reg_1 = reg_1;
2810 
2811 	if (!BIT_A(extension)) {
2812 		op1->type = M68K_OP_REG;
2813 		op1->reg = M68K_REG_D0 + reg_1;
2814 	}
2815 }
2816 
d68000_nbcd(m68k_info * info)2817 static void d68000_nbcd(m68k_info *info)
2818 {
2819 	build_ea(info, M68K_INS_NBCD, 1);
2820 }
2821 
d68000_neg_8(m68k_info * info)2822 static void d68000_neg_8(m68k_info *info)
2823 {
2824 	build_ea(info, M68K_INS_NEG, 1);
2825 }
2826 
d68000_neg_16(m68k_info * info)2827 static void d68000_neg_16(m68k_info *info)
2828 {
2829 	build_ea(info, M68K_INS_NEG, 2);
2830 }
2831 
d68000_neg_32(m68k_info * info)2832 static void d68000_neg_32(m68k_info *info)
2833 {
2834 	build_ea(info, M68K_INS_NEG, 4);
2835 }
2836 
d68000_negx_8(m68k_info * info)2837 static void d68000_negx_8(m68k_info *info)
2838 {
2839 	build_ea(info, M68K_INS_NEGX, 1);
2840 }
2841 
d68000_negx_16(m68k_info * info)2842 static void d68000_negx_16(m68k_info *info)
2843 {
2844 	build_ea(info, M68K_INS_NEGX, 2);
2845 }
2846 
d68000_negx_32(m68k_info * info)2847 static void d68000_negx_32(m68k_info *info)
2848 {
2849 	build_ea(info, M68K_INS_NEGX, 4);
2850 }
2851 
d68000_nop(m68k_info * info)2852 static void d68000_nop(m68k_info *info)
2853 {
2854 	MCInst_setOpcode(info->inst, M68K_INS_NOP);
2855 }
2856 
d68000_not_8(m68k_info * info)2857 static void d68000_not_8(m68k_info *info)
2858 {
2859 	build_ea(info, M68K_INS_NOT, 1);
2860 }
2861 
d68000_not_16(m68k_info * info)2862 static void d68000_not_16(m68k_info *info)
2863 {
2864 	build_ea(info, M68K_INS_NOT, 2);
2865 }
2866 
d68000_not_32(m68k_info * info)2867 static void d68000_not_32(m68k_info *info)
2868 {
2869 	build_ea(info, M68K_INS_NOT, 4);
2870 }
2871 
d68000_or_er_8(m68k_info * info)2872 static void d68000_or_er_8(m68k_info *info)
2873 {
2874 	build_er_1(info, M68K_INS_OR, 1);
2875 }
2876 
d68000_or_er_16(m68k_info * info)2877 static void d68000_or_er_16(m68k_info *info)
2878 {
2879 	build_er_1(info, M68K_INS_OR, 2);
2880 }
2881 
d68000_or_er_32(m68k_info * info)2882 static void d68000_or_er_32(m68k_info *info)
2883 {
2884 	build_er_1(info, M68K_INS_OR, 4);
2885 }
2886 
d68000_or_re_8(m68k_info * info)2887 static void d68000_or_re_8(m68k_info *info)
2888 {
2889 	build_re_1(info, M68K_INS_OR, 1);
2890 }
2891 
d68000_or_re_16(m68k_info * info)2892 static void d68000_or_re_16(m68k_info *info)
2893 {
2894 	build_re_1(info, M68K_INS_OR, 2);
2895 }
2896 
d68000_or_re_32(m68k_info * info)2897 static void d68000_or_re_32(m68k_info *info)
2898 {
2899 	build_re_1(info, M68K_INS_OR, 4);
2900 }
2901 
d68000_ori_8(m68k_info * info)2902 static void d68000_ori_8(m68k_info *info)
2903 {
2904 	build_imm_ea(info, M68K_INS_ORI, 1, read_imm_8(info));
2905 }
2906 
d68000_ori_16(m68k_info * info)2907 static void d68000_ori_16(m68k_info *info)
2908 {
2909 	build_imm_ea(info, M68K_INS_ORI, 2, read_imm_16(info));
2910 }
2911 
d68000_ori_32(m68k_info * info)2912 static void d68000_ori_32(m68k_info *info)
2913 {
2914 	build_imm_ea(info, M68K_INS_ORI, 4, read_imm_32(info));
2915 }
2916 
d68000_ori_to_ccr(m68k_info * info)2917 static void d68000_ori_to_ccr(m68k_info *info)
2918 {
2919 	build_imm_special_reg(info, M68K_INS_ORI, read_imm_8(info), 1, M68K_REG_CCR);
2920 }
2921 
d68000_ori_to_sr(m68k_info * info)2922 static void d68000_ori_to_sr(m68k_info *info)
2923 {
2924 	build_imm_special_reg(info, M68K_INS_ORI, read_imm_16(info), 2, M68K_REG_SR);
2925 }
2926 
d68020_pack_rr(m68k_info * info)2927 static void d68020_pack_rr(m68k_info *info)
2928 {
2929 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2930 	build_rr(info, M68K_INS_PACK, 0, read_imm_16(info));
2931 }
2932 
d68020_pack_mm(m68k_info * info)2933 static void d68020_pack_mm(m68k_info *info)
2934 {
2935 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2936 	build_mm(info, M68K_INS_PACK, 0, read_imm_16(info));
2937 }
2938 
d68000_pea(m68k_info * info)2939 static void d68000_pea(m68k_info *info)
2940 {
2941 	build_ea(info, M68K_INS_PEA, 4);
2942 }
2943 
d68000_reset(m68k_info * info)2944 static void d68000_reset(m68k_info *info)
2945 {
2946 	MCInst_setOpcode(info->inst, M68K_INS_RESET);
2947 }
2948 
d68000_ror_s_8(m68k_info * info)2949 static void d68000_ror_s_8(m68k_info *info)
2950 {
2951 	build_3bit_d(info, M68K_INS_ROR, 1);
2952 }
2953 
d68000_ror_s_16(m68k_info * info)2954 static void d68000_ror_s_16(m68k_info *info)
2955 {
2956 	build_3bit_d(info, M68K_INS_ROR, 2);
2957 }
2958 
d68000_ror_s_32(m68k_info * info)2959 static void d68000_ror_s_32(m68k_info *info)
2960 {
2961 	build_3bit_d(info, M68K_INS_ROR, 4);
2962 }
2963 
d68000_ror_r_8(m68k_info * info)2964 static void d68000_ror_r_8(m68k_info *info)
2965 {
2966 	build_r(info, M68K_INS_ROR, 1);
2967 }
2968 
d68000_ror_r_16(m68k_info * info)2969 static void d68000_ror_r_16(m68k_info *info)
2970 {
2971 	build_r(info, M68K_INS_ROR, 2);
2972 }
2973 
d68000_ror_r_32(m68k_info * info)2974 static void d68000_ror_r_32(m68k_info *info)
2975 {
2976 	build_r(info, M68K_INS_ROR, 4);
2977 }
2978 
d68000_ror_ea(m68k_info * info)2979 static void d68000_ror_ea(m68k_info *info)
2980 {
2981 	build_ea(info, M68K_INS_ROR, 2);
2982 }
2983 
d68000_rol_s_8(m68k_info * info)2984 static void d68000_rol_s_8(m68k_info *info)
2985 {
2986 	build_3bit_d(info, M68K_INS_ROL, 1);
2987 }
2988 
d68000_rol_s_16(m68k_info * info)2989 static void d68000_rol_s_16(m68k_info *info)
2990 {
2991 	build_3bit_d(info, M68K_INS_ROL, 2);
2992 }
2993 
d68000_rol_s_32(m68k_info * info)2994 static void d68000_rol_s_32(m68k_info *info)
2995 {
2996 	build_3bit_d(info, M68K_INS_ROL, 4);
2997 }
2998 
d68000_rol_r_8(m68k_info * info)2999 static void d68000_rol_r_8(m68k_info *info)
3000 {
3001 	build_r(info, M68K_INS_ROL, 1);
3002 }
3003 
d68000_rol_r_16(m68k_info * info)3004 static void d68000_rol_r_16(m68k_info *info)
3005 {
3006 	build_r(info, M68K_INS_ROL, 2);
3007 }
3008 
d68000_rol_r_32(m68k_info * info)3009 static void d68000_rol_r_32(m68k_info *info)
3010 {
3011 	build_r(info, M68K_INS_ROL, 4);
3012 }
3013 
d68000_rol_ea(m68k_info * info)3014 static void d68000_rol_ea(m68k_info *info)
3015 {
3016 	build_ea(info, M68K_INS_ROL, 2);
3017 }
3018 
d68000_roxr_s_8(m68k_info * info)3019 static void d68000_roxr_s_8(m68k_info *info)
3020 {
3021 	build_3bit_d(info, M68K_INS_ROXR, 1);
3022 }
3023 
d68000_roxr_s_16(m68k_info * info)3024 static void d68000_roxr_s_16(m68k_info *info)
3025 {
3026 	build_3bit_d(info, M68K_INS_ROXR, 2);
3027 }
3028 
d68000_roxr_s_32(m68k_info * info)3029 static void d68000_roxr_s_32(m68k_info *info)
3030 {
3031 	build_3bit_d(info, M68K_INS_ROXR, 4);
3032 }
3033 
d68000_roxr_r_8(m68k_info * info)3034 static void d68000_roxr_r_8(m68k_info *info)
3035 {
3036 	build_3bit_d(info, M68K_INS_ROXR, 4);
3037 }
3038 
d68000_roxr_r_16(m68k_info * info)3039 static void d68000_roxr_r_16(m68k_info *info)
3040 {
3041 	build_r(info, M68K_INS_ROXR, 2);
3042 }
3043 
d68000_roxr_r_32(m68k_info * info)3044 static void d68000_roxr_r_32(m68k_info *info)
3045 {
3046 	build_r(info, M68K_INS_ROXR, 4);
3047 }
3048 
d68000_roxr_ea(m68k_info * info)3049 static void d68000_roxr_ea(m68k_info *info)
3050 {
3051 	build_ea(info, M68K_INS_ROXR, 2);
3052 }
3053 
d68000_roxl_s_8(m68k_info * info)3054 static void d68000_roxl_s_8(m68k_info *info)
3055 {
3056 	build_3bit_d(info, M68K_INS_ROXL, 1);
3057 }
3058 
d68000_roxl_s_16(m68k_info * info)3059 static void d68000_roxl_s_16(m68k_info *info)
3060 {
3061 	build_3bit_d(info, M68K_INS_ROXL, 2);
3062 }
3063 
d68000_roxl_s_32(m68k_info * info)3064 static void d68000_roxl_s_32(m68k_info *info)
3065 {
3066 	build_3bit_d(info, M68K_INS_ROXL, 4);
3067 }
3068 
d68000_roxl_r_8(m68k_info * info)3069 static void d68000_roxl_r_8(m68k_info *info)
3070 {
3071 	build_r(info, M68K_INS_ROXL, 1);
3072 }
3073 
d68000_roxl_r_16(m68k_info * info)3074 static void d68000_roxl_r_16(m68k_info *info)
3075 {
3076 	build_r(info, M68K_INS_ROXL, 2);
3077 }
3078 
d68000_roxl_r_32(m68k_info * info)3079 static void d68000_roxl_r_32(m68k_info *info)
3080 {
3081 	build_r(info, M68K_INS_ROXL, 4);
3082 }
3083 
d68000_roxl_ea(m68k_info * info)3084 static void d68000_roxl_ea(m68k_info *info)
3085 {
3086 	build_ea(info, M68K_INS_ROXL, 2);
3087 }
3088 
d68010_rtd(m68k_info * info)3089 static void d68010_rtd(m68k_info *info)
3090 {
3091 	set_insn_group(info, M68K_GRP_RET);
3092 	LIMIT_CPU_TYPES(info, M68010_PLUS);
3093 	build_absolute_jump_with_immediate(info, M68K_INS_RTD, 0, read_imm_16(info));
3094 }
3095 
d68000_rte(m68k_info * info)3096 static void d68000_rte(m68k_info *info)
3097 {
3098 	set_insn_group(info, M68K_GRP_IRET);
3099 	MCInst_setOpcode(info->inst, M68K_INS_RTE);
3100 }
3101 
d68020_rtm(m68k_info * info)3102 static void d68020_rtm(m68k_info *info)
3103 {
3104 	cs_m68k* ext;
3105 	cs_m68k_op* op;
3106 
3107 	set_insn_group(info, M68K_GRP_RET);
3108 
3109 	LIMIT_CPU_TYPES(info, M68020_ONLY);
3110 
3111 	build_absolute_jump_with_immediate(info, M68K_INS_RTM, 0, 0);
3112 
3113 	ext = &info->extension;
3114 	op = &ext->operands[0];
3115 
3116 	op->address_mode = M68K_AM_NONE;
3117 	op->type = M68K_OP_REG;
3118 
3119 	if (BIT_3(info->ir)) {
3120 		op->reg = M68K_REG_A0 + (info->ir & 7);
3121 	} else {
3122 		op->reg = M68K_REG_D0 + (info->ir & 7);
3123 	}
3124 }
3125 
d68000_rtr(m68k_info * info)3126 static void d68000_rtr(m68k_info *info)
3127 {
3128 	set_insn_group(info, M68K_GRP_RET);
3129 	MCInst_setOpcode(info->inst, M68K_INS_RTR);
3130 }
3131 
d68000_rts(m68k_info * info)3132 static void d68000_rts(m68k_info *info)
3133 {
3134 	set_insn_group(info, M68K_GRP_RET);
3135 	MCInst_setOpcode(info->inst, M68K_INS_RTS);
3136 }
3137 
d68000_sbcd_rr(m68k_info * info)3138 static void d68000_sbcd_rr(m68k_info *info)
3139 {
3140 	build_rr(info, M68K_INS_SBCD, 1, 0);
3141 }
3142 
d68000_sbcd_mm(m68k_info * info)3143 static void d68000_sbcd_mm(m68k_info *info)
3144 {
3145 	build_mm(info, M68K_INS_SBCD, 0, read_imm_16(info));
3146 }
3147 
d68000_scc(m68k_info * info)3148 static void d68000_scc(m68k_info *info)
3149 {
3150 	cs_m68k* ext = build_init_op(info, s_scc_lut[(info->ir >> 8) & 0xf], 1, 1);
3151 	get_ea_mode_op(info, &ext->operands[0], info->ir, 1);
3152 }
3153 
d68000_stop(m68k_info * info)3154 static void d68000_stop(m68k_info *info)
3155 {
3156 	build_absolute_jump_with_immediate(info, M68K_INS_STOP, 0, read_imm_16(info));
3157 }
3158 
d68000_sub_er_8(m68k_info * info)3159 static void d68000_sub_er_8(m68k_info *info)
3160 {
3161 	build_er_1(info, M68K_INS_SUB, 1);
3162 }
3163 
d68000_sub_er_16(m68k_info * info)3164 static void d68000_sub_er_16(m68k_info *info)
3165 {
3166 	build_er_1(info, M68K_INS_SUB, 2);
3167 }
3168 
d68000_sub_er_32(m68k_info * info)3169 static void d68000_sub_er_32(m68k_info *info)
3170 {
3171 	build_er_1(info, M68K_INS_SUB, 4);
3172 }
3173 
d68000_sub_re_8(m68k_info * info)3174 static void d68000_sub_re_8(m68k_info *info)
3175 {
3176 	build_re_1(info, M68K_INS_SUB, 1);
3177 }
3178 
d68000_sub_re_16(m68k_info * info)3179 static void d68000_sub_re_16(m68k_info *info)
3180 {
3181 	build_re_1(info, M68K_INS_SUB, 2);
3182 }
3183 
d68000_sub_re_32(m68k_info * info)3184 static void d68000_sub_re_32(m68k_info *info)
3185 {
3186 	build_re_1(info, M68K_INS_SUB, 4);
3187 }
3188 
d68000_suba_16(m68k_info * info)3189 static void d68000_suba_16(m68k_info *info)
3190 {
3191 	build_ea_a(info, M68K_INS_SUBA, 2);
3192 }
3193 
d68000_suba_32(m68k_info * info)3194 static void d68000_suba_32(m68k_info *info)
3195 {
3196 	build_ea_a(info, M68K_INS_SUBA, 4);
3197 }
3198 
d68000_subi_8(m68k_info * info)3199 static void d68000_subi_8(m68k_info *info)
3200 {
3201 	build_imm_ea(info, M68K_INS_SUBI, 1, read_imm_8(info));
3202 }
3203 
d68000_subi_16(m68k_info * info)3204 static void d68000_subi_16(m68k_info *info)
3205 {
3206 	build_imm_ea(info, M68K_INS_SUBI, 2, read_imm_16(info));
3207 }
3208 
d68000_subi_32(m68k_info * info)3209 static void d68000_subi_32(m68k_info *info)
3210 {
3211 	build_imm_ea(info, M68K_INS_SUBI, 4, read_imm_32(info));
3212 }
3213 
d68000_subq_8(m68k_info * info)3214 static void d68000_subq_8(m68k_info *info)
3215 {
3216 	build_3bit_ea(info, M68K_INS_SUBQ, 1);
3217 }
3218 
d68000_subq_16(m68k_info * info)3219 static void d68000_subq_16(m68k_info *info)
3220 {
3221 	build_3bit_ea(info, M68K_INS_SUBQ, 2);
3222 }
3223 
d68000_subq_32(m68k_info * info)3224 static void d68000_subq_32(m68k_info *info)
3225 {
3226 	build_3bit_ea(info, M68K_INS_SUBQ, 4);
3227 }
3228 
d68000_subx_rr_8(m68k_info * info)3229 static void d68000_subx_rr_8(m68k_info *info)
3230 {
3231 	build_rr(info, M68K_INS_SUBX, 1, 0);
3232 }
3233 
d68000_subx_rr_16(m68k_info * info)3234 static void d68000_subx_rr_16(m68k_info *info)
3235 {
3236 	build_rr(info, M68K_INS_SUBX, 2, 0);
3237 }
3238 
d68000_subx_rr_32(m68k_info * info)3239 static void d68000_subx_rr_32(m68k_info *info)
3240 {
3241 	build_rr(info, M68K_INS_SUBX, 4, 0);
3242 }
3243 
d68000_subx_mm_8(m68k_info * info)3244 static void d68000_subx_mm_8(m68k_info *info)
3245 {
3246 	build_mm(info, M68K_INS_SUBX, 1, 0);
3247 }
3248 
d68000_subx_mm_16(m68k_info * info)3249 static void d68000_subx_mm_16(m68k_info *info)
3250 {
3251 	build_mm(info, M68K_INS_SUBX, 2, 0);
3252 }
3253 
d68000_subx_mm_32(m68k_info * info)3254 static void d68000_subx_mm_32(m68k_info *info)
3255 {
3256 	build_mm(info, M68K_INS_SUBX, 4, 0);
3257 }
3258 
d68000_swap(m68k_info * info)3259 static void d68000_swap(m68k_info *info)
3260 {
3261 	build_d(info, M68K_INS_SWAP, 0);
3262 }
3263 
d68000_tas(m68k_info * info)3264 static void d68000_tas(m68k_info *info)
3265 {
3266 	build_ea(info, M68K_INS_TAS, 1);
3267 }
3268 
d68000_trap(m68k_info * info)3269 static void d68000_trap(m68k_info *info)
3270 {
3271 	build_absolute_jump_with_immediate(info, M68K_INS_TRAP, 0, info->ir&0xf);
3272 }
3273 
d68020_trapcc_0(m68k_info * info)3274 static void d68020_trapcc_0(m68k_info *info)
3275 {
3276 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3277 	build_trap(info, 0, 0);
3278 
3279 	info->extension.op_count = 0;
3280 }
3281 
d68020_trapcc_16(m68k_info * info)3282 static void d68020_trapcc_16(m68k_info *info)
3283 {
3284 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3285 	build_trap(info, 2, read_imm_16(info));
3286 }
3287 
d68020_trapcc_32(m68k_info * info)3288 static void d68020_trapcc_32(m68k_info *info)
3289 {
3290 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3291 	build_trap(info, 4, read_imm_32(info));
3292 }
3293 
d68000_trapv(m68k_info * info)3294 static void d68000_trapv(m68k_info *info)
3295 {
3296 	MCInst_setOpcode(info->inst, M68K_INS_TRAPV);
3297 }
3298 
d68000_tst_8(m68k_info * info)3299 static void d68000_tst_8(m68k_info *info)
3300 {
3301 	build_ea(info, M68K_INS_TST, 1);
3302 }
3303 
d68020_tst_pcdi_8(m68k_info * info)3304 static void d68020_tst_pcdi_8(m68k_info *info)
3305 {
3306 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3307 	build_ea(info, M68K_INS_TST, 1);
3308 }
3309 
d68020_tst_pcix_8(m68k_info * info)3310 static void d68020_tst_pcix_8(m68k_info *info)
3311 {
3312 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3313 	build_ea(info, M68K_INS_TST, 1);
3314 }
3315 
d68020_tst_i_8(m68k_info * info)3316 static void d68020_tst_i_8(m68k_info *info)
3317 {
3318 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3319 	build_ea(info, M68K_INS_TST, 1);
3320 }
3321 
d68000_tst_16(m68k_info * info)3322 static void d68000_tst_16(m68k_info *info)
3323 {
3324 	build_ea(info, M68K_INS_TST, 2);
3325 }
3326 
d68020_tst_a_16(m68k_info * info)3327 static void d68020_tst_a_16(m68k_info *info)
3328 {
3329 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3330 	build_ea(info, M68K_INS_TST, 2);
3331 }
3332 
d68020_tst_pcdi_16(m68k_info * info)3333 static void d68020_tst_pcdi_16(m68k_info *info)
3334 {
3335 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3336 	build_ea(info, M68K_INS_TST, 2);
3337 }
3338 
d68020_tst_pcix_16(m68k_info * info)3339 static void d68020_tst_pcix_16(m68k_info *info)
3340 {
3341 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3342 	build_ea(info, M68K_INS_TST, 2);
3343 }
3344 
d68020_tst_i_16(m68k_info * info)3345 static void d68020_tst_i_16(m68k_info *info)
3346 {
3347 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3348 	build_ea(info, M68K_INS_TST, 2);
3349 }
3350 
d68000_tst_32(m68k_info * info)3351 static void d68000_tst_32(m68k_info *info)
3352 {
3353 	build_ea(info, M68K_INS_TST, 4);
3354 }
3355 
d68020_tst_a_32(m68k_info * info)3356 static void d68020_tst_a_32(m68k_info *info)
3357 {
3358 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3359 	build_ea(info, M68K_INS_TST, 4);
3360 }
3361 
d68020_tst_pcdi_32(m68k_info * info)3362 static void d68020_tst_pcdi_32(m68k_info *info)
3363 {
3364 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3365 	build_ea(info, M68K_INS_TST, 4);
3366 }
3367 
d68020_tst_pcix_32(m68k_info * info)3368 static void d68020_tst_pcix_32(m68k_info *info)
3369 {
3370 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3371 	build_ea(info, M68K_INS_TST, 4);
3372 }
3373 
d68020_tst_i_32(m68k_info * info)3374 static void d68020_tst_i_32(m68k_info *info)
3375 {
3376 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3377 	build_ea(info, M68K_INS_TST, 4);
3378 }
3379 
d68000_unlk(m68k_info * info)3380 static void d68000_unlk(m68k_info *info)
3381 {
3382 	cs_m68k_op* op;
3383 	cs_m68k* ext = build_init_op(info, M68K_INS_UNLK, 1, 0);
3384 
3385 	op = &ext->operands[0];
3386 
3387 	op->address_mode = M68K_AM_REG_DIRECT_ADDR;
3388 	op->reg = M68K_REG_A0 + (info->ir & 7);
3389 }
3390 
d68020_unpk_rr(m68k_info * info)3391 static void d68020_unpk_rr(m68k_info *info)
3392 {
3393 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3394 	build_rr(info, M68K_INS_UNPK, 0, read_imm_16(info));
3395 }
3396 
d68020_unpk_mm(m68k_info * info)3397 static void d68020_unpk_mm(m68k_info *info)
3398 {
3399 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3400 	build_mm(info, M68K_INS_UNPK, 0, read_imm_16(info));
3401 }
3402 
3403 /* ======================================================================== */
3404 /* ======================= INSTRUCTION TABLE BUILDER ====================== */
3405 /* ======================================================================== */
3406 
3407 /* EA Masks:
3408    800 = data register direct
3409    400 = address register direct
3410    200 = address register indirect
3411    100 = ARI postincrement
3412    80 = ARI pre-decrement
3413    40 = ARI displacement
3414    20 = ARI index
3415    10 = absolute short
3416    8 = absolute long
3417    4 = immediate / sr
3418    2 = pc displacement
3419    1 = pc idx
3420  */
3421 
3422 static opcode_struct g_opcode_info[] = {
3423 	/*  opcode handler         mask    match   ea_mask   mask2   match2*/
3424 	{d68000_1010         , 0xf000, 0xa000, 0x000},
3425 	{d68000_1111         , 0xf000, 0xf000, 0x000},
3426 	{d68000_abcd_rr      , 0xf1f8, 0xc100, 0x000},
3427 	{d68000_abcd_mm      , 0xf1f8, 0xc108, 0x000},
3428 	{d68000_add_er_8     , 0xf1c0, 0xd000, 0xbff},
3429 	{d68000_add_er_16    , 0xf1c0, 0xd040, 0xfff},
3430 	{d68000_add_er_32    , 0xf1c0, 0xd080, 0xfff},
3431 	{d68000_add_re_8     , 0xf1c0, 0xd100, 0x3f8},
3432 	{d68000_add_re_16    , 0xf1c0, 0xd140, 0x3f8},
3433 	{d68000_add_re_32    , 0xf1c0, 0xd180, 0x3f8},
3434 	{d68000_adda_16      , 0xf1c0, 0xd0c0, 0xfff},
3435 	{d68000_adda_32      , 0xf1c0, 0xd1c0, 0xfff},
3436 	{d68000_addi_8       , 0xffc0, 0x0600, 0xbf8},
3437 	{d68000_addi_16      , 0xffc0, 0x0640, 0xbf8},
3438 	{d68000_addi_32      , 0xffc0, 0x0680, 0xbf8},
3439 	{d68000_addq_8       , 0xf1c0, 0x5000, 0xbf8},
3440 	{d68000_addq_16      , 0xf1c0, 0x5040, 0xff8},
3441 	{d68000_addq_32      , 0xf1c0, 0x5080, 0xff8},
3442 	{d68000_addx_rr_8    , 0xf1f8, 0xd100, 0x000},
3443 	{d68000_addx_rr_16   , 0xf1f8, 0xd140, 0x000},
3444 	{d68000_addx_rr_32   , 0xf1f8, 0xd180, 0x000},
3445 	{d68000_addx_mm_8    , 0xf1f8, 0xd108, 0x000},
3446 	{d68000_addx_mm_16   , 0xf1f8, 0xd148, 0x000},
3447 	{d68000_addx_mm_32   , 0xf1f8, 0xd188, 0x000},
3448 	{d68000_and_er_8     , 0xf1c0, 0xc000, 0xbff},
3449 	{d68000_and_er_16    , 0xf1c0, 0xc040, 0xbff},
3450 	{d68000_and_er_32    , 0xf1c0, 0xc080, 0xbff},
3451 	{d68000_and_re_8     , 0xf1c0, 0xc100, 0x3f8},
3452 	{d68000_and_re_16    , 0xf1c0, 0xc140, 0x3f8},
3453 	{d68000_and_re_32    , 0xf1c0, 0xc180, 0x3f8},
3454 	{d68000_andi_to_ccr  , 0xffff, 0x023c, 0x000, 0xff00, 0x0000},
3455 	{d68000_andi_to_sr   , 0xffff, 0x027c, 0x000},
3456 	{d68000_andi_8       , 0xffc0, 0x0200, 0xbf8},
3457 	{d68000_andi_16      , 0xffc0, 0x0240, 0xbf8},
3458 	{d68000_andi_32      , 0xffc0, 0x0280, 0xbf8},
3459 	{d68000_asr_s_8      , 0xf1f8, 0xe000, 0x000},
3460 	{d68000_asr_s_16     , 0xf1f8, 0xe040, 0x000},
3461 	{d68000_asr_s_32     , 0xf1f8, 0xe080, 0x000},
3462 	{d68000_asr_r_8      , 0xf1f8, 0xe020, 0x000},
3463 	{d68000_asr_r_16     , 0xf1f8, 0xe060, 0x000},
3464 	{d68000_asr_r_32     , 0xf1f8, 0xe0a0, 0x000},
3465 	{d68000_asr_ea       , 0xffc0, 0xe0c0, 0x3f8},
3466 	{d68000_asl_s_8      , 0xf1f8, 0xe100, 0x000},
3467 	{d68000_asl_s_16     , 0xf1f8, 0xe140, 0x000},
3468 	{d68000_asl_s_32     , 0xf1f8, 0xe180, 0x000},
3469 	{d68000_asl_r_8      , 0xf1f8, 0xe120, 0x000},
3470 	{d68000_asl_r_16     , 0xf1f8, 0xe160, 0x000},
3471 	{d68000_asl_r_32     , 0xf1f8, 0xe1a0, 0x000},
3472 	{d68000_asl_ea       , 0xffc0, 0xe1c0, 0x3f8},
3473 	{d68000_bcc_8        , 0xf000, 0x6000, 0x000},
3474 	{d68000_bcc_16       , 0xf0ff, 0x6000, 0x000},
3475 	{d68020_bcc_32       , 0xf0ff, 0x60ff, 0x000},
3476 	{d68000_bchg_r       , 0xf1c0, 0x0140, 0xbf8},
3477 	{d68000_bchg_s       , 0xffc0, 0x0840, 0xbf8, 0xff00, 0x0000},
3478 	{d68000_bclr_r       , 0xf1c0, 0x0180, 0xbf8},
3479 	{d68000_bclr_s       , 0xffc0, 0x0880, 0xbf8, 0xff00, 0x0000},
3480 	{d68020_bfchg        , 0xffc0, 0xeac0, 0xa78, 0xf000, 0x0000},
3481 	{d68020_bfclr        , 0xffc0, 0xecc0, 0xa78, 0xf000, 0x0000},
3482 	{d68020_bfexts       , 0xffc0, 0xebc0, 0xa7b, 0x8000, 0x0000},
3483 	{d68020_bfextu       , 0xffc0, 0xe9c0, 0xa7b, 0x8000, 0x0000},
3484 	{d68020_bfffo        , 0xffc0, 0xedc0, 0xa7b, 0x8000, 0x0000},
3485 	{d68020_bfins        , 0xffc0, 0xefc0, 0xa78, 0x8000, 0x0000},
3486 	{d68020_bfset        , 0xffc0, 0xeec0, 0xa78, 0xf000, 0x0000},
3487 	{d68020_bftst        , 0xffc0, 0xe8c0, 0xa7b, 0xf000, 0x0000},
3488 	{d68010_bkpt         , 0xfff8, 0x4848, 0x000},
3489 	{d68000_bra_8        , 0xff00, 0x6000, 0x000},
3490 	{d68000_bra_16       , 0xffff, 0x6000, 0x000},
3491 	{d68020_bra_32       , 0xffff, 0x60ff, 0x000},
3492 	{d68000_bset_r       , 0xf1c0, 0x01c0, 0xbf8},
3493 	{d68000_bset_s       , 0xffc0, 0x08c0, 0xbf8, 0xfe00, 0x0000 },
3494 	{d68000_bsr_8        , 0xff00, 0x6100, 0x000},
3495 	{d68000_bsr_16       , 0xffff, 0x6100, 0x000},
3496 	{d68020_bsr_32       , 0xffff, 0x61ff, 0x000},
3497 	{d68000_btst_r       , 0xf1c0, 0x0100, 0xbff},
3498 	{d68000_btst_s       , 0xffc0, 0x0800, 0xbfb, 0xff00, 0x0000},
3499 	{d68020_callm        , 0xffc0, 0x06c0, 0x27b, 0xff00, 0x0000},
3500 	{d68020_cas_8        , 0xffc0, 0x0ac0, 0x3f8, 0xfe38, 0x0000},
3501 	{d68020_cas_16       , 0xffc0, 0x0cc0, 0x3f8, 0xfe38, 0x0000},
3502 	{d68020_cas_32       , 0xffc0, 0x0ec0, 0x3f8, 0xfe38, 0x0000},
3503 	{d68020_cas2_16      , 0xffff, 0x0cfc, 0x000, 0x0e38, 0x0000/*, 0x0e38, 0x0000 */},
3504 	{d68020_cas2_32      , 0xffff, 0x0efc, 0x000, 0x0e38, 0x0000/*, 0x0e38, 0x0000 */},
3505 	{d68000_chk_16       , 0xf1c0, 0x4180, 0xbff},
3506 	{d68020_chk_32       , 0xf1c0, 0x4100, 0xbff},
3507 	{d68020_chk2_cmp2_8  , 0xffc0, 0x00c0, 0x27b, 0x07ff, 0x0000},
3508 	{d68020_chk2_cmp2_16 , 0xffc0, 0x02c0, 0x27b, 0x07ff, 0x0000},
3509 	{d68020_chk2_cmp2_32 , 0xffc0, 0x04c0, 0x27b, 0x07ff, 0x0000},
3510 	{d68040_cinv         , 0xff20, 0xf400, 0x000},
3511 	{d68000_clr_8        , 0xffc0, 0x4200, 0xbf8},
3512 	{d68000_clr_16       , 0xffc0, 0x4240, 0xbf8},
3513 	{d68000_clr_32       , 0xffc0, 0x4280, 0xbf8},
3514 	{d68000_cmp_8        , 0xf1c0, 0xb000, 0xbff},
3515 	{d68000_cmp_16       , 0xf1c0, 0xb040, 0xfff},
3516 	{d68000_cmp_32       , 0xf1c0, 0xb080, 0xfff},
3517 	{d68000_cmpa_16      , 0xf1c0, 0xb0c0, 0xfff},
3518 	{d68000_cmpa_32      , 0xf1c0, 0xb1c0, 0xfff},
3519 	{d68000_cmpi_8       , 0xffc0, 0x0c00, 0xbf8},
3520 	{d68020_cmpi_pcdi_8  , 0xffff, 0x0c3a, 0x000},
3521 	{d68020_cmpi_pcix_8  , 0xffff, 0x0c3b, 0x000},
3522 	{d68000_cmpi_16      , 0xffc0, 0x0c40, 0xbf8},
3523 	{d68020_cmpi_pcdi_16 , 0xffff, 0x0c7a, 0x000},
3524 	{d68020_cmpi_pcix_16 , 0xffff, 0x0c7b, 0x000},
3525 	{d68000_cmpi_32      , 0xffc0, 0x0c80, 0xbf8},
3526 	{d68020_cmpi_pcdi_32 , 0xffff, 0x0cba, 0x000},
3527 	{d68020_cmpi_pcix_32 , 0xffff, 0x0cbb, 0x000},
3528 	{d68000_cmpm_8       , 0xf1f8, 0xb108, 0x000},
3529 	{d68000_cmpm_16      , 0xf1f8, 0xb148, 0x000},
3530 	{d68000_cmpm_32      , 0xf1f8, 0xb188, 0x000},
3531 	{d68020_cpbcc_16     , 0xf1c0, 0xf080, 0x000},
3532 	{d68020_cpbcc_32     , 0xf1c0, 0xf0c0, 0x000},
3533 	{d68020_cpdbcc       , 0xf1f8, 0xf048, 0x000},
3534 	{d68020_cpgen        , 0xf1c0, 0xf000, 0x000},
3535 	{d68020_cprestore    , 0xf1c0, 0xf140, 0x37f},
3536 	{d68020_cpsave       , 0xf1c0, 0xf100, 0x2f8},
3537 	{d68020_cpscc        , 0xf1c0, 0xf040, 0xbf8},
3538 	{d68020_cptrapcc_0   , 0xf1ff, 0xf07c, 0x000},
3539 	{d68020_cptrapcc_16  , 0xf1ff, 0xf07a, 0x000},
3540 	{d68020_cptrapcc_32  , 0xf1ff, 0xf07b, 0x000},
3541 	{d68040_cpush        , 0xff20, 0xf420, 0x000},
3542 	{d68000_dbcc         , 0xf0f8, 0x50c8, 0x000},
3543 	{d68000_dbra         , 0xfff8, 0x51c8, 0x000},
3544 	{d68000_divs         , 0xf1c0, 0x81c0, 0xbff},
3545 	{d68000_divu         , 0xf1c0, 0x80c0, 0xbff},
3546 	{d68020_divl         , 0xff80, 0x4c00, 0xbff, 0x83f8, 0x0000},
3547 	{d68000_eor_8        , 0xf1c0, 0xb100, 0xbf8},
3548 	{d68000_eor_16       , 0xf1c0, 0xb140, 0xbf8},
3549 	{d68000_eor_32       , 0xf1c0, 0xb180, 0xbf8},
3550 	{d68000_eori_to_ccr  , 0xffff, 0x0a3c, 0x000, 0xff00, 0x0000},
3551 	{d68000_eori_to_sr   , 0xffff, 0x0a7c, 0x000},
3552 	{d68000_eori_8       , 0xffc0, 0x0a00, 0xbf8},
3553 	{d68000_eori_16      , 0xffc0, 0x0a40, 0xbf8},
3554 	{d68000_eori_32      , 0xffc0, 0x0a80, 0xbf8},
3555 	{d68000_exg_dd       , 0xf1f8, 0xc140, 0x000},
3556 	{d68000_exg_aa       , 0xf1f8, 0xc148, 0x000},
3557 	{d68000_exg_da       , 0xf1f8, 0xc188, 0x000},
3558 	{d68020_extb_32      , 0xfff8, 0x49c0, 0x000},
3559 	{d68000_ext_16       , 0xfff8, 0x4880, 0x000},
3560 	{d68000_ext_32       , 0xfff8, 0x48c0, 0x000},
3561 	{d68000_illegal      , 0xffff, 0x4afc, 0x000},
3562 	{d68000_jmp          , 0xffc0, 0x4ec0, 0x27b},
3563 	{d68000_jsr          , 0xffc0, 0x4e80, 0x27b},
3564 	{d68000_lea          , 0xf1c0, 0x41c0, 0x27b},
3565 	{d68000_link_16      , 0xfff8, 0x4e50, 0x000},
3566 	{d68020_link_32      , 0xfff8, 0x4808, 0x000},
3567 	{d68000_lsr_s_8      , 0xf1f8, 0xe008, 0x000},
3568 	{d68000_lsr_s_16     , 0xf1f8, 0xe048, 0x000},
3569 	{d68000_lsr_s_32     , 0xf1f8, 0xe088, 0x000},
3570 	{d68000_lsr_r_8      , 0xf1f8, 0xe028, 0x000},
3571 	{d68000_lsr_r_16     , 0xf1f8, 0xe068, 0x000},
3572 	{d68000_lsr_r_32     , 0xf1f8, 0xe0a8, 0x000},
3573 	{d68000_lsr_ea       , 0xffc0, 0xe2c0, 0x3f8},
3574 	{d68000_lsl_s_8      , 0xf1f8, 0xe108, 0x000},
3575 	{d68000_lsl_s_16     , 0xf1f8, 0xe148, 0x000},
3576 	{d68000_lsl_s_32     , 0xf1f8, 0xe188, 0x000},
3577 	{d68000_lsl_r_8      , 0xf1f8, 0xe128, 0x000},
3578 	{d68000_lsl_r_16     , 0xf1f8, 0xe168, 0x000},
3579 	{d68000_lsl_r_32     , 0xf1f8, 0xe1a8, 0x000},
3580 	{d68000_lsl_ea       , 0xffc0, 0xe3c0, 0x3f8},
3581 	{d68000_move_8       , 0xf000, 0x1000, 0xbff},
3582 	{d68000_move_16      , 0xf000, 0x3000, 0xfff},
3583 	{d68000_move_32      , 0xf000, 0x2000, 0xfff},
3584 	{d68000_movea_16     , 0xf1c0, 0x3040, 0xfff},
3585 	{d68000_movea_32     , 0xf1c0, 0x2040, 0xfff},
3586 	{d68000_move_to_ccr  , 0xffc0, 0x44c0, 0xbff},
3587 	{d68010_move_fr_ccr  , 0xffc0, 0x42c0, 0xbf8},
3588 	{d68000_move_to_sr   , 0xffc0, 0x46c0, 0xbff},
3589 	{d68000_move_fr_sr   , 0xffc0, 0x40c0, 0xbf8},
3590 	{d68000_move_to_usp  , 0xfff8, 0x4e60, 0x000},
3591 	{d68000_move_fr_usp  , 0xfff8, 0x4e68, 0x000},
3592 	{d68010_movec        , 0xfffe, 0x4e7a, 0x000},
3593 	{d68000_movem_pd_16  , 0xfff8, 0x48a0, 0x000},
3594 	{d68000_movem_pd_32  , 0xfff8, 0x48e0, 0x000},
3595 	{d68000_movem_re_16  , 0xffc0, 0x4880, 0x2f8},
3596 	{d68000_movem_re_32  , 0xffc0, 0x48c0, 0x2f8},
3597 	{d68000_movem_er_16  , 0xffc0, 0x4c80, 0x37b},
3598 	{d68000_movem_er_32  , 0xffc0, 0x4cc0, 0x37b},
3599 	{d68000_movep_er_16  , 0xf1f8, 0x0108, 0x000},
3600 	{d68000_movep_er_32  , 0xf1f8, 0x0148, 0x000},
3601 	{d68000_movep_re_16  , 0xf1f8, 0x0188, 0x000},
3602 	{d68000_movep_re_32  , 0xf1f8, 0x01c8, 0x000},
3603 	{d68010_moves_8      , 0xffc0, 0x0e00, 0x3f8, 0x07ff, 0x0000},
3604 	{d68010_moves_16     , 0xffc0, 0x0e40, 0x3f8, 0x07ff, 0x0000},
3605 	{d68010_moves_32     , 0xffc0, 0x0e80, 0x3f8, 0x07ff, 0x0000},
3606 	{d68000_moveq        , 0xf100, 0x7000, 0x000},
3607 	{d68040_move16_pi_pi , 0xfff8, 0xf620, 0x000, 0x8fff, 0x8000},
3608 	{d68040_move16_pi_al , 0xfff8, 0xf600, 0x000},
3609 	{d68040_move16_al_pi , 0xfff8, 0xf608, 0x000},
3610 	{d68040_move16_ai_al , 0xfff8, 0xf610, 0x000},
3611 	{d68040_move16_al_ai , 0xfff8, 0xf618, 0x000},
3612 	{d68000_muls         , 0xf1c0, 0xc1c0, 0xbff},
3613 	{d68000_mulu         , 0xf1c0, 0xc0c0, 0xbff},
3614 	{d68020_mull         , 0xffc0, 0x4c00, 0xbff, 0x83f8, 0x0000},
3615 	{d68000_nbcd         , 0xffc0, 0x4800, 0xbf8},
3616 	{d68000_neg_8        , 0xffc0, 0x4400, 0xbf8},
3617 	{d68000_neg_16       , 0xffc0, 0x4440, 0xbf8},
3618 	{d68000_neg_32       , 0xffc0, 0x4480, 0xbf8},
3619 	{d68000_negx_8       , 0xffc0, 0x4000, 0xbf8},
3620 	{d68000_negx_16      , 0xffc0, 0x4040, 0xbf8},
3621 	{d68000_negx_32      , 0xffc0, 0x4080, 0xbf8},
3622 	{d68000_nop          , 0xffff, 0x4e71, 0x000},
3623 	{d68000_not_8        , 0xffc0, 0x4600, 0xbf8},
3624 	{d68000_not_16       , 0xffc0, 0x4640, 0xbf8},
3625 	{d68000_not_32       , 0xffc0, 0x4680, 0xbf8},
3626 	{d68000_or_er_8      , 0xf1c0, 0x8000, 0xbff},
3627 	{d68000_or_er_16     , 0xf1c0, 0x8040, 0xbff},
3628 	{d68000_or_er_32     , 0xf1c0, 0x8080, 0xbff},
3629 	{d68000_or_re_8      , 0xf1c0, 0x8100, 0x3f8},
3630 	{d68000_or_re_16     , 0xf1c0, 0x8140, 0x3f8},
3631 	{d68000_or_re_32     , 0xf1c0, 0x8180, 0x3f8},
3632 	{d68000_ori_to_ccr   , 0xffff, 0x003c, 0x000, 0xff00, 0x0000},
3633 	{d68000_ori_to_sr    , 0xffff, 0x007c, 0x000},
3634 	{d68000_ori_8        , 0xffc0, 0x0000, 0xbf8},
3635 	{d68000_ori_16       , 0xffc0, 0x0040, 0xbf8},
3636 	{d68000_ori_32       , 0xffc0, 0x0080, 0xbf8},
3637 	{d68020_pack_rr      , 0xf1f8, 0x8140, 0x000},
3638 	{d68020_pack_mm      , 0xf1f8, 0x8148, 0x000},
3639 	{d68000_pea          , 0xffc0, 0x4840, 0x27b},
3640 	{d68000_reset        , 0xffff, 0x4e70, 0x000},
3641 	{d68000_ror_s_8      , 0xf1f8, 0xe018, 0x000},
3642 	{d68000_ror_s_16     , 0xf1f8, 0xe058, 0x000},
3643 	{d68000_ror_s_32     , 0xf1f8, 0xe098, 0x000},
3644 	{d68000_ror_r_8      , 0xf1f8, 0xe038, 0x000},
3645 	{d68000_ror_r_16     , 0xf1f8, 0xe078, 0x000},
3646 	{d68000_ror_r_32     , 0xf1f8, 0xe0b8, 0x000},
3647 	{d68000_ror_ea       , 0xffc0, 0xe6c0, 0x3f8},
3648 	{d68000_rol_s_8      , 0xf1f8, 0xe118, 0x000},
3649 	{d68000_rol_s_16     , 0xf1f8, 0xe158, 0x000},
3650 	{d68000_rol_s_32     , 0xf1f8, 0xe198, 0x000},
3651 	{d68000_rol_r_8      , 0xf1f8, 0xe138, 0x000},
3652 	{d68000_rol_r_16     , 0xf1f8, 0xe178, 0x000},
3653 	{d68000_rol_r_32     , 0xf1f8, 0xe1b8, 0x000},
3654 	{d68000_rol_ea       , 0xffc0, 0xe7c0, 0x3f8},
3655 	{d68000_roxr_s_8     , 0xf1f8, 0xe010, 0x000},
3656 	{d68000_roxr_s_16    , 0xf1f8, 0xe050, 0x000},
3657 	{d68000_roxr_s_32    , 0xf1f8, 0xe090, 0x000},
3658 	{d68000_roxr_r_8     , 0xf1f8, 0xe030, 0x000},
3659 	{d68000_roxr_r_16    , 0xf1f8, 0xe070, 0x000},
3660 	{d68000_roxr_r_32    , 0xf1f8, 0xe0b0, 0x000},
3661 	{d68000_roxr_ea      , 0xffc0, 0xe4c0, 0x3f8},
3662 	{d68000_roxl_s_8     , 0xf1f8, 0xe110, 0x000},
3663 	{d68000_roxl_s_16    , 0xf1f8, 0xe150, 0x000},
3664 	{d68000_roxl_s_32    , 0xf1f8, 0xe190, 0x000},
3665 	{d68000_roxl_r_8     , 0xf1f8, 0xe130, 0x000},
3666 	{d68000_roxl_r_16    , 0xf1f8, 0xe170, 0x000},
3667 	{d68000_roxl_r_32    , 0xf1f8, 0xe1b0, 0x000},
3668 	{d68000_roxl_ea      , 0xffc0, 0xe5c0, 0x3f8},
3669 	{d68010_rtd          , 0xffff, 0x4e74, 0x000},
3670 	{d68000_rte          , 0xffff, 0x4e73, 0x000},
3671 	{d68020_rtm          , 0xfff0, 0x06c0, 0x000},
3672 	{d68000_rtr          , 0xffff, 0x4e77, 0x000},
3673 	{d68000_rts          , 0xffff, 0x4e75, 0x000},
3674 	{d68000_sbcd_rr      , 0xf1f8, 0x8100, 0x000},
3675 	{d68000_sbcd_mm      , 0xf1f8, 0x8108, 0x000},
3676 	{d68000_scc          , 0xf0c0, 0x50c0, 0xbf8},
3677 	{d68000_stop         , 0xffff, 0x4e72, 0x000},
3678 	{d68000_sub_er_8     , 0xf1c0, 0x9000, 0xbff},
3679 	{d68000_sub_er_16    , 0xf1c0, 0x9040, 0xfff},
3680 	{d68000_sub_er_32    , 0xf1c0, 0x9080, 0xfff},
3681 	{d68000_sub_re_8     , 0xf1c0, 0x9100, 0x3f8},
3682 	{d68000_sub_re_16    , 0xf1c0, 0x9140, 0x3f8},
3683 	{d68000_sub_re_32    , 0xf1c0, 0x9180, 0x3f8},
3684 	{d68000_suba_16      , 0xf1c0, 0x90c0, 0xfff},
3685 	{d68000_suba_32      , 0xf1c0, 0x91c0, 0xfff},
3686 	{d68000_subi_8       , 0xffc0, 0x0400, 0xbf8},
3687 	{d68000_subi_16      , 0xffc0, 0x0440, 0xbf8},
3688 	{d68000_subi_32      , 0xffc0, 0x0480, 0xbf8},
3689 	{d68000_subq_8       , 0xf1c0, 0x5100, 0xbf8},
3690 	{d68000_subq_16      , 0xf1c0, 0x5140, 0xff8},
3691 	{d68000_subq_32      , 0xf1c0, 0x5180, 0xff8},
3692 	{d68000_subx_rr_8    , 0xf1f8, 0x9100, 0x000},
3693 	{d68000_subx_rr_16   , 0xf1f8, 0x9140, 0x000},
3694 	{d68000_subx_rr_32   , 0xf1f8, 0x9180, 0x000},
3695 	{d68000_subx_mm_8    , 0xf1f8, 0x9108, 0x000},
3696 	{d68000_subx_mm_16   , 0xf1f8, 0x9148, 0x000},
3697 	{d68000_subx_mm_32   , 0xf1f8, 0x9188, 0x000},
3698 	{d68000_swap         , 0xfff8, 0x4840, 0x000},
3699 	{d68000_tas          , 0xffc0, 0x4ac0, 0xbf8},
3700 	{d68000_trap         , 0xfff0, 0x4e40, 0x000},
3701 	{d68020_trapcc_0     , 0xf0ff, 0x50fc, 0x000},
3702 	{d68020_trapcc_16    , 0xf0ff, 0x50fa, 0x000},
3703 	{d68020_trapcc_32    , 0xf0ff, 0x50fb, 0x000},
3704 	{d68000_trapv        , 0xffff, 0x4e76, 0x000},
3705 	{d68000_tst_8        , 0xffc0, 0x4a00, 0xbf8},
3706 	{d68020_tst_pcdi_8   , 0xffff, 0x4a3a, 0x000},
3707 	{d68020_tst_pcix_8   , 0xffff, 0x4a3b, 0x000},
3708 	{d68020_tst_i_8      , 0xffff, 0x4a3c, 0x000},
3709 	{d68000_tst_16       , 0xffc0, 0x4a40, 0xbf8},
3710 	{d68020_tst_a_16     , 0xfff8, 0x4a48, 0x000},
3711 	{d68020_tst_pcdi_16  , 0xffff, 0x4a7a, 0x000},
3712 	{d68020_tst_pcix_16  , 0xffff, 0x4a7b, 0x000},
3713 	{d68020_tst_i_16     , 0xffff, 0x4a7c, 0x000},
3714 	{d68000_tst_32       , 0xffc0, 0x4a80, 0xbf8},
3715 	{d68020_tst_a_32     , 0xfff8, 0x4a88, 0x000},
3716 	{d68020_tst_pcdi_32  , 0xffff, 0x4aba, 0x000},
3717 	{d68020_tst_pcix_32  , 0xffff, 0x4abb, 0x000},
3718 	{d68020_tst_i_32     , 0xffff, 0x4abc, 0x000},
3719 	{d68000_unlk         , 0xfff8, 0x4e58, 0x000},
3720 	{d68020_unpk_rr      , 0xf1f8, 0x8180, 0x000},
3721 	{d68020_unpk_mm      , 0xf1f8, 0x8188, 0x000},
3722 	{0, 0, 0, 0}
3723 };
3724 
3725 /* Check if opcode is using a valid ea mode */
valid_ea(uint opcode,uint mask)3726 static int valid_ea(uint opcode, uint mask)
3727 {
3728 	if (mask == 0)
3729 		return 1;
3730 
3731 	switch(opcode & 0x3f) {
3732 		case 0x00: case 0x01: case 0x02: case 0x03:
3733 		case 0x04: case 0x05: case 0x06: case 0x07:
3734 			return (mask & 0x800) != 0;
3735 		case 0x08: case 0x09: case 0x0a: case 0x0b:
3736 		case 0x0c: case 0x0d: case 0x0e: case 0x0f:
3737 			return (mask & 0x400) != 0;
3738 		case 0x10: case 0x11: case 0x12: case 0x13:
3739 		case 0x14: case 0x15: case 0x16: case 0x17:
3740 			return (mask & 0x200) != 0;
3741 		case 0x18: case 0x19: case 0x1a: case 0x1b:
3742 		case 0x1c: case 0x1d: case 0x1e: case 0x1f:
3743 			return (mask & 0x100) != 0;
3744 		case 0x20: case 0x21: case 0x22: case 0x23:
3745 		case 0x24: case 0x25: case 0x26: case 0x27:
3746 			return (mask & 0x080) != 0;
3747 		case 0x28: case 0x29: case 0x2a: case 0x2b:
3748 		case 0x2c: case 0x2d: case 0x2e: case 0x2f:
3749 			return (mask & 0x040) != 0;
3750 		case 0x30: case 0x31: case 0x32: case 0x33:
3751 		case 0x34: case 0x35: case 0x36: case 0x37:
3752 			return (mask & 0x020) != 0;
3753 		case 0x38:
3754 			return (mask & 0x010) != 0;
3755 		case 0x39:
3756 			return (mask & 0x008) != 0;
3757 		case 0x3a:
3758 			return (mask & 0x002) != 0;
3759 		case 0x3b:
3760 			return (mask & 0x001) != 0;
3761 		case 0x3c:
3762 			return (mask & 0x004) != 0;
3763 	}
3764 	return 0;
3765 
3766 }
3767 
3768 /* Used by qsort */
compare_nof_true_bits(const void * aptr,const void * bptr)3769 static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr)
3770 {
3771 	uint a = ((const opcode_struct*)aptr)->mask;
3772 	uint b = ((const opcode_struct*)bptr)->mask;
3773 
3774 	a = ((a & 0xAAAA) >> 1) + (a & 0x5555);
3775 	a = ((a & 0xCCCC) >> 2) + (a & 0x3333);
3776 	a = ((a & 0xF0F0) >> 4) + (a & 0x0F0F);
3777 	a = ((a & 0xFF00) >> 8) + (a & 0x00FF);
3778 
3779 	b = ((b & 0xAAAA) >> 1) + (b & 0x5555);
3780 	b = ((b & 0xCCCC) >> 2) + (b & 0x3333);
3781 	b = ((b & 0xF0F0) >> 4) + (b & 0x0F0F);
3782 	b = ((b & 0xFF00) >> 8) + (b & 0x00FF);
3783 
3784 	return b - a; /* reversed to get greatest to least sorting */
3785 }
3786 
3787 /* build the opcode handler jump table */
build_opcode_table(void)3788 static void build_opcode_table(void)
3789 {
3790 	uint i;
3791 	uint opcode;
3792 	opcode_struct* ostruct;
3793 	uint opcode_info_length = 0;
3794 
3795 	/* Already initialized ? */
3796 	if (g_instruction_table[0].instruction != NULL) {
3797 		return;
3798 	}
3799 
3800 	for(ostruct = g_opcode_info;ostruct->opcode_handler != 0;ostruct++)
3801 		opcode_info_length++;
3802 
3803 	qsort((void *)g_opcode_info, opcode_info_length, sizeof(g_opcode_info[0]), compare_nof_true_bits);
3804 
3805 	for(i=0;i<0x10000;i++) {
3806 		g_instruction_table[i].instruction = d68000_invalid; /* default to invalid, undecoded opcode */
3807 		opcode = i;
3808 		/* search through opcode info for a match */
3809 		for(ostruct = g_opcode_info;ostruct->opcode_handler != 0;ostruct++) {
3810 			/* match opcode mask and allowed ea modes */
3811 			if ((opcode & ostruct->mask) == ostruct->match) {
3812 				/* Handle destination ea for move instructions */
3813 				if ((ostruct->opcode_handler == d68000_move_8 ||
3814 							ostruct->opcode_handler == d68000_move_16 ||
3815 							ostruct->opcode_handler == d68000_move_32) &&
3816 						!valid_ea(((opcode>>9)&7) | ((opcode>>3)&0x38), 0xbf8))
3817 					continue;
3818 				if (valid_ea(opcode, ostruct->ea_mask)) {
3819 					g_instruction_table[i].instruction = ostruct->opcode_handler;
3820 					g_instruction_table[i].word2_mask = ostruct->mask2;
3821 					g_instruction_table[i].word2_match = ostruct->match2;
3822 					break;
3823 				}
3824 			}
3825 		}
3826 	}
3827 }
3828 
instruction_is_valid(m68k_info * info,const unsigned int word_check)3829 static int instruction_is_valid(m68k_info *info, const unsigned int word_check)
3830 {
3831 	const unsigned int instruction = info->ir;
3832 	instruction_struct *i = &g_instruction_table[instruction];
3833 
3834 	if ( (i->word2_mask && ((word_check & i->word2_mask) != i->word2_match)) ||
3835 		(i->instruction == d68000_invalid) ) {
3836 		d68000_invalid(info);
3837 		return 0;
3838 	}
3839 
3840 	return 1;
3841 }
3842 
exists_reg_list(uint16_t * regs,uint8_t count,m68k_reg reg)3843 static int exists_reg_list(uint16_t *regs, uint8_t count, m68k_reg reg)
3844 {
3845 	uint8_t i;
3846 
3847 	for (i = 0; i < count; ++i) {
3848 		if (regs[i] == (uint16_t)reg)
3849 			return 1;
3850 	}
3851 
3852 	return 0;
3853 }
3854 
add_reg_to_rw_list(m68k_info * info,m68k_reg reg,int write)3855 static void add_reg_to_rw_list(m68k_info *info, m68k_reg reg, int write)
3856 {
3857 	if (reg == M68K_REG_INVALID)
3858 		return;
3859 
3860 	if (write)
3861 	{
3862 		if (exists_reg_list(info->regs_write, info->regs_write_count, reg))
3863 			return;
3864 
3865 		info->regs_write[info->regs_write_count] = (uint16_t)reg;
3866 		info->regs_write_count++;
3867 	}
3868 	else
3869 	{
3870 		if (exists_reg_list(info->regs_read, info->regs_read_count, reg))
3871 			return;
3872 
3873 		info->regs_read[info->regs_read_count] = (uint16_t)reg;
3874 		info->regs_read_count++;
3875 	}
3876 }
3877 
update_am_reg_list(m68k_info * info,cs_m68k_op * op,int write)3878 static void update_am_reg_list(m68k_info *info, cs_m68k_op *op, int write)
3879 {
3880 	switch (op->address_mode) {
3881 		case M68K_AM_REG_DIRECT_ADDR:
3882 		case M68K_AM_REG_DIRECT_DATA:
3883 			add_reg_to_rw_list(info, op->reg, write);
3884 			break;
3885 
3886 		case M68K_AM_REGI_ADDR_POST_INC:
3887 		case M68K_AM_REGI_ADDR_PRE_DEC:
3888 			add_reg_to_rw_list(info, op->reg, 1);
3889 			break;
3890 
3891 		case M68K_AM_REGI_ADDR:
3892 		case M68K_AM_REGI_ADDR_DISP:
3893 			add_reg_to_rw_list(info, op->reg, 0);
3894 			break;
3895 
3896 		case M68K_AM_AREGI_INDEX_8_BIT_DISP:
3897 		case M68K_AM_AREGI_INDEX_BASE_DISP:
3898 		case M68K_AM_MEMI_POST_INDEX:
3899 		case M68K_AM_MEMI_PRE_INDEX:
3900 		case M68K_AM_PCI_INDEX_8_BIT_DISP:
3901 		case M68K_AM_PCI_INDEX_BASE_DISP:
3902 		case M68K_AM_PC_MEMI_PRE_INDEX:
3903 		case M68K_AM_PC_MEMI_POST_INDEX:
3904 			add_reg_to_rw_list(info, op->mem.index_reg, 0);
3905 			add_reg_to_rw_list(info, op->mem.base_reg, 0);
3906 			break;
3907 
3908 		// no register(s) in the other addressing modes
3909 		default:
3910 			break;
3911 	}
3912 }
3913 
update_bits_range(m68k_info * info,m68k_reg reg_start,uint8_t bits,int write)3914 static void update_bits_range(m68k_info *info, m68k_reg reg_start, uint8_t bits, int write)
3915 {
3916 	int i;
3917 
3918 	for (i = 0; i < 8; ++i) {
3919 		if (bits & (1 << i)) {
3920 			add_reg_to_rw_list(info, reg_start + i, write);
3921 		}
3922 	}
3923 }
3924 
update_reg_list_regbits(m68k_info * info,cs_m68k_op * op,int write)3925 static void update_reg_list_regbits(m68k_info *info, cs_m68k_op *op, int write)
3926 {
3927 	uint32_t bits = op->register_bits;
3928 	update_bits_range(info, M68K_REG_D0, bits & 0xff, write);
3929 	update_bits_range(info, M68K_REG_A0, (bits >> 8) & 0xff, write);
3930 	update_bits_range(info, M68K_REG_FP0, (bits >> 16) & 0xff, write);
3931 }
3932 
update_op_reg_list(m68k_info * info,cs_m68k_op * op,int write)3933 static void update_op_reg_list(m68k_info *info, cs_m68k_op *op, int write)
3934 {
3935 	switch ((int)op->type) {
3936 		case M68K_OP_REG:
3937 			add_reg_to_rw_list(info, op->reg, write);
3938 			break;
3939 
3940 		case M68K_OP_MEM:
3941 			update_am_reg_list(info, op, write);
3942 			break;
3943 
3944 		case M68K_OP_REG_BITS:
3945 			update_reg_list_regbits(info, op, write);
3946 			break;
3947 
3948 		case M68K_OP_REG_PAIR:
3949 			add_reg_to_rw_list(info, M68K_REG_D0 + op->reg_pair.reg_0, write);
3950 			add_reg_to_rw_list(info, M68K_REG_D0 + op->reg_pair.reg_1, write);
3951 			break;
3952 	}
3953 }
3954 
build_regs_read_write_counts(m68k_info * info)3955 static void build_regs_read_write_counts(m68k_info *info)
3956 {
3957 	int i;
3958 
3959 	if (!info->extension.op_count)
3960 		return;
3961 
3962 	if (info->extension.op_count == 1) {
3963 		update_op_reg_list(info, &info->extension.operands[0], 1);
3964 	} else {
3965 		// first operand is always read
3966 		update_op_reg_list(info, &info->extension.operands[0], 0);
3967 
3968 		// remaning write
3969 		for (i = 1; i < info->extension.op_count; ++i)
3970 			update_op_reg_list(info, &info->extension.operands[i], 1);
3971 	}
3972 }
3973 
m68k_setup_internals(m68k_info * info,MCInst * inst,unsigned int pc,unsigned int cpu_type)3974 static void m68k_setup_internals(m68k_info* info, MCInst* inst, unsigned int pc, unsigned int cpu_type)
3975 {
3976 	info->inst = inst;
3977 	info->pc = pc;
3978 	info->ir = 0;
3979 	info->type = cpu_type;
3980 	info->address_mask = 0xffffffff;
3981 
3982 	switch(info->type) {
3983 		case M68K_CPU_TYPE_68000:
3984 			info->type = TYPE_68000;
3985 			info->address_mask = 0x00ffffff;
3986 			break;
3987 		case M68K_CPU_TYPE_68010:
3988 			info->type = TYPE_68010;
3989 			info->address_mask = 0x00ffffff;
3990 			break;
3991 		case M68K_CPU_TYPE_68EC020:
3992 			info->type = TYPE_68020;
3993 			info->address_mask = 0x00ffffff;
3994 			break;
3995 		case M68K_CPU_TYPE_68020:
3996 			info->type = TYPE_68020;
3997 			info->address_mask = 0xffffffff;
3998 			break;
3999 		case M68K_CPU_TYPE_68030:
4000 			info->type = TYPE_68030;
4001 			info->address_mask = 0xffffffff;
4002 			break;
4003 		case M68K_CPU_TYPE_68040:
4004 			info->type = TYPE_68040;
4005 			info->address_mask = 0xffffffff;
4006 			break;
4007 		default:
4008 			info->address_mask = 0;
4009 			return;
4010 	}
4011 }
4012 
4013 /* ======================================================================== */
4014 /* ================================= API ================================== */
4015 /* ======================================================================== */
4016 
4017 /* Disasemble one instruction at pc and store in str_buff */
m68k_disassemble(m68k_info * info,uint64_t pc)4018 static unsigned int m68k_disassemble(m68k_info *info, uint64_t pc)
4019 {
4020 	MCInst *inst = info->inst;
4021 	cs_m68k* ext = &info->extension;
4022 	int i;
4023 	unsigned int size;
4024 
4025 	inst->Opcode = M68K_INS_INVALID;
4026 
4027 	build_opcode_table();
4028 
4029 	memset(ext, 0, sizeof(cs_m68k));
4030 	ext->op_size.type = M68K_SIZE_TYPE_CPU;
4031 
4032 	for (i = 0; i < M68K_OPERAND_COUNT; ++i)
4033 		ext->operands[i].type = M68K_OP_REG;
4034 
4035 	info->ir = peek_imm_16(info);
4036 	if (instruction_is_valid(info, peek_imm_32(info) & 0xffff)) {
4037 		info->ir = read_imm_16(info);
4038 		g_instruction_table[info->ir].instruction(info);
4039 	}
4040 
4041 	size = info->pc - (unsigned int)pc;
4042 	info->pc = (unsigned int)pc;
4043 
4044 	return size;
4045 }
4046 
M68K_getInstruction(csh ud,const uint8_t * code,size_t code_len,MCInst * instr,uint16_t * size,uint64_t address,void * inst_info)4047 bool M68K_getInstruction(csh ud, const uint8_t* code, size_t code_len, MCInst* instr, uint16_t* size, uint64_t address, void* inst_info)
4048 {
4049 #ifdef M68K_DEBUG
4050 	SStream ss;
4051 #endif
4052 	int s;
4053 	int cpu_type = M68K_CPU_TYPE_68000;
4054 	cs_struct* handle = instr->csh;
4055 	m68k_info *info = (m68k_info*)handle->printer_info;
4056 
4057 	// code len has to be at least 2 bytes to be valid m68k
4058 
4059 	if (code_len < 2) {
4060 		*size = 0;
4061 		return false;
4062 	}
4063 
4064 	if (instr->flat_insn->detail) {
4065 		memset(instr->flat_insn->detail, 0, offsetof(cs_detail, m68k)+sizeof(cs_m68k));
4066 	}
4067 
4068 	info->groups_count = 0;
4069 	info->regs_read_count = 0;
4070 	info->regs_write_count = 0;
4071 	info->code = code;
4072 	info->code_len = code_len;
4073 	info->baseAddress = address;
4074 
4075 	if (handle->mode & CS_MODE_M68K_010)
4076 		cpu_type = M68K_CPU_TYPE_68010;
4077 	if (handle->mode & CS_MODE_M68K_020)
4078 		cpu_type = M68K_CPU_TYPE_68020;
4079 	if (handle->mode & CS_MODE_M68K_030)
4080 		cpu_type = M68K_CPU_TYPE_68030;
4081 	if (handle->mode & CS_MODE_M68K_040)
4082 		cpu_type = M68K_CPU_TYPE_68040;
4083 	if (handle->mode & CS_MODE_M68K_060)
4084 		cpu_type = M68K_CPU_TYPE_68040;	// 060 = 040 for now
4085 
4086 	m68k_setup_internals(info, instr, (unsigned int)address, cpu_type);
4087 	s = m68k_disassemble(info, address);
4088 
4089 	if (s == 0) {
4090 		*size = 2;
4091 		return false;
4092 	}
4093 
4094 	build_regs_read_write_counts(info);
4095 
4096 #ifdef M68K_DEBUG
4097 	SStream_Init(&ss);
4098 	M68K_printInst(instr, &ss, info);
4099 #endif
4100 
4101 	// Make sure we always stay within range
4102 	if (s > (int)code_len)
4103 		*size = (uint16_t)code_len;
4104 	else
4105 		*size = (uint16_t)s;
4106 
4107 	return true;
4108 }
4109 
4110