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