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