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