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