• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 long long peek_imm_64(const m68k_info *info) { return 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 long long read_imm_64(m68k_info *info) { const unsigned long long 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 static 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 	// Special case - adjust direction of fmove
2066 	if ((opmode == 0x00) && ((next >> 13) & 0x1) != 0) {
2067 		op0 = &ext->operands[1];
2068 		op1 = &ext->operands[0];
2069 	} else {
2070 		op0 = &ext->operands[0];
2071 		op1 = &ext->operands[1];
2072 	}
2073 
2074 	if (rm == 0 && supports_single_op && src == dst) {
2075 		ext->op_count = 1;
2076 		op0->reg = M68K_REG_FP0 + dst;
2077 		return;
2078 	}
2079 
2080 	if (rm == 1) {
2081 		switch (src) {
2082 			case 0x00 :
2083 				ext->op_size.cpu_size = M68K_CPU_SIZE_LONG;
2084 				get_ea_mode_op(info, op0, info->ir, 4);
2085 				break;
2086 
2087 			case 0x06 :
2088 				ext->op_size.cpu_size = M68K_CPU_SIZE_BYTE;
2089 				get_ea_mode_op(info, op0, info->ir, 1);
2090 				break;
2091 
2092 			case 0x04 :
2093 				ext->op_size.cpu_size = M68K_CPU_SIZE_WORD;
2094 				get_ea_mode_op(info, op0, info->ir, 2);
2095 				break;
2096 
2097 			case 0x01 :
2098 				ext->op_size.type = M68K_SIZE_TYPE_FPU;
2099 				ext->op_size.fpu_size = M68K_FPU_SIZE_SINGLE;
2100 				get_ea_mode_op(info, op0, info->ir, 4);
2101 				op0->type = M68K_OP_FP_SINGLE;
2102 				break;
2103 
2104 			case 0x05:
2105 				ext->op_size.type = M68K_SIZE_TYPE_FPU;
2106 				ext->op_size.fpu_size = M68K_FPU_SIZE_DOUBLE;
2107 				get_ea_mode_op(info, op0, info->ir, 8);
2108 				op0->type = M68K_OP_FP_DOUBLE;
2109 				break;
2110 
2111 			default :
2112 				ext->op_size.type = M68K_SIZE_TYPE_FPU;
2113 				ext->op_size.fpu_size = M68K_FPU_SIZE_EXTENDED;
2114 				break;
2115 		}
2116 	} else {
2117 		op0->reg = M68K_REG_FP0 + src;
2118 	}
2119 
2120 	op1->reg = M68K_REG_FP0 + dst;
2121 }
2122 
d68020_cprestore(m68k_info * info)2123 static void d68020_cprestore(m68k_info *info)
2124 {
2125 	cs_m68k* ext;
2126 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2127 
2128 	ext = build_init_op(info, M68K_INS_FRESTORE, 1, 0);
2129 	get_ea_mode_op(info, &ext->operands[0], info->ir, 1);
2130 }
2131 
d68020_cpsave(m68k_info * info)2132 static void d68020_cpsave(m68k_info *info)
2133 {
2134 	cs_m68k* ext;
2135 
2136 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2137 
2138 	ext = build_init_op(info, M68K_INS_FSAVE, 1, 0);
2139 	get_ea_mode_op(info, &ext->operands[0], info->ir, 1);
2140 }
2141 
d68020_cpscc(m68k_info * info)2142 static void d68020_cpscc(m68k_info *info)
2143 {
2144 	cs_m68k* ext;
2145 
2146 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2147 	ext = build_init_op(info, M68K_INS_FSF, 1, 1);
2148 
2149 	// these are all in row with the extension so just doing a add here is fine
2150 	info->inst->Opcode += (read_imm_16(info) & 0x2f);
2151 
2152 	get_ea_mode_op(info, &ext->operands[0], info->ir, 1);
2153 }
2154 
d68020_cptrapcc_0(m68k_info * info)2155 static void d68020_cptrapcc_0(m68k_info *info)
2156 {
2157 	uint extension1;
2158 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2159 
2160 	extension1 = read_imm_16(info);
2161 
2162 	build_init_op(info, M68K_INS_FTRAPF, 0, 0);
2163 
2164 	// these are all in row with the extension so just doing a add here is fine
2165 	info->inst->Opcode += (extension1 & 0x2f);
2166 }
2167 
d68020_cptrapcc_16(m68k_info * info)2168 static void d68020_cptrapcc_16(m68k_info *info)
2169 {
2170 	uint extension1, extension2;
2171 	cs_m68k_op* op0;
2172 	cs_m68k* ext;
2173 
2174 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2175 
2176 	extension1 = read_imm_16(info);
2177 	extension2 = read_imm_16(info);
2178 
2179 	ext = build_init_op(info, M68K_INS_FTRAPF, 1, 2);
2180 
2181 	// these are all in row with the extension so just doing a add here is fine
2182 	info->inst->Opcode += (extension1 & 0x2f);
2183 
2184 	op0 = &ext->operands[0];
2185 
2186 	op0->address_mode = M68K_AM_IMMEDIATE;
2187 	op0->type = M68K_OP_IMM;
2188 	op0->imm = extension2;
2189 }
2190 
d68020_cptrapcc_32(m68k_info * info)2191 static void d68020_cptrapcc_32(m68k_info *info)
2192 {
2193 	uint extension1, extension2;
2194 	cs_m68k* ext;
2195 	cs_m68k_op* op0;
2196 
2197 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2198 
2199 	extension1 = read_imm_16(info);
2200 	extension2 = read_imm_32(info);
2201 
2202 	ext = build_init_op(info, M68K_INS_FTRAPF, 1, 2);
2203 
2204 	// these are all in row with the extension so just doing a add here is fine
2205 	info->inst->Opcode += (extension1 & 0x2f);
2206 
2207 	op0 = &ext->operands[0];
2208 
2209 	op0->address_mode = M68K_AM_IMMEDIATE;
2210 	op0->type = M68K_OP_IMM;
2211 	op0->imm = extension2;
2212 }
2213 
d68040_cpush(m68k_info * info)2214 static void d68040_cpush(m68k_info *info)
2215 {
2216 	LIMIT_CPU_TYPES(info, M68040_PLUS);
2217 	build_cpush_cinv(info, M68K_INS_CPUSHL);
2218 }
2219 
d68000_dbra(m68k_info * info)2220 static void d68000_dbra(m68k_info *info)
2221 {
2222 	build_dbxx(info, M68K_INS_DBRA, 0, make_int_16(read_imm_16(info)));
2223 }
2224 
d68000_dbcc(m68k_info * info)2225 static void d68000_dbcc(m68k_info *info)
2226 {
2227 	build_dbcc(info, 0, make_int_16(read_imm_16(info)));
2228 }
2229 
d68000_divs(m68k_info * info)2230 static void d68000_divs(m68k_info *info)
2231 {
2232 	build_er_1(info, M68K_INS_DIVS, 2);
2233 }
2234 
d68000_divu(m68k_info * info)2235 static void d68000_divu(m68k_info *info)
2236 {
2237 	build_er_1(info, M68K_INS_DIVU, 2);
2238 }
2239 
d68020_divl(m68k_info * info)2240 static void d68020_divl(m68k_info *info)
2241 {
2242 	uint extension, insn_signed;
2243 	cs_m68k* ext;
2244 	cs_m68k_op* op0;
2245 	cs_m68k_op* op1;
2246 	uint reg_0, reg_1;
2247 
2248 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2249 
2250 	extension = read_imm_16(info);
2251 	insn_signed = 0;
2252 
2253 	if (BIT_B((extension)))
2254 		insn_signed = 1;
2255 
2256 	ext = build_init_op(info, insn_signed ? M68K_INS_DIVS : M68K_INS_DIVU, 2, 4);
2257 
2258 	op0 = &ext->operands[0];
2259 	op1 = &ext->operands[1];
2260 
2261 	get_ea_mode_op(info, op0, info->ir, 4);
2262 
2263 	reg_0 = extension & 7;
2264 	reg_1 = (extension >> 12) & 7;
2265 
2266 	op1->address_mode = M68K_AM_NONE;
2267 	op1->type = M68K_OP_REG_PAIR;
2268 	op1->reg_pair.reg_0 = reg_0;
2269 	op1->reg_pair.reg_1 = reg_1;
2270 
2271 	if ((reg_0 == reg_1) || !BIT_A(extension)) {
2272 		op1->type = M68K_OP_REG;
2273 		op1->reg = M68K_REG_D0 + reg_1;
2274 	}
2275 }
2276 
d68000_eor_8(m68k_info * info)2277 static void d68000_eor_8(m68k_info *info)
2278 {
2279 	build_re_1(info, M68K_INS_EOR, 1);
2280 }
2281 
d68000_eor_16(m68k_info * info)2282 static void d68000_eor_16(m68k_info *info)
2283 {
2284 	build_re_1(info, M68K_INS_EOR, 2);
2285 }
2286 
d68000_eor_32(m68k_info * info)2287 static void d68000_eor_32(m68k_info *info)
2288 {
2289 	build_re_1(info, M68K_INS_EOR, 4);
2290 }
2291 
d68000_eori_8(m68k_info * info)2292 static void d68000_eori_8(m68k_info *info)
2293 {
2294 	build_imm_ea(info, M68K_INS_EORI, 1, read_imm_8(info));
2295 }
2296 
d68000_eori_16(m68k_info * info)2297 static void d68000_eori_16(m68k_info *info)
2298 {
2299 	build_imm_ea(info, M68K_INS_EORI, 2, read_imm_16(info));
2300 }
2301 
d68000_eori_32(m68k_info * info)2302 static void d68000_eori_32(m68k_info *info)
2303 {
2304 	build_imm_ea(info, M68K_INS_EORI, 4, read_imm_32(info));
2305 }
2306 
d68000_eori_to_ccr(m68k_info * info)2307 static void d68000_eori_to_ccr(m68k_info *info)
2308 {
2309 	build_imm_special_reg(info, M68K_INS_EORI, read_imm_8(info), 1, M68K_REG_CCR);
2310 }
2311 
d68000_eori_to_sr(m68k_info * info)2312 static void d68000_eori_to_sr(m68k_info *info)
2313 {
2314 	build_imm_special_reg(info, M68K_INS_EORI, read_imm_16(info), 2, M68K_REG_SR);
2315 }
2316 
d68000_exg_dd(m68k_info * info)2317 static void d68000_exg_dd(m68k_info *info)
2318 {
2319 	build_r(info, M68K_INS_EXG, 4);
2320 }
2321 
d68000_exg_aa(m68k_info * info)2322 static void d68000_exg_aa(m68k_info *info)
2323 {
2324 	cs_m68k_op* op0;
2325 	cs_m68k_op* op1;
2326 	cs_m68k* ext = build_init_op(info, M68K_INS_EXG, 2, 4);
2327 
2328 	op0 = &ext->operands[0];
2329 	op1 = &ext->operands[1];
2330 
2331 	op0->address_mode = M68K_AM_NONE;
2332 	op0->reg = M68K_REG_A0 + ((info->ir >> 9) & 7);
2333 
2334 	op1->address_mode = M68K_AM_NONE;
2335 	op1->reg = M68K_REG_A0 + (info->ir & 7);
2336 }
2337 
d68000_exg_da(m68k_info * info)2338 static void d68000_exg_da(m68k_info *info)
2339 {
2340 	cs_m68k_op* op0;
2341 	cs_m68k_op* op1;
2342 	cs_m68k* ext = build_init_op(info, M68K_INS_EXG, 2, 4);
2343 
2344 	op0 = &ext->operands[0];
2345 	op1 = &ext->operands[1];
2346 
2347 	op0->address_mode = M68K_AM_NONE;
2348 	op0->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
2349 
2350 	op1->address_mode = M68K_AM_NONE;
2351 	op1->reg = M68K_REG_A0 + (info->ir & 7);
2352 }
2353 
d68000_ext_16(m68k_info * info)2354 static void d68000_ext_16(m68k_info *info)
2355 {
2356 	build_d(info, M68K_INS_EXT, 2);
2357 }
2358 
d68000_ext_32(m68k_info * info)2359 static void d68000_ext_32(m68k_info *info)
2360 {
2361 	build_d(info, M68K_INS_EXT, 4);
2362 }
2363 
d68020_extb_32(m68k_info * info)2364 static void d68020_extb_32(m68k_info *info)
2365 {
2366 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2367 	build_d(info, M68K_INS_EXTB, 4);
2368 }
2369 
d68000_jmp(m68k_info * info)2370 static void d68000_jmp(m68k_info *info)
2371 {
2372 	cs_m68k* ext = build_init_op(info, M68K_INS_JMP, 1, 0);
2373 	set_insn_group(info, M68K_GRP_JUMP);
2374 	get_ea_mode_op(info, &ext->operands[0], info->ir, 4);
2375 }
2376 
d68000_jsr(m68k_info * info)2377 static void d68000_jsr(m68k_info *info)
2378 {
2379 	cs_m68k* ext = build_init_op(info, M68K_INS_JSR, 1, 0);
2380 	set_insn_group(info, M68K_GRP_JUMP);
2381 	get_ea_mode_op(info, &ext->operands[0], info->ir, 4);
2382 }
2383 
d68000_lea(m68k_info * info)2384 static void d68000_lea(m68k_info *info)
2385 {
2386 	build_ea_a(info, M68K_INS_LEA, 4);
2387 }
2388 
d68000_link_16(m68k_info * info)2389 static void d68000_link_16(m68k_info *info)
2390 {
2391 	build_link(info, read_imm_16(info), 2);
2392 }
2393 
d68020_link_32(m68k_info * info)2394 static void d68020_link_32(m68k_info *info)
2395 {
2396 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2397 	build_link(info, read_imm_32(info), 4);
2398 }
2399 
d68000_lsr_s_8(m68k_info * info)2400 static void d68000_lsr_s_8(m68k_info *info)
2401 {
2402 	build_3bit_d(info, M68K_INS_LSR, 1);
2403 }
2404 
d68000_lsr_s_16(m68k_info * info)2405 static void d68000_lsr_s_16(m68k_info *info)
2406 {
2407 	build_3bit_d(info, M68K_INS_LSR, 2);
2408 }
2409 
d68000_lsr_s_32(m68k_info * info)2410 static void d68000_lsr_s_32(m68k_info *info)
2411 {
2412 	build_3bit_d(info, M68K_INS_LSR, 4);
2413 }
2414 
d68000_lsr_r_8(m68k_info * info)2415 static void d68000_lsr_r_8(m68k_info *info)
2416 {
2417 	build_r(info, M68K_INS_LSR, 1);
2418 }
2419 
d68000_lsr_r_16(m68k_info * info)2420 static void d68000_lsr_r_16(m68k_info *info)
2421 {
2422 	build_r(info, M68K_INS_LSR, 2);
2423 }
2424 
d68000_lsr_r_32(m68k_info * info)2425 static void d68000_lsr_r_32(m68k_info *info)
2426 {
2427 	build_r(info, M68K_INS_LSR, 4);
2428 }
2429 
d68000_lsr_ea(m68k_info * info)2430 static void d68000_lsr_ea(m68k_info *info)
2431 {
2432 	build_ea(info, M68K_INS_LSR, 2);
2433 }
2434 
d68000_lsl_s_8(m68k_info * info)2435 static void d68000_lsl_s_8(m68k_info *info)
2436 {
2437 	build_3bit_d(info, M68K_INS_LSL, 1);
2438 }
2439 
d68000_lsl_s_16(m68k_info * info)2440 static void d68000_lsl_s_16(m68k_info *info)
2441 {
2442 	build_3bit_d(info, M68K_INS_LSL, 2);
2443 }
2444 
d68000_lsl_s_32(m68k_info * info)2445 static void d68000_lsl_s_32(m68k_info *info)
2446 {
2447 	build_3bit_d(info, M68K_INS_LSL, 4);
2448 }
2449 
d68000_lsl_r_8(m68k_info * info)2450 static void d68000_lsl_r_8(m68k_info *info)
2451 {
2452 	build_r(info, M68K_INS_LSL, 1);
2453 }
2454 
d68000_lsl_r_16(m68k_info * info)2455 static void d68000_lsl_r_16(m68k_info *info)
2456 {
2457 	build_r(info, M68K_INS_LSL, 2);
2458 }
2459 
d68000_lsl_r_32(m68k_info * info)2460 static void d68000_lsl_r_32(m68k_info *info)
2461 {
2462 	build_r(info, M68K_INS_LSL, 4);
2463 }
2464 
d68000_lsl_ea(m68k_info * info)2465 static void d68000_lsl_ea(m68k_info *info)
2466 {
2467 	build_ea(info, M68K_INS_LSL, 2);
2468 }
2469 
d68000_move_8(m68k_info * info)2470 static void d68000_move_8(m68k_info *info)
2471 {
2472 	build_ea_ea(info, M68K_INS_MOVE, 1);
2473 }
2474 
d68000_move_16(m68k_info * info)2475 static void d68000_move_16(m68k_info *info)
2476 {
2477 	build_ea_ea(info, M68K_INS_MOVE, 2);
2478 }
2479 
d68000_move_32(m68k_info * info)2480 static void d68000_move_32(m68k_info *info)
2481 {
2482 	build_ea_ea(info, M68K_INS_MOVE, 4);
2483 }
2484 
d68000_movea_16(m68k_info * info)2485 static void d68000_movea_16(m68k_info *info)
2486 {
2487 	build_ea_a(info, M68K_INS_MOVEA, 2);
2488 }
2489 
d68000_movea_32(m68k_info * info)2490 static void d68000_movea_32(m68k_info *info)
2491 {
2492 	build_ea_a(info, M68K_INS_MOVEA, 4);
2493 }
2494 
d68000_move_to_ccr(m68k_info * info)2495 static void d68000_move_to_ccr(m68k_info *info)
2496 {
2497 	cs_m68k_op* op0;
2498 	cs_m68k_op* op1;
2499 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 2);
2500 
2501 	op0 = &ext->operands[0];
2502 	op1 = &ext->operands[1];
2503 
2504 	get_ea_mode_op(info, op0, info->ir, 1);
2505 
2506 	op1->address_mode = M68K_AM_NONE;
2507 	op1->reg = M68K_REG_CCR;
2508 }
2509 
d68010_move_fr_ccr(m68k_info * info)2510 static void d68010_move_fr_ccr(m68k_info *info)
2511 {
2512 	cs_m68k_op* op0;
2513 	cs_m68k_op* op1;
2514 	cs_m68k* ext;
2515 
2516 	LIMIT_CPU_TYPES(info, M68010_PLUS);
2517 
2518 	ext = build_init_op(info, M68K_INS_MOVE, 2, 2);
2519 
2520 	op0 = &ext->operands[0];
2521 	op1 = &ext->operands[1];
2522 
2523 	op0->address_mode = M68K_AM_NONE;
2524 	op0->reg = M68K_REG_CCR;
2525 
2526 	get_ea_mode_op(info, op1, info->ir, 1);
2527 }
2528 
d68000_move_fr_sr(m68k_info * info)2529 static void d68000_move_fr_sr(m68k_info *info)
2530 {
2531 	cs_m68k_op* op0;
2532 	cs_m68k_op* op1;
2533 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 2);
2534 
2535 	op0 = &ext->operands[0];
2536 	op1 = &ext->operands[1];
2537 
2538 	op0->address_mode = M68K_AM_NONE;
2539 	op0->reg = M68K_REG_SR;
2540 
2541 	get_ea_mode_op(info, op1, info->ir, 2);
2542 }
2543 
d68000_move_to_sr(m68k_info * info)2544 static void d68000_move_to_sr(m68k_info *info)
2545 {
2546 	cs_m68k_op* op0;
2547 	cs_m68k_op* op1;
2548 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 2);
2549 
2550 	op0 = &ext->operands[0];
2551 	op1 = &ext->operands[1];
2552 
2553 	get_ea_mode_op(info, op0, info->ir, 2);
2554 
2555 	op1->address_mode = M68K_AM_NONE;
2556 	op1->reg = M68K_REG_SR;
2557 }
2558 
d68000_move_fr_usp(m68k_info * info)2559 static void d68000_move_fr_usp(m68k_info *info)
2560 {
2561 	cs_m68k_op* op0;
2562 	cs_m68k_op* op1;
2563 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 0);
2564 
2565 	op0 = &ext->operands[0];
2566 	op1 = &ext->operands[1];
2567 
2568 	op0->address_mode = M68K_AM_NONE;
2569 	op0->reg = M68K_REG_USP;
2570 
2571 	op1->address_mode = M68K_AM_NONE;
2572 	op1->reg = M68K_REG_A0 + (info->ir & 7);
2573 }
2574 
d68000_move_to_usp(m68k_info * info)2575 static void d68000_move_to_usp(m68k_info *info)
2576 {
2577 	cs_m68k_op* op0;
2578 	cs_m68k_op* op1;
2579 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 0);
2580 
2581 	op0 = &ext->operands[0];
2582 	op1 = &ext->operands[1];
2583 
2584 	op0->address_mode = M68K_AM_NONE;
2585 	op0->reg = M68K_REG_A0 + (info->ir & 7);
2586 
2587 	op1->address_mode = M68K_AM_NONE;
2588 	op1->reg = M68K_REG_USP;
2589 }
2590 
d68010_movec(m68k_info * info)2591 static void d68010_movec(m68k_info *info)
2592 {
2593 	uint extension;
2594 	m68k_reg reg;
2595 	cs_m68k* ext;
2596 	cs_m68k_op* op0;
2597 	cs_m68k_op* op1;
2598 
2599 
2600 	LIMIT_CPU_TYPES(info, M68010_PLUS);
2601 
2602 	extension = read_imm_16(info);
2603 	reg = M68K_REG_INVALID;
2604 
2605 	ext = build_init_op(info, M68K_INS_MOVEC, 2, 0);
2606 
2607 	op0 = &ext->operands[0];
2608 	op1 = &ext->operands[1];
2609 
2610 	switch (extension & 0xfff) {
2611 		case 0x000: reg = M68K_REG_SFC; break;
2612 		case 0x001: reg = M68K_REG_DFC; break;
2613 		case 0x800: reg = M68K_REG_USP; break;
2614 		case 0x801: reg = M68K_REG_VBR; break;
2615 		case 0x002: reg = M68K_REG_CACR; break;
2616 		case 0x802: reg = M68K_REG_CAAR; break;
2617 		case 0x803: reg = M68K_REG_MSP; break;
2618 		case 0x804: reg = M68K_REG_ISP; break;
2619 		case 0x003: reg = M68K_REG_TC; break;
2620 		case 0x004: reg = M68K_REG_ITT0; break;
2621 		case 0x005: reg = M68K_REG_ITT1; break;
2622 		case 0x006: reg = M68K_REG_DTT0; break;
2623 		case 0x007: reg = M68K_REG_DTT1; break;
2624 		case 0x805: reg = M68K_REG_MMUSR; break;
2625 		case 0x806: reg = M68K_REG_URP; break;
2626 		case 0x807: reg = M68K_REG_SRP; break;
2627 	}
2628 
2629 	if (BIT_1(info->ir)) {
2630 		op0->reg = (BIT_F(extension) ? M68K_REG_A0 : M68K_REG_D0) + ((extension >> 12) & 7);
2631 		op1->reg = reg;
2632 	} else {
2633 		op0->reg = reg;
2634 		op1->reg = (BIT_F(extension) ? M68K_REG_A0 : M68K_REG_D0) + ((extension >> 12) & 7);
2635 	}
2636 }
2637 
d68000_movem_pd_16(m68k_info * info)2638 static void d68000_movem_pd_16(m68k_info *info)
2639 {
2640 	build_movem_re(info, M68K_INS_MOVEM, 2);
2641 }
2642 
d68000_movem_pd_32(m68k_info * info)2643 static void d68000_movem_pd_32(m68k_info *info)
2644 {
2645 	build_movem_re(info, M68K_INS_MOVEM, 4);
2646 }
2647 
d68000_movem_er_16(m68k_info * info)2648 static void d68000_movem_er_16(m68k_info *info)
2649 {
2650 	build_movem_er(info, M68K_INS_MOVEM, 2);
2651 }
2652 
d68000_movem_er_32(m68k_info * info)2653 static void d68000_movem_er_32(m68k_info *info)
2654 {
2655 	build_movem_er(info, M68K_INS_MOVEM, 4);
2656 }
2657 
d68000_movem_re_16(m68k_info * info)2658 static void d68000_movem_re_16(m68k_info *info)
2659 {
2660 	build_movem_re(info, M68K_INS_MOVEM, 2);
2661 }
2662 
d68000_movem_re_32(m68k_info * info)2663 static void d68000_movem_re_32(m68k_info *info)
2664 {
2665 	build_movem_re(info, M68K_INS_MOVEM, 4);
2666 }
2667 
d68000_movep_re_16(m68k_info * info)2668 static void d68000_movep_re_16(m68k_info *info)
2669 {
2670 	build_movep_re(info, 2);
2671 }
2672 
d68000_movep_re_32(m68k_info * info)2673 static void d68000_movep_re_32(m68k_info *info)
2674 {
2675 	build_movep_re(info, 4);
2676 }
2677 
d68000_movep_er_16(m68k_info * info)2678 static void d68000_movep_er_16(m68k_info *info)
2679 {
2680 	build_movep_er(info, 2);
2681 }
2682 
d68000_movep_er_32(m68k_info * info)2683 static void d68000_movep_er_32(m68k_info *info)
2684 {
2685 	build_movep_er(info, 4);
2686 }
2687 
d68010_moves_8(m68k_info * info)2688 static void d68010_moves_8(m68k_info *info)
2689 {
2690 	LIMIT_CPU_TYPES(info, M68010_PLUS);
2691 	build_moves(info, 1);
2692 }
2693 
d68010_moves_16(m68k_info * info)2694 static void d68010_moves_16(m68k_info *info)
2695 {
2696 	//uint extension;
2697 	LIMIT_CPU_TYPES(info, M68010_PLUS);
2698 	build_moves(info, 2);
2699 }
2700 
d68010_moves_32(m68k_info * info)2701 static void d68010_moves_32(m68k_info *info)
2702 {
2703 	LIMIT_CPU_TYPES(info, M68010_PLUS);
2704 	build_moves(info, 4);
2705 }
2706 
d68000_moveq(m68k_info * info)2707 static void d68000_moveq(m68k_info *info)
2708 {
2709 	cs_m68k_op* op0;
2710 	cs_m68k_op* op1;
2711 
2712 	cs_m68k* ext = build_init_op(info, M68K_INS_MOVEQ, 2, 0);
2713 
2714 	op0 = &ext->operands[0];
2715 	op1 = &ext->operands[1];
2716 
2717 	op0->type = M68K_OP_IMM;
2718 	op0->address_mode = M68K_AM_IMMEDIATE;
2719 	op0->imm = (info->ir & 0xff);
2720 
2721 	op1->address_mode = M68K_AM_REG_DIRECT_DATA;
2722 	op1->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
2723 }
2724 
d68040_move16_pi_pi(m68k_info * info)2725 static void d68040_move16_pi_pi(m68k_info *info)
2726 {
2727 	int data[] = { info->ir & 7, (read_imm_16(info) >> 12) & 7 };
2728 	int modes[] = { M68K_AM_REGI_ADDR_POST_INC, M68K_AM_REGI_ADDR_POST_INC };
2729 
2730 	LIMIT_CPU_TYPES(info, M68040_PLUS);
2731 
2732 	build_move16(info, data, modes);
2733 }
2734 
d68040_move16_pi_al(m68k_info * info)2735 static void d68040_move16_pi_al(m68k_info *info)
2736 {
2737 	int data[] = { info->ir & 7, read_imm_32(info) };
2738 	int modes[] = { M68K_AM_REGI_ADDR_POST_INC, M68K_AM_ABSOLUTE_DATA_LONG };
2739 
2740 	LIMIT_CPU_TYPES(info, M68040_PLUS);
2741 
2742 	build_move16(info, data, modes);
2743 }
2744 
d68040_move16_al_pi(m68k_info * info)2745 static void d68040_move16_al_pi(m68k_info *info)
2746 {
2747 	int data[] = { read_imm_32(info), info->ir & 7 };
2748 	int modes[] = { M68K_AM_ABSOLUTE_DATA_LONG, M68K_AM_REGI_ADDR_POST_INC };
2749 
2750 	LIMIT_CPU_TYPES(info, M68040_PLUS);
2751 
2752 	build_move16(info, data, modes);
2753 }
2754 
d68040_move16_ai_al(m68k_info * info)2755 static void d68040_move16_ai_al(m68k_info *info)
2756 {
2757 	int data[] = { info->ir & 7, read_imm_32(info) };
2758 	int modes[] = { M68K_AM_REG_DIRECT_ADDR, M68K_AM_ABSOLUTE_DATA_LONG };
2759 
2760 	LIMIT_CPU_TYPES(info, M68040_PLUS);
2761 
2762 	build_move16(info, data, modes);
2763 }
2764 
d68040_move16_al_ai(m68k_info * info)2765 static void d68040_move16_al_ai(m68k_info *info)
2766 {
2767 	int data[] = { read_imm_32(info), info->ir & 7 };
2768 	int modes[] = { M68K_AM_ABSOLUTE_DATA_LONG, M68K_AM_REG_DIRECT_ADDR };
2769 
2770 	LIMIT_CPU_TYPES(info, M68040_PLUS);
2771 
2772 	build_move16(info, data, modes);
2773 }
2774 
d68000_muls(m68k_info * info)2775 static void d68000_muls(m68k_info *info)
2776 {
2777 	build_er_1(info, M68K_INS_MULS, 2);
2778 }
2779 
d68000_mulu(m68k_info * info)2780 static void d68000_mulu(m68k_info *info)
2781 {
2782 	build_er_1(info, M68K_INS_MULU, 2);
2783 }
2784 
d68020_mull(m68k_info * info)2785 static void d68020_mull(m68k_info *info)
2786 {
2787 	uint extension, insn_signed;
2788 	cs_m68k* ext;
2789 	cs_m68k_op* op0;
2790 	cs_m68k_op* op1;
2791 	uint reg_0, reg_1;
2792 
2793 
2794 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2795 
2796 	extension = read_imm_16(info);
2797 	insn_signed = 0;
2798 
2799 	if (BIT_B((extension)))
2800 		insn_signed = 1;
2801 
2802 	ext = build_init_op(info, insn_signed ? M68K_INS_MULS : M68K_INS_MULU, 2, 4);
2803 
2804 	op0 = &ext->operands[0];
2805 	op1 = &ext->operands[1];
2806 
2807 	get_ea_mode_op(info, op0, info->ir, 4);
2808 
2809 	reg_0 = extension & 7;
2810 	reg_1 = (extension >> 12) & 7;
2811 
2812 	op1->address_mode = M68K_AM_NONE;
2813 	op1->type = M68K_OP_REG_PAIR;
2814 	op1->reg_pair.reg_0 = reg_0;
2815 	op1->reg_pair.reg_1 = reg_1;
2816 
2817 	if (!BIT_A(extension)) {
2818 		op1->type = M68K_OP_REG;
2819 		op1->reg = M68K_REG_D0 + reg_1;
2820 	}
2821 }
2822 
d68000_nbcd(m68k_info * info)2823 static void d68000_nbcd(m68k_info *info)
2824 {
2825 	build_ea(info, M68K_INS_NBCD, 1);
2826 }
2827 
d68000_neg_8(m68k_info * info)2828 static void d68000_neg_8(m68k_info *info)
2829 {
2830 	build_ea(info, M68K_INS_NEG, 1);
2831 }
2832 
d68000_neg_16(m68k_info * info)2833 static void d68000_neg_16(m68k_info *info)
2834 {
2835 	build_ea(info, M68K_INS_NEG, 2);
2836 }
2837 
d68000_neg_32(m68k_info * info)2838 static void d68000_neg_32(m68k_info *info)
2839 {
2840 	build_ea(info, M68K_INS_NEG, 4);
2841 }
2842 
d68000_negx_8(m68k_info * info)2843 static void d68000_negx_8(m68k_info *info)
2844 {
2845 	build_ea(info, M68K_INS_NEGX, 1);
2846 }
2847 
d68000_negx_16(m68k_info * info)2848 static void d68000_negx_16(m68k_info *info)
2849 {
2850 	build_ea(info, M68K_INS_NEGX, 2);
2851 }
2852 
d68000_negx_32(m68k_info * info)2853 static void d68000_negx_32(m68k_info *info)
2854 {
2855 	build_ea(info, M68K_INS_NEGX, 4);
2856 }
2857 
d68000_nop(m68k_info * info)2858 static void d68000_nop(m68k_info *info)
2859 {
2860 	MCInst_setOpcode(info->inst, M68K_INS_NOP);
2861 }
2862 
d68000_not_8(m68k_info * info)2863 static void d68000_not_8(m68k_info *info)
2864 {
2865 	build_ea(info, M68K_INS_NOT, 1);
2866 }
2867 
d68000_not_16(m68k_info * info)2868 static void d68000_not_16(m68k_info *info)
2869 {
2870 	build_ea(info, M68K_INS_NOT, 2);
2871 }
2872 
d68000_not_32(m68k_info * info)2873 static void d68000_not_32(m68k_info *info)
2874 {
2875 	build_ea(info, M68K_INS_NOT, 4);
2876 }
2877 
d68000_or_er_8(m68k_info * info)2878 static void d68000_or_er_8(m68k_info *info)
2879 {
2880 	build_er_1(info, M68K_INS_OR, 1);
2881 }
2882 
d68000_or_er_16(m68k_info * info)2883 static void d68000_or_er_16(m68k_info *info)
2884 {
2885 	build_er_1(info, M68K_INS_OR, 2);
2886 }
2887 
d68000_or_er_32(m68k_info * info)2888 static void d68000_or_er_32(m68k_info *info)
2889 {
2890 	build_er_1(info, M68K_INS_OR, 4);
2891 }
2892 
d68000_or_re_8(m68k_info * info)2893 static void d68000_or_re_8(m68k_info *info)
2894 {
2895 	build_re_1(info, M68K_INS_OR, 1);
2896 }
2897 
d68000_or_re_16(m68k_info * info)2898 static void d68000_or_re_16(m68k_info *info)
2899 {
2900 	build_re_1(info, M68K_INS_OR, 2);
2901 }
2902 
d68000_or_re_32(m68k_info * info)2903 static void d68000_or_re_32(m68k_info *info)
2904 {
2905 	build_re_1(info, M68K_INS_OR, 4);
2906 }
2907 
d68000_ori_8(m68k_info * info)2908 static void d68000_ori_8(m68k_info *info)
2909 {
2910 	build_imm_ea(info, M68K_INS_ORI, 1, read_imm_8(info));
2911 }
2912 
d68000_ori_16(m68k_info * info)2913 static void d68000_ori_16(m68k_info *info)
2914 {
2915 	build_imm_ea(info, M68K_INS_ORI, 2, read_imm_16(info));
2916 }
2917 
d68000_ori_32(m68k_info * info)2918 static void d68000_ori_32(m68k_info *info)
2919 {
2920 	build_imm_ea(info, M68K_INS_ORI, 4, read_imm_32(info));
2921 }
2922 
d68000_ori_to_ccr(m68k_info * info)2923 static void d68000_ori_to_ccr(m68k_info *info)
2924 {
2925 	build_imm_special_reg(info, M68K_INS_ORI, read_imm_8(info), 1, M68K_REG_CCR);
2926 }
2927 
d68000_ori_to_sr(m68k_info * info)2928 static void d68000_ori_to_sr(m68k_info *info)
2929 {
2930 	build_imm_special_reg(info, M68K_INS_ORI, read_imm_16(info), 2, M68K_REG_SR);
2931 }
2932 
d68020_pack_rr(m68k_info * info)2933 static void d68020_pack_rr(m68k_info *info)
2934 {
2935 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2936 	build_rr(info, M68K_INS_PACK, 0, read_imm_16(info));
2937 }
2938 
d68020_pack_mm(m68k_info * info)2939 static void d68020_pack_mm(m68k_info *info)
2940 {
2941 	LIMIT_CPU_TYPES(info, M68020_PLUS);
2942 	build_mm(info, M68K_INS_PACK, 0, read_imm_16(info));
2943 }
2944 
d68000_pea(m68k_info * info)2945 static void d68000_pea(m68k_info *info)
2946 {
2947 	build_ea(info, M68K_INS_PEA, 4);
2948 }
2949 
d68000_reset(m68k_info * info)2950 static void d68000_reset(m68k_info *info)
2951 {
2952 	MCInst_setOpcode(info->inst, M68K_INS_RESET);
2953 }
2954 
d68000_ror_s_8(m68k_info * info)2955 static void d68000_ror_s_8(m68k_info *info)
2956 {
2957 	build_3bit_d(info, M68K_INS_ROR, 1);
2958 }
2959 
d68000_ror_s_16(m68k_info * info)2960 static void d68000_ror_s_16(m68k_info *info)
2961 {
2962 	build_3bit_d(info, M68K_INS_ROR, 2);
2963 }
2964 
d68000_ror_s_32(m68k_info * info)2965 static void d68000_ror_s_32(m68k_info *info)
2966 {
2967 	build_3bit_d(info, M68K_INS_ROR, 4);
2968 }
2969 
d68000_ror_r_8(m68k_info * info)2970 static void d68000_ror_r_8(m68k_info *info)
2971 {
2972 	build_r(info, M68K_INS_ROR, 1);
2973 }
2974 
d68000_ror_r_16(m68k_info * info)2975 static void d68000_ror_r_16(m68k_info *info)
2976 {
2977 	build_r(info, M68K_INS_ROR, 2);
2978 }
2979 
d68000_ror_r_32(m68k_info * info)2980 static void d68000_ror_r_32(m68k_info *info)
2981 {
2982 	build_r(info, M68K_INS_ROR, 4);
2983 }
2984 
d68000_ror_ea(m68k_info * info)2985 static void d68000_ror_ea(m68k_info *info)
2986 {
2987 	build_ea(info, M68K_INS_ROR, 2);
2988 }
2989 
d68000_rol_s_8(m68k_info * info)2990 static void d68000_rol_s_8(m68k_info *info)
2991 {
2992 	build_3bit_d(info, M68K_INS_ROL, 1);
2993 }
2994 
d68000_rol_s_16(m68k_info * info)2995 static void d68000_rol_s_16(m68k_info *info)
2996 {
2997 	build_3bit_d(info, M68K_INS_ROL, 2);
2998 }
2999 
d68000_rol_s_32(m68k_info * info)3000 static void d68000_rol_s_32(m68k_info *info)
3001 {
3002 	build_3bit_d(info, M68K_INS_ROL, 4);
3003 }
3004 
d68000_rol_r_8(m68k_info * info)3005 static void d68000_rol_r_8(m68k_info *info)
3006 {
3007 	build_r(info, M68K_INS_ROL, 1);
3008 }
3009 
d68000_rol_r_16(m68k_info * info)3010 static void d68000_rol_r_16(m68k_info *info)
3011 {
3012 	build_r(info, M68K_INS_ROL, 2);
3013 }
3014 
d68000_rol_r_32(m68k_info * info)3015 static void d68000_rol_r_32(m68k_info *info)
3016 {
3017 	build_r(info, M68K_INS_ROL, 4);
3018 }
3019 
d68000_rol_ea(m68k_info * info)3020 static void d68000_rol_ea(m68k_info *info)
3021 {
3022 	build_ea(info, M68K_INS_ROL, 2);
3023 }
3024 
d68000_roxr_s_8(m68k_info * info)3025 static void d68000_roxr_s_8(m68k_info *info)
3026 {
3027 	build_3bit_d(info, M68K_INS_ROXR, 1);
3028 }
3029 
d68000_roxr_s_16(m68k_info * info)3030 static void d68000_roxr_s_16(m68k_info *info)
3031 {
3032 	build_3bit_d(info, M68K_INS_ROXR, 2);
3033 }
3034 
d68000_roxr_s_32(m68k_info * info)3035 static void d68000_roxr_s_32(m68k_info *info)
3036 {
3037 	build_3bit_d(info, M68K_INS_ROXR, 4);
3038 }
3039 
d68000_roxr_r_8(m68k_info * info)3040 static void d68000_roxr_r_8(m68k_info *info)
3041 {
3042 	build_3bit_d(info, M68K_INS_ROXR, 4);
3043 }
3044 
d68000_roxr_r_16(m68k_info * info)3045 static void d68000_roxr_r_16(m68k_info *info)
3046 {
3047 	build_r(info, M68K_INS_ROXR, 2);
3048 }
3049 
d68000_roxr_r_32(m68k_info * info)3050 static void d68000_roxr_r_32(m68k_info *info)
3051 {
3052 	build_r(info, M68K_INS_ROXR, 4);
3053 }
3054 
d68000_roxr_ea(m68k_info * info)3055 static void d68000_roxr_ea(m68k_info *info)
3056 {
3057 	build_ea(info, M68K_INS_ROXR, 2);
3058 }
3059 
d68000_roxl_s_8(m68k_info * info)3060 static void d68000_roxl_s_8(m68k_info *info)
3061 {
3062 	build_3bit_d(info, M68K_INS_ROXL, 1);
3063 }
3064 
d68000_roxl_s_16(m68k_info * info)3065 static void d68000_roxl_s_16(m68k_info *info)
3066 {
3067 	build_3bit_d(info, M68K_INS_ROXL, 2);
3068 }
3069 
d68000_roxl_s_32(m68k_info * info)3070 static void d68000_roxl_s_32(m68k_info *info)
3071 {
3072 	build_3bit_d(info, M68K_INS_ROXL, 4);
3073 }
3074 
d68000_roxl_r_8(m68k_info * info)3075 static void d68000_roxl_r_8(m68k_info *info)
3076 {
3077 	build_r(info, M68K_INS_ROXL, 1);
3078 }
3079 
d68000_roxl_r_16(m68k_info * info)3080 static void d68000_roxl_r_16(m68k_info *info)
3081 {
3082 	build_r(info, M68K_INS_ROXL, 2);
3083 }
3084 
d68000_roxl_r_32(m68k_info * info)3085 static void d68000_roxl_r_32(m68k_info *info)
3086 {
3087 	build_r(info, M68K_INS_ROXL, 4);
3088 }
3089 
d68000_roxl_ea(m68k_info * info)3090 static void d68000_roxl_ea(m68k_info *info)
3091 {
3092 	build_ea(info, M68K_INS_ROXL, 2);
3093 }
3094 
d68010_rtd(m68k_info * info)3095 static void d68010_rtd(m68k_info *info)
3096 {
3097 	set_insn_group(info, M68K_GRP_RET);
3098 	LIMIT_CPU_TYPES(info, M68010_PLUS);
3099 	build_absolute_jump_with_immediate(info, M68K_INS_RTD, 0, read_imm_16(info));
3100 }
3101 
d68000_rte(m68k_info * info)3102 static void d68000_rte(m68k_info *info)
3103 {
3104 	set_insn_group(info, M68K_GRP_IRET);
3105 	MCInst_setOpcode(info->inst, M68K_INS_RTE);
3106 }
3107 
d68020_rtm(m68k_info * info)3108 static void d68020_rtm(m68k_info *info)
3109 {
3110 	cs_m68k* ext;
3111 	cs_m68k_op* op;
3112 
3113 	set_insn_group(info, M68K_GRP_RET);
3114 
3115 	LIMIT_CPU_TYPES(info, M68020_ONLY);
3116 
3117 	build_absolute_jump_with_immediate(info, M68K_INS_RTM, 0, 0);
3118 
3119 	ext = &info->extension;
3120 	op = &ext->operands[0];
3121 
3122 	op->address_mode = M68K_AM_NONE;
3123 	op->type = M68K_OP_REG;
3124 
3125 	if (BIT_3(info->ir)) {
3126 		op->reg = M68K_REG_A0 + (info->ir & 7);
3127 	} else {
3128 		op->reg = M68K_REG_D0 + (info->ir & 7);
3129 	}
3130 }
3131 
d68000_rtr(m68k_info * info)3132 static void d68000_rtr(m68k_info *info)
3133 {
3134 	set_insn_group(info, M68K_GRP_RET);
3135 	MCInst_setOpcode(info->inst, M68K_INS_RTR);
3136 }
3137 
d68000_rts(m68k_info * info)3138 static void d68000_rts(m68k_info *info)
3139 {
3140 	set_insn_group(info, M68K_GRP_RET);
3141 	MCInst_setOpcode(info->inst, M68K_INS_RTS);
3142 }
3143 
d68000_sbcd_rr(m68k_info * info)3144 static void d68000_sbcd_rr(m68k_info *info)
3145 {
3146 	build_rr(info, M68K_INS_SBCD, 1, 0);
3147 }
3148 
d68000_sbcd_mm(m68k_info * info)3149 static void d68000_sbcd_mm(m68k_info *info)
3150 {
3151 	build_mm(info, M68K_INS_SBCD, 0, read_imm_16(info));
3152 }
3153 
d68000_scc(m68k_info * info)3154 static void d68000_scc(m68k_info *info)
3155 {
3156 	cs_m68k* ext = build_init_op(info, s_scc_lut[(info->ir >> 8) & 0xf], 1, 1);
3157 	get_ea_mode_op(info, &ext->operands[0], info->ir, 1);
3158 }
3159 
d68000_stop(m68k_info * info)3160 static void d68000_stop(m68k_info *info)
3161 {
3162 	build_absolute_jump_with_immediate(info, M68K_INS_STOP, 0, read_imm_16(info));
3163 }
3164 
d68000_sub_er_8(m68k_info * info)3165 static void d68000_sub_er_8(m68k_info *info)
3166 {
3167 	build_er_1(info, M68K_INS_SUB, 1);
3168 }
3169 
d68000_sub_er_16(m68k_info * info)3170 static void d68000_sub_er_16(m68k_info *info)
3171 {
3172 	build_er_1(info, M68K_INS_SUB, 2);
3173 }
3174 
d68000_sub_er_32(m68k_info * info)3175 static void d68000_sub_er_32(m68k_info *info)
3176 {
3177 	build_er_1(info, M68K_INS_SUB, 4);
3178 }
3179 
d68000_sub_re_8(m68k_info * info)3180 static void d68000_sub_re_8(m68k_info *info)
3181 {
3182 	build_re_1(info, M68K_INS_SUB, 1);
3183 }
3184 
d68000_sub_re_16(m68k_info * info)3185 static void d68000_sub_re_16(m68k_info *info)
3186 {
3187 	build_re_1(info, M68K_INS_SUB, 2);
3188 }
3189 
d68000_sub_re_32(m68k_info * info)3190 static void d68000_sub_re_32(m68k_info *info)
3191 {
3192 	build_re_1(info, M68K_INS_SUB, 4);
3193 }
3194 
d68000_suba_16(m68k_info * info)3195 static void d68000_suba_16(m68k_info *info)
3196 {
3197 	build_ea_a(info, M68K_INS_SUBA, 2);
3198 }
3199 
d68000_suba_32(m68k_info * info)3200 static void d68000_suba_32(m68k_info *info)
3201 {
3202 	build_ea_a(info, M68K_INS_SUBA, 4);
3203 }
3204 
d68000_subi_8(m68k_info * info)3205 static void d68000_subi_8(m68k_info *info)
3206 {
3207 	build_imm_ea(info, M68K_INS_SUBI, 1, read_imm_8(info));
3208 }
3209 
d68000_subi_16(m68k_info * info)3210 static void d68000_subi_16(m68k_info *info)
3211 {
3212 	build_imm_ea(info, M68K_INS_SUBI, 2, read_imm_16(info));
3213 }
3214 
d68000_subi_32(m68k_info * info)3215 static void d68000_subi_32(m68k_info *info)
3216 {
3217 	build_imm_ea(info, M68K_INS_SUBI, 4, read_imm_32(info));
3218 }
3219 
d68000_subq_8(m68k_info * info)3220 static void d68000_subq_8(m68k_info *info)
3221 {
3222 	build_3bit_ea(info, M68K_INS_SUBQ, 1);
3223 }
3224 
d68000_subq_16(m68k_info * info)3225 static void d68000_subq_16(m68k_info *info)
3226 {
3227 	build_3bit_ea(info, M68K_INS_SUBQ, 2);
3228 }
3229 
d68000_subq_32(m68k_info * info)3230 static void d68000_subq_32(m68k_info *info)
3231 {
3232 	build_3bit_ea(info, M68K_INS_SUBQ, 4);
3233 }
3234 
d68000_subx_rr_8(m68k_info * info)3235 static void d68000_subx_rr_8(m68k_info *info)
3236 {
3237 	build_rr(info, M68K_INS_SUBX, 1, 0);
3238 }
3239 
d68000_subx_rr_16(m68k_info * info)3240 static void d68000_subx_rr_16(m68k_info *info)
3241 {
3242 	build_rr(info, M68K_INS_SUBX, 2, 0);
3243 }
3244 
d68000_subx_rr_32(m68k_info * info)3245 static void d68000_subx_rr_32(m68k_info *info)
3246 {
3247 	build_rr(info, M68K_INS_SUBX, 4, 0);
3248 }
3249 
d68000_subx_mm_8(m68k_info * info)3250 static void d68000_subx_mm_8(m68k_info *info)
3251 {
3252 	build_mm(info, M68K_INS_SUBX, 1, 0);
3253 }
3254 
d68000_subx_mm_16(m68k_info * info)3255 static void d68000_subx_mm_16(m68k_info *info)
3256 {
3257 	build_mm(info, M68K_INS_SUBX, 2, 0);
3258 }
3259 
d68000_subx_mm_32(m68k_info * info)3260 static void d68000_subx_mm_32(m68k_info *info)
3261 {
3262 	build_mm(info, M68K_INS_SUBX, 4, 0);
3263 }
3264 
d68000_swap(m68k_info * info)3265 static void d68000_swap(m68k_info *info)
3266 {
3267 	build_d(info, M68K_INS_SWAP, 0);
3268 }
3269 
d68000_tas(m68k_info * info)3270 static void d68000_tas(m68k_info *info)
3271 {
3272 	build_ea(info, M68K_INS_TAS, 1);
3273 }
3274 
d68000_trap(m68k_info * info)3275 static void d68000_trap(m68k_info *info)
3276 {
3277 	build_absolute_jump_with_immediate(info, M68K_INS_TRAP, 0, info->ir&0xf);
3278 }
3279 
d68020_trapcc_0(m68k_info * info)3280 static void d68020_trapcc_0(m68k_info *info)
3281 {
3282 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3283 	build_trap(info, 0, 0);
3284 
3285 	info->extension.op_count = 0;
3286 }
3287 
d68020_trapcc_16(m68k_info * info)3288 static void d68020_trapcc_16(m68k_info *info)
3289 {
3290 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3291 	build_trap(info, 2, read_imm_16(info));
3292 }
3293 
d68020_trapcc_32(m68k_info * info)3294 static void d68020_trapcc_32(m68k_info *info)
3295 {
3296 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3297 	build_trap(info, 4, read_imm_32(info));
3298 }
3299 
d68000_trapv(m68k_info * info)3300 static void d68000_trapv(m68k_info *info)
3301 {
3302 	MCInst_setOpcode(info->inst, M68K_INS_TRAPV);
3303 }
3304 
d68000_tst_8(m68k_info * info)3305 static void d68000_tst_8(m68k_info *info)
3306 {
3307 	build_ea(info, M68K_INS_TST, 1);
3308 }
3309 
d68020_tst_pcdi_8(m68k_info * info)3310 static void d68020_tst_pcdi_8(m68k_info *info)
3311 {
3312 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3313 	build_ea(info, M68K_INS_TST, 1);
3314 }
3315 
d68020_tst_pcix_8(m68k_info * info)3316 static void d68020_tst_pcix_8(m68k_info *info)
3317 {
3318 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3319 	build_ea(info, M68K_INS_TST, 1);
3320 }
3321 
d68020_tst_i_8(m68k_info * info)3322 static void d68020_tst_i_8(m68k_info *info)
3323 {
3324 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3325 	build_ea(info, M68K_INS_TST, 1);
3326 }
3327 
d68000_tst_16(m68k_info * info)3328 static void d68000_tst_16(m68k_info *info)
3329 {
3330 	build_ea(info, M68K_INS_TST, 2);
3331 }
3332 
d68020_tst_a_16(m68k_info * info)3333 static void d68020_tst_a_16(m68k_info *info)
3334 {
3335 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3336 	build_ea(info, M68K_INS_TST, 2);
3337 }
3338 
d68020_tst_pcdi_16(m68k_info * info)3339 static void d68020_tst_pcdi_16(m68k_info *info)
3340 {
3341 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3342 	build_ea(info, M68K_INS_TST, 2);
3343 }
3344 
d68020_tst_pcix_16(m68k_info * info)3345 static void d68020_tst_pcix_16(m68k_info *info)
3346 {
3347 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3348 	build_ea(info, M68K_INS_TST, 2);
3349 }
3350 
d68020_tst_i_16(m68k_info * info)3351 static void d68020_tst_i_16(m68k_info *info)
3352 {
3353 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3354 	build_ea(info, M68K_INS_TST, 2);
3355 }
3356 
d68000_tst_32(m68k_info * info)3357 static void d68000_tst_32(m68k_info *info)
3358 {
3359 	build_ea(info, M68K_INS_TST, 4);
3360 }
3361 
d68020_tst_a_32(m68k_info * info)3362 static void d68020_tst_a_32(m68k_info *info)
3363 {
3364 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3365 	build_ea(info, M68K_INS_TST, 4);
3366 }
3367 
d68020_tst_pcdi_32(m68k_info * info)3368 static void d68020_tst_pcdi_32(m68k_info *info)
3369 {
3370 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3371 	build_ea(info, M68K_INS_TST, 4);
3372 }
3373 
d68020_tst_pcix_32(m68k_info * info)3374 static void d68020_tst_pcix_32(m68k_info *info)
3375 {
3376 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3377 	build_ea(info, M68K_INS_TST, 4);
3378 }
3379 
d68020_tst_i_32(m68k_info * info)3380 static void d68020_tst_i_32(m68k_info *info)
3381 {
3382 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3383 	build_ea(info, M68K_INS_TST, 4);
3384 }
3385 
d68000_unlk(m68k_info * info)3386 static void d68000_unlk(m68k_info *info)
3387 {
3388 	cs_m68k_op* op;
3389 	cs_m68k* ext = build_init_op(info, M68K_INS_UNLK, 1, 0);
3390 
3391 	op = &ext->operands[0];
3392 
3393 	op->address_mode = M68K_AM_REG_DIRECT_ADDR;
3394 	op->reg = M68K_REG_A0 + (info->ir & 7);
3395 }
3396 
d68020_unpk_rr(m68k_info * info)3397 static void d68020_unpk_rr(m68k_info *info)
3398 {
3399 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3400 	build_rr(info, M68K_INS_UNPK, 0, read_imm_16(info));
3401 }
3402 
d68020_unpk_mm(m68k_info * info)3403 static void d68020_unpk_mm(m68k_info *info)
3404 {
3405 	LIMIT_CPU_TYPES(info, M68020_PLUS);
3406 	build_mm(info, M68K_INS_UNPK, 0, read_imm_16(info));
3407 }
3408 
3409 /* ======================================================================== */
3410 /* ======================= INSTRUCTION TABLE BUILDER ====================== */
3411 /* ======================================================================== */
3412 
3413 /* EA Masks:
3414    800 = data register direct
3415    400 = address register direct
3416    200 = address register indirect
3417    100 = ARI postincrement
3418    80 = ARI pre-decrement
3419    40 = ARI displacement
3420    20 = ARI index
3421    10 = absolute short
3422    8 = absolute long
3423    4 = immediate / sr
3424    2 = pc displacement
3425    1 = pc idx
3426  */
3427 
3428 static opcode_struct g_opcode_info[] = {
3429 	/*  opcode handler         mask    match   ea_mask   mask2   match2*/
3430 	{d68000_1010         , 0xf000, 0xa000, 0x000},
3431 	{d68000_1111         , 0xf000, 0xf000, 0x000},
3432 	{d68000_abcd_rr      , 0xf1f8, 0xc100, 0x000},
3433 	{d68000_abcd_mm      , 0xf1f8, 0xc108, 0x000},
3434 	{d68000_add_er_8     , 0xf1c0, 0xd000, 0xbff},
3435 	{d68000_add_er_16    , 0xf1c0, 0xd040, 0xfff},
3436 	{d68000_add_er_32    , 0xf1c0, 0xd080, 0xfff},
3437 	{d68000_add_re_8     , 0xf1c0, 0xd100, 0x3f8},
3438 	{d68000_add_re_16    , 0xf1c0, 0xd140, 0x3f8},
3439 	{d68000_add_re_32    , 0xf1c0, 0xd180, 0x3f8},
3440 	{d68000_adda_16      , 0xf1c0, 0xd0c0, 0xfff},
3441 	{d68000_adda_32      , 0xf1c0, 0xd1c0, 0xfff},
3442 	{d68000_addi_8       , 0xffc0, 0x0600, 0xbf8},
3443 	{d68000_addi_16      , 0xffc0, 0x0640, 0xbf8},
3444 	{d68000_addi_32      , 0xffc0, 0x0680, 0xbf8},
3445 	{d68000_addq_8       , 0xf1c0, 0x5000, 0xbf8},
3446 	{d68000_addq_16      , 0xf1c0, 0x5040, 0xff8},
3447 	{d68000_addq_32      , 0xf1c0, 0x5080, 0xff8},
3448 	{d68000_addx_rr_8    , 0xf1f8, 0xd100, 0x000},
3449 	{d68000_addx_rr_16   , 0xf1f8, 0xd140, 0x000},
3450 	{d68000_addx_rr_32   , 0xf1f8, 0xd180, 0x000},
3451 	{d68000_addx_mm_8    , 0xf1f8, 0xd108, 0x000},
3452 	{d68000_addx_mm_16   , 0xf1f8, 0xd148, 0x000},
3453 	{d68000_addx_mm_32   , 0xf1f8, 0xd188, 0x000},
3454 	{d68000_and_er_8     , 0xf1c0, 0xc000, 0xbff},
3455 	{d68000_and_er_16    , 0xf1c0, 0xc040, 0xbff},
3456 	{d68000_and_er_32    , 0xf1c0, 0xc080, 0xbff},
3457 	{d68000_and_re_8     , 0xf1c0, 0xc100, 0x3f8},
3458 	{d68000_and_re_16    , 0xf1c0, 0xc140, 0x3f8},
3459 	{d68000_and_re_32    , 0xf1c0, 0xc180, 0x3f8},
3460 	{d68000_andi_to_ccr  , 0xffff, 0x023c, 0x000, 0xff00, 0x0000},
3461 	{d68000_andi_to_sr   , 0xffff, 0x027c, 0x000},
3462 	{d68000_andi_8       , 0xffc0, 0x0200, 0xbf8},
3463 	{d68000_andi_16      , 0xffc0, 0x0240, 0xbf8},
3464 	{d68000_andi_32      , 0xffc0, 0x0280, 0xbf8},
3465 	{d68000_asr_s_8      , 0xf1f8, 0xe000, 0x000},
3466 	{d68000_asr_s_16     , 0xf1f8, 0xe040, 0x000},
3467 	{d68000_asr_s_32     , 0xf1f8, 0xe080, 0x000},
3468 	{d68000_asr_r_8      , 0xf1f8, 0xe020, 0x000},
3469 	{d68000_asr_r_16     , 0xf1f8, 0xe060, 0x000},
3470 	{d68000_asr_r_32     , 0xf1f8, 0xe0a0, 0x000},
3471 	{d68000_asr_ea       , 0xffc0, 0xe0c0, 0x3f8},
3472 	{d68000_asl_s_8      , 0xf1f8, 0xe100, 0x000},
3473 	{d68000_asl_s_16     , 0xf1f8, 0xe140, 0x000},
3474 	{d68000_asl_s_32     , 0xf1f8, 0xe180, 0x000},
3475 	{d68000_asl_r_8      , 0xf1f8, 0xe120, 0x000},
3476 	{d68000_asl_r_16     , 0xf1f8, 0xe160, 0x000},
3477 	{d68000_asl_r_32     , 0xf1f8, 0xe1a0, 0x000},
3478 	{d68000_asl_ea       , 0xffc0, 0xe1c0, 0x3f8},
3479 	{d68000_bcc_8        , 0xf000, 0x6000, 0x000},
3480 	{d68000_bcc_16       , 0xf0ff, 0x6000, 0x000},
3481 	{d68020_bcc_32       , 0xf0ff, 0x60ff, 0x000},
3482 	{d68000_bchg_r       , 0xf1c0, 0x0140, 0xbf8},
3483 	{d68000_bchg_s       , 0xffc0, 0x0840, 0xbf8, 0xff00, 0x0000},
3484 	{d68000_bclr_r       , 0xf1c0, 0x0180, 0xbf8},
3485 	{d68000_bclr_s       , 0xffc0, 0x0880, 0xbf8, 0xff00, 0x0000},
3486 	{d68020_bfchg        , 0xffc0, 0xeac0, 0xa78, 0xf000, 0x0000},
3487 	{d68020_bfclr        , 0xffc0, 0xecc0, 0xa78, 0xf000, 0x0000},
3488 	{d68020_bfexts       , 0xffc0, 0xebc0, 0xa7b, 0x8000, 0x0000},
3489 	{d68020_bfextu       , 0xffc0, 0xe9c0, 0xa7b, 0x8000, 0x0000},
3490 	{d68020_bfffo        , 0xffc0, 0xedc0, 0xa7b, 0x8000, 0x0000},
3491 	{d68020_bfins        , 0xffc0, 0xefc0, 0xa78, 0x8000, 0x0000},
3492 	{d68020_bfset        , 0xffc0, 0xeec0, 0xa78, 0xf000, 0x0000},
3493 	{d68020_bftst        , 0xffc0, 0xe8c0, 0xa7b, 0xf000, 0x0000},
3494 	{d68010_bkpt         , 0xfff8, 0x4848, 0x000},
3495 	{d68000_bra_8        , 0xff00, 0x6000, 0x000},
3496 	{d68000_bra_16       , 0xffff, 0x6000, 0x000},
3497 	{d68020_bra_32       , 0xffff, 0x60ff, 0x000},
3498 	{d68000_bset_r       , 0xf1c0, 0x01c0, 0xbf8},
3499 	{d68000_bset_s       , 0xffc0, 0x08c0, 0xbf8, 0xfe00, 0x0000 },
3500 	{d68000_bsr_8        , 0xff00, 0x6100, 0x000},
3501 	{d68000_bsr_16       , 0xffff, 0x6100, 0x000},
3502 	{d68020_bsr_32       , 0xffff, 0x61ff, 0x000},
3503 	{d68000_btst_r       , 0xf1c0, 0x0100, 0xbff},
3504 	{d68000_btst_s       , 0xffc0, 0x0800, 0xbfb, 0xff00, 0x0000},
3505 	{d68020_callm        , 0xffc0, 0x06c0, 0x27b, 0xff00, 0x0000},
3506 	{d68020_cas_8        , 0xffc0, 0x0ac0, 0x3f8, 0xfe38, 0x0000},
3507 	{d68020_cas_16       , 0xffc0, 0x0cc0, 0x3f8, 0xfe38, 0x0000},
3508 	{d68020_cas_32       , 0xffc0, 0x0ec0, 0x3f8, 0xfe38, 0x0000},
3509 	{d68020_cas2_16      , 0xffff, 0x0cfc, 0x000, 0x0e38, 0x0000/*, 0x0e38, 0x0000 */},
3510 	{d68020_cas2_32      , 0xffff, 0x0efc, 0x000, 0x0e38, 0x0000/*, 0x0e38, 0x0000 */},
3511 	{d68000_chk_16       , 0xf1c0, 0x4180, 0xbff},
3512 	{d68020_chk_32       , 0xf1c0, 0x4100, 0xbff},
3513 	{d68020_chk2_cmp2_8  , 0xffc0, 0x00c0, 0x27b, 0x07ff, 0x0000},
3514 	{d68020_chk2_cmp2_16 , 0xffc0, 0x02c0, 0x27b, 0x07ff, 0x0000},
3515 	{d68020_chk2_cmp2_32 , 0xffc0, 0x04c0, 0x27b, 0x07ff, 0x0000},
3516 	{d68040_cinv         , 0xff20, 0xf400, 0x000},
3517 	{d68000_clr_8        , 0xffc0, 0x4200, 0xbf8},
3518 	{d68000_clr_16       , 0xffc0, 0x4240, 0xbf8},
3519 	{d68000_clr_32       , 0xffc0, 0x4280, 0xbf8},
3520 	{d68000_cmp_8        , 0xf1c0, 0xb000, 0xbff},
3521 	{d68000_cmp_16       , 0xf1c0, 0xb040, 0xfff},
3522 	{d68000_cmp_32       , 0xf1c0, 0xb080, 0xfff},
3523 	{d68000_cmpa_16      , 0xf1c0, 0xb0c0, 0xfff},
3524 	{d68000_cmpa_32      , 0xf1c0, 0xb1c0, 0xfff},
3525 	{d68000_cmpi_8       , 0xffc0, 0x0c00, 0xbf8},
3526 	{d68020_cmpi_pcdi_8  , 0xffff, 0x0c3a, 0x000},
3527 	{d68020_cmpi_pcix_8  , 0xffff, 0x0c3b, 0x000},
3528 	{d68000_cmpi_16      , 0xffc0, 0x0c40, 0xbf8},
3529 	{d68020_cmpi_pcdi_16 , 0xffff, 0x0c7a, 0x000},
3530 	{d68020_cmpi_pcix_16 , 0xffff, 0x0c7b, 0x000},
3531 	{d68000_cmpi_32      , 0xffc0, 0x0c80, 0xbf8},
3532 	{d68020_cmpi_pcdi_32 , 0xffff, 0x0cba, 0x000},
3533 	{d68020_cmpi_pcix_32 , 0xffff, 0x0cbb, 0x000},
3534 	{d68000_cmpm_8       , 0xf1f8, 0xb108, 0x000},
3535 	{d68000_cmpm_16      , 0xf1f8, 0xb148, 0x000},
3536 	{d68000_cmpm_32      , 0xf1f8, 0xb188, 0x000},
3537 	{d68020_cpbcc_16     , 0xf1c0, 0xf080, 0x000},
3538 	{d68020_cpbcc_32     , 0xf1c0, 0xf0c0, 0x000},
3539 	{d68020_cpdbcc       , 0xf1f8, 0xf048, 0x000},
3540 	{d68020_cpgen        , 0xf1c0, 0xf000, 0x000},
3541 	{d68020_cprestore    , 0xf1c0, 0xf140, 0x37f},
3542 	{d68020_cpsave       , 0xf1c0, 0xf100, 0x2f8},
3543 	{d68020_cpscc        , 0xf1c0, 0xf040, 0xbf8},
3544 	{d68020_cptrapcc_0   , 0xf1ff, 0xf07c, 0x000},
3545 	{d68020_cptrapcc_16  , 0xf1ff, 0xf07a, 0x000},
3546 	{d68020_cptrapcc_32  , 0xf1ff, 0xf07b, 0x000},
3547 	{d68040_cpush        , 0xff20, 0xf420, 0x000},
3548 	{d68000_dbcc         , 0xf0f8, 0x50c8, 0x000},
3549 	{d68000_dbra         , 0xfff8, 0x51c8, 0x000},
3550 	{d68000_divs         , 0xf1c0, 0x81c0, 0xbff},
3551 	{d68000_divu         , 0xf1c0, 0x80c0, 0xbff},
3552 	{d68020_divl         , 0xff80, 0x4c00, 0xbff, 0x83f8, 0x0000},
3553 	{d68000_eor_8        , 0xf1c0, 0xb100, 0xbf8},
3554 	{d68000_eor_16       , 0xf1c0, 0xb140, 0xbf8},
3555 	{d68000_eor_32       , 0xf1c0, 0xb180, 0xbf8},
3556 	{d68000_eori_to_ccr  , 0xffff, 0x0a3c, 0x000, 0xff00, 0x0000},
3557 	{d68000_eori_to_sr   , 0xffff, 0x0a7c, 0x000},
3558 	{d68000_eori_8       , 0xffc0, 0x0a00, 0xbf8},
3559 	{d68000_eori_16      , 0xffc0, 0x0a40, 0xbf8},
3560 	{d68000_eori_32      , 0xffc0, 0x0a80, 0xbf8},
3561 	{d68000_exg_dd       , 0xf1f8, 0xc140, 0x000},
3562 	{d68000_exg_aa       , 0xf1f8, 0xc148, 0x000},
3563 	{d68000_exg_da       , 0xf1f8, 0xc188, 0x000},
3564 	{d68020_extb_32      , 0xfff8, 0x49c0, 0x000},
3565 	{d68000_ext_16       , 0xfff8, 0x4880, 0x000},
3566 	{d68000_ext_32       , 0xfff8, 0x48c0, 0x000},
3567 	{d68000_illegal      , 0xffff, 0x4afc, 0x000},
3568 	{d68000_jmp          , 0xffc0, 0x4ec0, 0x27b},
3569 	{d68000_jsr          , 0xffc0, 0x4e80, 0x27b},
3570 	{d68000_lea          , 0xf1c0, 0x41c0, 0x27b},
3571 	{d68000_link_16      , 0xfff8, 0x4e50, 0x000},
3572 	{d68020_link_32      , 0xfff8, 0x4808, 0x000},
3573 	{d68000_lsr_s_8      , 0xf1f8, 0xe008, 0x000},
3574 	{d68000_lsr_s_16     , 0xf1f8, 0xe048, 0x000},
3575 	{d68000_lsr_s_32     , 0xf1f8, 0xe088, 0x000},
3576 	{d68000_lsr_r_8      , 0xf1f8, 0xe028, 0x000},
3577 	{d68000_lsr_r_16     , 0xf1f8, 0xe068, 0x000},
3578 	{d68000_lsr_r_32     , 0xf1f8, 0xe0a8, 0x000},
3579 	{d68000_lsr_ea       , 0xffc0, 0xe2c0, 0x3f8},
3580 	{d68000_lsl_s_8      , 0xf1f8, 0xe108, 0x000},
3581 	{d68000_lsl_s_16     , 0xf1f8, 0xe148, 0x000},
3582 	{d68000_lsl_s_32     , 0xf1f8, 0xe188, 0x000},
3583 	{d68000_lsl_r_8      , 0xf1f8, 0xe128, 0x000},
3584 	{d68000_lsl_r_16     , 0xf1f8, 0xe168, 0x000},
3585 	{d68000_lsl_r_32     , 0xf1f8, 0xe1a8, 0x000},
3586 	{d68000_lsl_ea       , 0xffc0, 0xe3c0, 0x3f8},
3587 	{d68000_move_8       , 0xf000, 0x1000, 0xbff},
3588 	{d68000_move_16      , 0xf000, 0x3000, 0xfff},
3589 	{d68000_move_32      , 0xf000, 0x2000, 0xfff},
3590 	{d68000_movea_16     , 0xf1c0, 0x3040, 0xfff},
3591 	{d68000_movea_32     , 0xf1c0, 0x2040, 0xfff},
3592 	{d68000_move_to_ccr  , 0xffc0, 0x44c0, 0xbff},
3593 	{d68010_move_fr_ccr  , 0xffc0, 0x42c0, 0xbf8},
3594 	{d68000_move_to_sr   , 0xffc0, 0x46c0, 0xbff},
3595 	{d68000_move_fr_sr   , 0xffc0, 0x40c0, 0xbf8},
3596 	{d68000_move_to_usp  , 0xfff8, 0x4e60, 0x000},
3597 	{d68000_move_fr_usp  , 0xfff8, 0x4e68, 0x000},
3598 	{d68010_movec        , 0xfffe, 0x4e7a, 0x000},
3599 	{d68000_movem_pd_16  , 0xfff8, 0x48a0, 0x000},
3600 	{d68000_movem_pd_32  , 0xfff8, 0x48e0, 0x000},
3601 	{d68000_movem_re_16  , 0xffc0, 0x4880, 0x2f8},
3602 	{d68000_movem_re_32  , 0xffc0, 0x48c0, 0x2f8},
3603 	{d68000_movem_er_16  , 0xffc0, 0x4c80, 0x37b},
3604 	{d68000_movem_er_32  , 0xffc0, 0x4cc0, 0x37b},
3605 	{d68000_movep_er_16  , 0xf1f8, 0x0108, 0x000},
3606 	{d68000_movep_er_32  , 0xf1f8, 0x0148, 0x000},
3607 	{d68000_movep_re_16  , 0xf1f8, 0x0188, 0x000},
3608 	{d68000_movep_re_32  , 0xf1f8, 0x01c8, 0x000},
3609 	{d68010_moves_8      , 0xffc0, 0x0e00, 0x3f8, 0x07ff, 0x0000},
3610 	{d68010_moves_16     , 0xffc0, 0x0e40, 0x3f8, 0x07ff, 0x0000},
3611 	{d68010_moves_32     , 0xffc0, 0x0e80, 0x3f8, 0x07ff, 0x0000},
3612 	{d68000_moveq        , 0xf100, 0x7000, 0x000},
3613 	{d68040_move16_pi_pi , 0xfff8, 0xf620, 0x000, 0x8fff, 0x8000},
3614 	{d68040_move16_pi_al , 0xfff8, 0xf600, 0x000},
3615 	{d68040_move16_al_pi , 0xfff8, 0xf608, 0x000},
3616 	{d68040_move16_ai_al , 0xfff8, 0xf610, 0x000},
3617 	{d68040_move16_al_ai , 0xfff8, 0xf618, 0x000},
3618 	{d68000_muls         , 0xf1c0, 0xc1c0, 0xbff},
3619 	{d68000_mulu         , 0xf1c0, 0xc0c0, 0xbff},
3620 	{d68020_mull         , 0xffc0, 0x4c00, 0xbff, 0x83f8, 0x0000},
3621 	{d68000_nbcd         , 0xffc0, 0x4800, 0xbf8},
3622 	{d68000_neg_8        , 0xffc0, 0x4400, 0xbf8},
3623 	{d68000_neg_16       , 0xffc0, 0x4440, 0xbf8},
3624 	{d68000_neg_32       , 0xffc0, 0x4480, 0xbf8},
3625 	{d68000_negx_8       , 0xffc0, 0x4000, 0xbf8},
3626 	{d68000_negx_16      , 0xffc0, 0x4040, 0xbf8},
3627 	{d68000_negx_32      , 0xffc0, 0x4080, 0xbf8},
3628 	{d68000_nop          , 0xffff, 0x4e71, 0x000},
3629 	{d68000_not_8        , 0xffc0, 0x4600, 0xbf8},
3630 	{d68000_not_16       , 0xffc0, 0x4640, 0xbf8},
3631 	{d68000_not_32       , 0xffc0, 0x4680, 0xbf8},
3632 	{d68000_or_er_8      , 0xf1c0, 0x8000, 0xbff},
3633 	{d68000_or_er_16     , 0xf1c0, 0x8040, 0xbff},
3634 	{d68000_or_er_32     , 0xf1c0, 0x8080, 0xbff},
3635 	{d68000_or_re_8      , 0xf1c0, 0x8100, 0x3f8},
3636 	{d68000_or_re_16     , 0xf1c0, 0x8140, 0x3f8},
3637 	{d68000_or_re_32     , 0xf1c0, 0x8180, 0x3f8},
3638 	{d68000_ori_to_ccr   , 0xffff, 0x003c, 0x000, 0xff00, 0x0000},
3639 	{d68000_ori_to_sr    , 0xffff, 0x007c, 0x000},
3640 	{d68000_ori_8        , 0xffc0, 0x0000, 0xbf8},
3641 	{d68000_ori_16       , 0xffc0, 0x0040, 0xbf8},
3642 	{d68000_ori_32       , 0xffc0, 0x0080, 0xbf8},
3643 	{d68020_pack_rr      , 0xf1f8, 0x8140, 0x000},
3644 	{d68020_pack_mm      , 0xf1f8, 0x8148, 0x000},
3645 	{d68000_pea          , 0xffc0, 0x4840, 0x27b},
3646 	{d68000_reset        , 0xffff, 0x4e70, 0x000},
3647 	{d68000_ror_s_8      , 0xf1f8, 0xe018, 0x000},
3648 	{d68000_ror_s_16     , 0xf1f8, 0xe058, 0x000},
3649 	{d68000_ror_s_32     , 0xf1f8, 0xe098, 0x000},
3650 	{d68000_ror_r_8      , 0xf1f8, 0xe038, 0x000},
3651 	{d68000_ror_r_16     , 0xf1f8, 0xe078, 0x000},
3652 	{d68000_ror_r_32     , 0xf1f8, 0xe0b8, 0x000},
3653 	{d68000_ror_ea       , 0xffc0, 0xe6c0, 0x3f8},
3654 	{d68000_rol_s_8      , 0xf1f8, 0xe118, 0x000},
3655 	{d68000_rol_s_16     , 0xf1f8, 0xe158, 0x000},
3656 	{d68000_rol_s_32     , 0xf1f8, 0xe198, 0x000},
3657 	{d68000_rol_r_8      , 0xf1f8, 0xe138, 0x000},
3658 	{d68000_rol_r_16     , 0xf1f8, 0xe178, 0x000},
3659 	{d68000_rol_r_32     , 0xf1f8, 0xe1b8, 0x000},
3660 	{d68000_rol_ea       , 0xffc0, 0xe7c0, 0x3f8},
3661 	{d68000_roxr_s_8     , 0xf1f8, 0xe010, 0x000},
3662 	{d68000_roxr_s_16    , 0xf1f8, 0xe050, 0x000},
3663 	{d68000_roxr_s_32    , 0xf1f8, 0xe090, 0x000},
3664 	{d68000_roxr_r_8     , 0xf1f8, 0xe030, 0x000},
3665 	{d68000_roxr_r_16    , 0xf1f8, 0xe070, 0x000},
3666 	{d68000_roxr_r_32    , 0xf1f8, 0xe0b0, 0x000},
3667 	{d68000_roxr_ea      , 0xffc0, 0xe4c0, 0x3f8},
3668 	{d68000_roxl_s_8     , 0xf1f8, 0xe110, 0x000},
3669 	{d68000_roxl_s_16    , 0xf1f8, 0xe150, 0x000},
3670 	{d68000_roxl_s_32    , 0xf1f8, 0xe190, 0x000},
3671 	{d68000_roxl_r_8     , 0xf1f8, 0xe130, 0x000},
3672 	{d68000_roxl_r_16    , 0xf1f8, 0xe170, 0x000},
3673 	{d68000_roxl_r_32    , 0xf1f8, 0xe1b0, 0x000},
3674 	{d68000_roxl_ea      , 0xffc0, 0xe5c0, 0x3f8},
3675 	{d68010_rtd          , 0xffff, 0x4e74, 0x000},
3676 	{d68000_rte          , 0xffff, 0x4e73, 0x000},
3677 	{d68020_rtm          , 0xfff0, 0x06c0, 0x000},
3678 	{d68000_rtr          , 0xffff, 0x4e77, 0x000},
3679 	{d68000_rts          , 0xffff, 0x4e75, 0x000},
3680 	{d68000_sbcd_rr      , 0xf1f8, 0x8100, 0x000},
3681 	{d68000_sbcd_mm      , 0xf1f8, 0x8108, 0x000},
3682 	{d68000_scc          , 0xf0c0, 0x50c0, 0xbf8},
3683 	{d68000_stop         , 0xffff, 0x4e72, 0x000},
3684 	{d68000_sub_er_8     , 0xf1c0, 0x9000, 0xbff},
3685 	{d68000_sub_er_16    , 0xf1c0, 0x9040, 0xfff},
3686 	{d68000_sub_er_32    , 0xf1c0, 0x9080, 0xfff},
3687 	{d68000_sub_re_8     , 0xf1c0, 0x9100, 0x3f8},
3688 	{d68000_sub_re_16    , 0xf1c0, 0x9140, 0x3f8},
3689 	{d68000_sub_re_32    , 0xf1c0, 0x9180, 0x3f8},
3690 	{d68000_suba_16      , 0xf1c0, 0x90c0, 0xfff},
3691 	{d68000_suba_32      , 0xf1c0, 0x91c0, 0xfff},
3692 	{d68000_subi_8       , 0xffc0, 0x0400, 0xbf8},
3693 	{d68000_subi_16      , 0xffc0, 0x0440, 0xbf8},
3694 	{d68000_subi_32      , 0xffc0, 0x0480, 0xbf8},
3695 	{d68000_subq_8       , 0xf1c0, 0x5100, 0xbf8},
3696 	{d68000_subq_16      , 0xf1c0, 0x5140, 0xff8},
3697 	{d68000_subq_32      , 0xf1c0, 0x5180, 0xff8},
3698 	{d68000_subx_rr_8    , 0xf1f8, 0x9100, 0x000},
3699 	{d68000_subx_rr_16   , 0xf1f8, 0x9140, 0x000},
3700 	{d68000_subx_rr_32   , 0xf1f8, 0x9180, 0x000},
3701 	{d68000_subx_mm_8    , 0xf1f8, 0x9108, 0x000},
3702 	{d68000_subx_mm_16   , 0xf1f8, 0x9148, 0x000},
3703 	{d68000_subx_mm_32   , 0xf1f8, 0x9188, 0x000},
3704 	{d68000_swap         , 0xfff8, 0x4840, 0x000},
3705 	{d68000_tas          , 0xffc0, 0x4ac0, 0xbf8},
3706 	{d68000_trap         , 0xfff0, 0x4e40, 0x000},
3707 	{d68020_trapcc_0     , 0xf0ff, 0x50fc, 0x000},
3708 	{d68020_trapcc_16    , 0xf0ff, 0x50fa, 0x000},
3709 	{d68020_trapcc_32    , 0xf0ff, 0x50fb, 0x000},
3710 	{d68000_trapv        , 0xffff, 0x4e76, 0x000},
3711 	{d68000_tst_8        , 0xffc0, 0x4a00, 0xbf8},
3712 	{d68020_tst_pcdi_8   , 0xffff, 0x4a3a, 0x000},
3713 	{d68020_tst_pcix_8   , 0xffff, 0x4a3b, 0x000},
3714 	{d68020_tst_i_8      , 0xffff, 0x4a3c, 0x000},
3715 	{d68000_tst_16       , 0xffc0, 0x4a40, 0xbf8},
3716 	{d68020_tst_a_16     , 0xfff8, 0x4a48, 0x000},
3717 	{d68020_tst_pcdi_16  , 0xffff, 0x4a7a, 0x000},
3718 	{d68020_tst_pcix_16  , 0xffff, 0x4a7b, 0x000},
3719 	{d68020_tst_i_16     , 0xffff, 0x4a7c, 0x000},
3720 	{d68000_tst_32       , 0xffc0, 0x4a80, 0xbf8},
3721 	{d68020_tst_a_32     , 0xfff8, 0x4a88, 0x000},
3722 	{d68020_tst_pcdi_32  , 0xffff, 0x4aba, 0x000},
3723 	{d68020_tst_pcix_32  , 0xffff, 0x4abb, 0x000},
3724 	{d68020_tst_i_32     , 0xffff, 0x4abc, 0x000},
3725 	{d68000_unlk         , 0xfff8, 0x4e58, 0x000},
3726 	{d68020_unpk_rr      , 0xf1f8, 0x8180, 0x000},
3727 	{d68020_unpk_mm      , 0xf1f8, 0x8188, 0x000},
3728 	{0, 0, 0, 0}
3729 };
3730 
3731 /* Check if opcode is using a valid ea mode */
valid_ea(uint opcode,uint mask)3732 static int valid_ea(uint opcode, uint mask)
3733 {
3734 	if (mask == 0)
3735 		return 1;
3736 
3737 	switch(opcode & 0x3f) {
3738 		case 0x00: case 0x01: case 0x02: case 0x03:
3739 		case 0x04: case 0x05: case 0x06: case 0x07:
3740 			return (mask & 0x800) != 0;
3741 		case 0x08: case 0x09: case 0x0a: case 0x0b:
3742 		case 0x0c: case 0x0d: case 0x0e: case 0x0f:
3743 			return (mask & 0x400) != 0;
3744 		case 0x10: case 0x11: case 0x12: case 0x13:
3745 		case 0x14: case 0x15: case 0x16: case 0x17:
3746 			return (mask & 0x200) != 0;
3747 		case 0x18: case 0x19: case 0x1a: case 0x1b:
3748 		case 0x1c: case 0x1d: case 0x1e: case 0x1f:
3749 			return (mask & 0x100) != 0;
3750 		case 0x20: case 0x21: case 0x22: case 0x23:
3751 		case 0x24: case 0x25: case 0x26: case 0x27:
3752 			return (mask & 0x080) != 0;
3753 		case 0x28: case 0x29: case 0x2a: case 0x2b:
3754 		case 0x2c: case 0x2d: case 0x2e: case 0x2f:
3755 			return (mask & 0x040) != 0;
3756 		case 0x30: case 0x31: case 0x32: case 0x33:
3757 		case 0x34: case 0x35: case 0x36: case 0x37:
3758 			return (mask & 0x020) != 0;
3759 		case 0x38:
3760 			return (mask & 0x010) != 0;
3761 		case 0x39:
3762 			return (mask & 0x008) != 0;
3763 		case 0x3a:
3764 			return (mask & 0x002) != 0;
3765 		case 0x3b:
3766 			return (mask & 0x001) != 0;
3767 		case 0x3c:
3768 			return (mask & 0x004) != 0;
3769 	}
3770 	return 0;
3771 
3772 }
3773 
3774 /* Used by qsort */
compare_nof_true_bits(const void * aptr,const void * bptr)3775 static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr)
3776 {
3777 	uint a = ((const opcode_struct*)aptr)->mask;
3778 	uint b = ((const opcode_struct*)bptr)->mask;
3779 
3780 	a = ((a & 0xAAAA) >> 1) + (a & 0x5555);
3781 	a = ((a & 0xCCCC) >> 2) + (a & 0x3333);
3782 	a = ((a & 0xF0F0) >> 4) + (a & 0x0F0F);
3783 	a = ((a & 0xFF00) >> 8) + (a & 0x00FF);
3784 
3785 	b = ((b & 0xAAAA) >> 1) + (b & 0x5555);
3786 	b = ((b & 0xCCCC) >> 2) + (b & 0x3333);
3787 	b = ((b & 0xF0F0) >> 4) + (b & 0x0F0F);
3788 	b = ((b & 0xFF00) >> 8) + (b & 0x00FF);
3789 
3790 	return b - a; /* reversed to get greatest to least sorting */
3791 }
3792 
3793 /* build the opcode handler jump table */
build_opcode_table(void)3794 static void build_opcode_table(void)
3795 {
3796 	uint i;
3797 	uint opcode;
3798 	opcode_struct* ostruct;
3799 	uint opcode_info_length = 0;
3800 
3801 	/* Already initialized ? */
3802 	if (g_instruction_table[0].instruction != NULL) {
3803 		return;
3804 	}
3805 
3806 	for(ostruct = g_opcode_info;ostruct->opcode_handler != 0;ostruct++)
3807 		opcode_info_length++;
3808 
3809 	qsort((void *)g_opcode_info, opcode_info_length, sizeof(g_opcode_info[0]), compare_nof_true_bits);
3810 
3811 	for(i=0;i<0x10000;i++) {
3812 		g_instruction_table[i].instruction = d68000_invalid; /* default to invalid, undecoded opcode */
3813 		opcode = i;
3814 		/* search through opcode info for a match */
3815 		for(ostruct = g_opcode_info;ostruct->opcode_handler != 0;ostruct++) {
3816 			/* match opcode mask and allowed ea modes */
3817 			if ((opcode & ostruct->mask) == ostruct->match) {
3818 				/* Handle destination ea for move instructions */
3819 				if ((ostruct->opcode_handler == d68000_move_8 ||
3820 							ostruct->opcode_handler == d68000_move_16 ||
3821 							ostruct->opcode_handler == d68000_move_32) &&
3822 						!valid_ea(((opcode>>9)&7) | ((opcode>>3)&0x38), 0xbf8))
3823 					continue;
3824 				if (valid_ea(opcode, ostruct->ea_mask)) {
3825 					g_instruction_table[i].instruction = ostruct->opcode_handler;
3826 					g_instruction_table[i].word2_mask = ostruct->mask2;
3827 					g_instruction_table[i].word2_match = ostruct->match2;
3828 					break;
3829 				}
3830 			}
3831 		}
3832 	}
3833 }
3834 
instruction_is_valid(m68k_info * info,const unsigned int word_check)3835 static int instruction_is_valid(m68k_info *info, const unsigned int word_check)
3836 {
3837 	const unsigned int instruction = info->ir;
3838 	instruction_struct *i = &g_instruction_table[instruction];
3839 
3840 	if ( (i->word2_mask && ((word_check & i->word2_mask) != i->word2_match)) ||
3841 		(i->instruction == d68000_invalid) ) {
3842 		d68000_invalid(info);
3843 		return 0;
3844 	}
3845 
3846 	return 1;
3847 }
3848 
exists_reg_list(uint16_t * regs,uint8_t count,m68k_reg reg)3849 static int exists_reg_list(uint16_t *regs, uint8_t count, m68k_reg reg)
3850 {
3851 	uint8_t i;
3852 
3853 	for (i = 0; i < count; ++i) {
3854 		if (regs[i] == (uint16_t)reg)
3855 			return 1;
3856 	}
3857 
3858 	return 0;
3859 }
3860 
add_reg_to_rw_list(m68k_info * info,m68k_reg reg,int write)3861 static void add_reg_to_rw_list(m68k_info *info, m68k_reg reg, int write)
3862 {
3863 	if (reg == M68K_REG_INVALID)
3864 		return;
3865 
3866 	if (write)
3867 	{
3868 		if (exists_reg_list(info->regs_write, info->regs_write_count, reg))
3869 			return;
3870 
3871 		info->regs_write[info->regs_write_count] = (uint16_t)reg;
3872 		info->regs_write_count++;
3873 	}
3874 	else
3875 	{
3876 		if (exists_reg_list(info->regs_read, info->regs_read_count, reg))
3877 			return;
3878 
3879 		info->regs_read[info->regs_read_count] = (uint16_t)reg;
3880 		info->regs_read_count++;
3881 	}
3882 }
3883 
update_am_reg_list(m68k_info * info,cs_m68k_op * op,int write)3884 static void update_am_reg_list(m68k_info *info, cs_m68k_op *op, int write)
3885 {
3886 	switch (op->address_mode) {
3887 		case M68K_AM_REG_DIRECT_ADDR:
3888 		case M68K_AM_REG_DIRECT_DATA:
3889 			add_reg_to_rw_list(info, op->reg, write);
3890 			break;
3891 
3892 		case M68K_AM_REGI_ADDR_POST_INC:
3893 		case M68K_AM_REGI_ADDR_PRE_DEC:
3894 			add_reg_to_rw_list(info, op->reg, 1);
3895 			break;
3896 
3897 		case M68K_AM_REGI_ADDR:
3898 		case M68K_AM_REGI_ADDR_DISP:
3899 			add_reg_to_rw_list(info, op->reg, 0);
3900 			break;
3901 
3902 		case M68K_AM_AREGI_INDEX_8_BIT_DISP:
3903 		case M68K_AM_AREGI_INDEX_BASE_DISP:
3904 		case M68K_AM_MEMI_POST_INDEX:
3905 		case M68K_AM_MEMI_PRE_INDEX:
3906 		case M68K_AM_PCI_INDEX_8_BIT_DISP:
3907 		case M68K_AM_PCI_INDEX_BASE_DISP:
3908 		case M68K_AM_PC_MEMI_PRE_INDEX:
3909 		case M68K_AM_PC_MEMI_POST_INDEX:
3910 			add_reg_to_rw_list(info, op->mem.index_reg, 0);
3911 			add_reg_to_rw_list(info, op->mem.base_reg, 0);
3912 			break;
3913 
3914 		// no register(s) in the other addressing modes
3915 		default:
3916 			break;
3917 	}
3918 }
3919 
update_bits_range(m68k_info * info,m68k_reg reg_start,uint8_t bits,int write)3920 static void update_bits_range(m68k_info *info, m68k_reg reg_start, uint8_t bits, int write)
3921 {
3922 	int i;
3923 
3924 	for (i = 0; i < 8; ++i) {
3925 		if (bits & (1 << i)) {
3926 			add_reg_to_rw_list(info, reg_start + i, write);
3927 		}
3928 	}
3929 }
3930 
update_reg_list_regbits(m68k_info * info,cs_m68k_op * op,int write)3931 static void update_reg_list_regbits(m68k_info *info, cs_m68k_op *op, int write)
3932 {
3933 	uint32_t bits = op->register_bits;
3934 	update_bits_range(info, M68K_REG_D0, bits & 0xff, write);
3935 	update_bits_range(info, M68K_REG_A0, (bits >> 8) & 0xff, write);
3936 	update_bits_range(info, M68K_REG_FP0, (bits >> 16) & 0xff, write);
3937 }
3938 
update_op_reg_list(m68k_info * info,cs_m68k_op * op,int write)3939 static void update_op_reg_list(m68k_info *info, cs_m68k_op *op, int write)
3940 {
3941 	switch ((int)op->type) {
3942 		case M68K_OP_REG:
3943 			add_reg_to_rw_list(info, op->reg, write);
3944 			break;
3945 
3946 		case M68K_OP_MEM:
3947 			update_am_reg_list(info, op, write);
3948 			break;
3949 
3950 		case M68K_OP_REG_BITS:
3951 			update_reg_list_regbits(info, op, write);
3952 			break;
3953 
3954 		case M68K_OP_REG_PAIR:
3955 			add_reg_to_rw_list(info, M68K_REG_D0 + op->reg_pair.reg_0, write);
3956 			add_reg_to_rw_list(info, M68K_REG_D0 + op->reg_pair.reg_1, write);
3957 			break;
3958 	}
3959 }
3960 
build_regs_read_write_counts(m68k_info * info)3961 static void build_regs_read_write_counts(m68k_info *info)
3962 {
3963 	int i;
3964 
3965 	if (!info->extension.op_count)
3966 		return;
3967 
3968 	if (info->extension.op_count == 1) {
3969 		update_op_reg_list(info, &info->extension.operands[0], 1);
3970 	} else {
3971 		// first operand is always read
3972 		update_op_reg_list(info, &info->extension.operands[0], 0);
3973 
3974 		// remaning write
3975 		for (i = 1; i < info->extension.op_count; ++i)
3976 			update_op_reg_list(info, &info->extension.operands[i], 1);
3977 	}
3978 }
3979 
m68k_setup_internals(m68k_info * info,MCInst * inst,unsigned int pc,unsigned int cpu_type)3980 static void m68k_setup_internals(m68k_info* info, MCInst* inst, unsigned int pc, unsigned int cpu_type)
3981 {
3982 	info->inst = inst;
3983 	info->pc = pc;
3984 	info->ir = 0;
3985 	info->type = cpu_type;
3986 	info->address_mask = 0xffffffff;
3987 
3988 	switch(info->type) {
3989 		case M68K_CPU_TYPE_68000:
3990 			info->type = TYPE_68000;
3991 			info->address_mask = 0x00ffffff;
3992 			break;
3993 		case M68K_CPU_TYPE_68010:
3994 			info->type = TYPE_68010;
3995 			info->address_mask = 0x00ffffff;
3996 			break;
3997 		case M68K_CPU_TYPE_68EC020:
3998 			info->type = TYPE_68020;
3999 			info->address_mask = 0x00ffffff;
4000 			break;
4001 		case M68K_CPU_TYPE_68020:
4002 			info->type = TYPE_68020;
4003 			info->address_mask = 0xffffffff;
4004 			break;
4005 		case M68K_CPU_TYPE_68030:
4006 			info->type = TYPE_68030;
4007 			info->address_mask = 0xffffffff;
4008 			break;
4009 		case M68K_CPU_TYPE_68040:
4010 			info->type = TYPE_68040;
4011 			info->address_mask = 0xffffffff;
4012 			break;
4013 		default:
4014 			info->address_mask = 0;
4015 			return;
4016 	}
4017 }
4018 
4019 /* ======================================================================== */
4020 /* ================================= API ================================== */
4021 /* ======================================================================== */
4022 
4023 /* Disasemble one instruction at pc and store in str_buff */
m68k_disassemble(m68k_info * info,uint64_t pc)4024 static unsigned int m68k_disassemble(m68k_info *info, uint64_t pc)
4025 {
4026 	MCInst *inst = info->inst;
4027 	cs_m68k* ext = &info->extension;
4028 	int i;
4029 	unsigned int size;
4030 
4031 	inst->Opcode = M68K_INS_INVALID;
4032 
4033 	build_opcode_table();
4034 
4035 	memset(ext, 0, sizeof(cs_m68k));
4036 	ext->op_size.type = M68K_SIZE_TYPE_CPU;
4037 
4038 	for (i = 0; i < M68K_OPERAND_COUNT; ++i)
4039 		ext->operands[i].type = M68K_OP_REG;
4040 
4041 	info->ir = peek_imm_16(info);
4042 	if (instruction_is_valid(info, peek_imm_32(info) & 0xffff)) {
4043 		info->ir = read_imm_16(info);
4044 		g_instruction_table[info->ir].instruction(info);
4045 	}
4046 
4047 	size = info->pc - (unsigned int)pc;
4048 	info->pc = (unsigned int)pc;
4049 
4050 	return size;
4051 }
4052 
M68K_getInstruction(csh ud,const uint8_t * code,size_t code_len,MCInst * instr,uint16_t * size,uint64_t address,void * inst_info)4053 bool M68K_getInstruction(csh ud, const uint8_t* code, size_t code_len, MCInst* instr, uint16_t* size, uint64_t address, void* inst_info)
4054 {
4055 #ifdef M68K_DEBUG
4056 	SStream ss;
4057 #endif
4058 	int s;
4059 	int cpu_type = M68K_CPU_TYPE_68000;
4060 	cs_struct* handle = instr->csh;
4061 	m68k_info *info = (m68k_info*)handle->printer_info;
4062 
4063 	// code len has to be at least 2 bytes to be valid m68k
4064 
4065 	if (code_len < 2) {
4066 		*size = 0;
4067 		return false;
4068 	}
4069 
4070 	if (instr->flat_insn->detail) {
4071 		memset(instr->flat_insn->detail, 0, offsetof(cs_detail, m68k)+sizeof(cs_m68k));
4072 	}
4073 
4074 	info->groups_count = 0;
4075 	info->regs_read_count = 0;
4076 	info->regs_write_count = 0;
4077 	info->code = code;
4078 	info->code_len = code_len;
4079 	info->baseAddress = address;
4080 
4081 	if (handle->mode & CS_MODE_M68K_010)
4082 		cpu_type = M68K_CPU_TYPE_68010;
4083 	if (handle->mode & CS_MODE_M68K_020)
4084 		cpu_type = M68K_CPU_TYPE_68020;
4085 	if (handle->mode & CS_MODE_M68K_030)
4086 		cpu_type = M68K_CPU_TYPE_68030;
4087 	if (handle->mode & CS_MODE_M68K_040)
4088 		cpu_type = M68K_CPU_TYPE_68040;
4089 	if (handle->mode & CS_MODE_M68K_060)
4090 		cpu_type = M68K_CPU_TYPE_68040;	// 060 = 040 for now
4091 
4092 	m68k_setup_internals(info, instr, (unsigned int)address, cpu_type);
4093 	s = m68k_disassemble(info, address);
4094 
4095 	if (s == 0) {
4096 		*size = 2;
4097 		return false;
4098 	}
4099 
4100 	build_regs_read_write_counts(info);
4101 
4102 #ifdef M68K_DEBUG
4103 	SStream_Init(&ss);
4104 	M68K_printInst(instr, &ss, info);
4105 #endif
4106 
4107 	// Make sure we always stay within range
4108 	if (s > (int)code_len)
4109 		*size = (uint16_t)code_len;
4110 	else
4111 		*size = (uint16_t)s;
4112 
4113 	return true;
4114 }
4115 
4116