blob: ba2fd3eb630ba6c4708576438205131b3a0f35d9 [file] [log] [blame]
Daniel Collin2ee675c2015-08-03 18:45:08 +02001/* ======================================================================== */
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
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +080030/* The code bellow is based on MUSASHI but has been heavily modified for capstore by
Daniel Collin988bb632016-04-10 10:55:21 +020031 * Daniel Collin <daniel@collin.com> 2015-2016 */
Daniel Collin2ee675c2015-08-03 18:45:08 +020032
33/* ======================================================================== */
34/* ================================ INCLUDES ============================== */
35/* ======================================================================== */
36
37#include <stdlib.h>
38#include <stdio.h>
39#include <string.h>
Daniel Colline8a4e982015-10-04 14:22:58 +020040
41#include "../../cs_priv.h"
42#include "../../utils.h"
Daniel Collin2ee675c2015-08-03 18:45:08 +020043
44#include "../../MCInst.h"
45#include "../../MCInstrDesc.h"
46#include "../../MCRegisterInfo.h"
Daniel Collinfc63aca2015-10-04 14:12:59 +020047#include "M68KInstPrinter.h"
Daniel Colline8a4e982015-10-04 14:22:58 +020048#include "M68KDisassembler.h"
Daniel Collin2ee675c2015-08-03 18:45:08 +020049
50#ifndef DECL_SPEC
51#define DECL_SPEC
52#endif
53
54/* ======================================================================== */
55/* ============================ GENERAL DEFINES =========================== */
56/* ======================================================================== */
57
58/* unsigned int and int must be at least 32 bits wide */
59#undef uint
60#define uint unsigned int
61
62/* Bit Isolation Functions */
63#define BIT_0(A) ((A) & 0x00000001)
64#define BIT_1(A) ((A) & 0x00000002)
65#define BIT_2(A) ((A) & 0x00000004)
66#define BIT_3(A) ((A) & 0x00000008)
67#define BIT_4(A) ((A) & 0x00000010)
68#define BIT_5(A) ((A) & 0x00000020)
69#define BIT_6(A) ((A) & 0x00000040)
70#define BIT_7(A) ((A) & 0x00000080)
71#define BIT_8(A) ((A) & 0x00000100)
72#define BIT_9(A) ((A) & 0x00000200)
73#define BIT_A(A) ((A) & 0x00000400)
74#define BIT_B(A) ((A) & 0x00000800)
75#define BIT_C(A) ((A) & 0x00001000)
76#define BIT_D(A) ((A) & 0x00002000)
77#define BIT_E(A) ((A) & 0x00004000)
78#define BIT_F(A) ((A) & 0x00008000)
79#define BIT_10(A) ((A) & 0x00010000)
80#define BIT_11(A) ((A) & 0x00020000)
81#define BIT_12(A) ((A) & 0x00040000)
82#define BIT_13(A) ((A) & 0x00080000)
83#define BIT_14(A) ((A) & 0x00100000)
84#define BIT_15(A) ((A) & 0x00200000)
85#define BIT_16(A) ((A) & 0x00400000)
86#define BIT_17(A) ((A) & 0x00800000)
87#define BIT_18(A) ((A) & 0x01000000)
88#define BIT_19(A) ((A) & 0x02000000)
89#define BIT_1A(A) ((A) & 0x04000000)
90#define BIT_1B(A) ((A) & 0x08000000)
91#define BIT_1C(A) ((A) & 0x10000000)
92#define BIT_1D(A) ((A) & 0x20000000)
93#define BIT_1E(A) ((A) & 0x40000000)
94#define BIT_1F(A) ((A) & 0x80000000)
95
96/* These are the CPU types understood by this disassembler */
97#define TYPE_68000 1
98#define TYPE_68010 2
99#define TYPE_68020 4
100#define TYPE_68030 8
101#define TYPE_68040 16
102
103#define M68000_ONLY TYPE_68000
104
105#define M68010_ONLY TYPE_68010
106#define M68010_LESS (TYPE_68000 | TYPE_68010)
107#define M68010_PLUS (TYPE_68010 | TYPE_68020 | TYPE_68030 | TYPE_68040)
108
109#define M68020_ONLY TYPE_68020
110#define M68020_LESS (TYPE_68010 | TYPE_68020)
111#define M68020_PLUS (TYPE_68020 | TYPE_68030 | TYPE_68040)
112
113#define M68030_ONLY TYPE_68030
114#define M68030_LESS (TYPE_68010 | TYPE_68020 | TYPE_68030)
115#define M68030_PLUS (TYPE_68030 | TYPE_68040)
116
117#define M68040_PLUS TYPE_68040
118
Daniel Collin997112d2015-10-09 08:25:10 +0200119enum {
120 M68K_CPU_TYPE_INVALID,
121 M68K_CPU_TYPE_68000,
122 M68K_CPU_TYPE_68010,
123 M68K_CPU_TYPE_68EC020,
124 M68K_CPU_TYPE_68020,
125 M68K_CPU_TYPE_68030, /* Supported by disassembler ONLY */
126 M68K_CPU_TYPE_68040 /* Supported by disassembler ONLY */
127};
Daniel Collin2ee675c2015-08-03 18:45:08 +0200128
129/* Extension word formats */
130#define EXT_8BIT_DISPLACEMENT(A) ((A)&0xff)
131#define EXT_FULL(A) BIT_8(A)
132#define EXT_EFFECTIVE_ZERO(A) (((A)&0xe4) == 0xc4 || ((A)&0xe2) == 0xc0)
133#define EXT_BASE_REGISTER_PRESENT(A) (!BIT_7(A))
134#define EXT_INDEX_REGISTER_PRESENT(A) (!BIT_6(A))
135#define EXT_INDEX_REGISTER(A) (((A)>>12)&7)
136#define EXT_INDEX_PRE_POST(A) (EXT_INDEX_PRESENT(A) && (A)&3)
137#define EXT_INDEX_PRE(A) (EXT_INDEX_PRESENT(A) && ((A)&7) < 4 && ((A)&7) != 0)
138#define EXT_INDEX_POST(A) (EXT_INDEX_PRESENT(A) && ((A)&7) > 4)
139#define EXT_INDEX_SCALE(A) (((A)>>9)&3)
140#define EXT_INDEX_LONG(A) BIT_B(A)
141#define EXT_INDEX_AR(A) BIT_F(A)
142#define EXT_BASE_DISPLACEMENT_PRESENT(A) (((A)&0x30) > 0x10)
143#define EXT_BASE_DISPLACEMENT_WORD(A) (((A)&0x30) == 0x20)
144#define EXT_BASE_DISPLACEMENT_LONG(A) (((A)&0x30) == 0x30)
145#define EXT_OUTER_DISPLACEMENT_PRESENT(A) (((A)&3) > 1 && ((A)&0x47) < 0x44)
146#define EXT_OUTER_DISPLACEMENT_WORD(A) (((A)&3) == 2 && ((A)&0x47) < 0x44)
147#define EXT_OUTER_DISPLACEMENT_LONG(A) (((A)&3) == 3 && ((A)&0x47) < 0x44)
148
149#define IS_BITSET(val,b) ((val) & (1 << (b)))
150#define BITFIELD_MASK(sb,eb) (((1 << ((sb) + 1))-1) & (~((1 << (eb))-1)))
151#define BITFIELD(val,sb,eb) ((BITFIELD_MASK(sb,eb) & (val)) >> (eb))
152
Daniel Colline8a4e982015-10-04 14:22:58 +0200153///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
154
Nicolas PLANEL626510c2015-10-12 21:31:16 +1100155static unsigned int m68k_read_disassembler_16(const m68k_info *info, const uint64_t addr)
Daniel Colline8a4e982015-10-04 14:22:58 +0200156{
Nicolas PLANEL97aca802015-10-10 19:55:42 +1100157 const uint16_t v0 = info->code[addr + 0];
158 const uint16_t v1 = info->code[addr + 1];
Daniel Collin988bb632016-04-10 10:55:21 +0200159 return (v0 << 8) | v1;
Daniel Colline8a4e982015-10-04 14:22:58 +0200160}
161
Nicolas PLANEL626510c2015-10-12 21:31:16 +1100162static unsigned int m68k_read_disassembler_32(const m68k_info *info, const uint64_t addr)
Daniel Colline8a4e982015-10-04 14:22:58 +0200163{
Nicolas PLANEL97aca802015-10-10 19:55:42 +1100164 const uint32_t v0 = info->code[addr + 0];
165 const uint32_t v1 = info->code[addr + 1];
166 const uint32_t v2 = info->code[addr + 2];
167 const uint32_t v3 = info->code[addr + 3];
Daniel Colline8a4e982015-10-04 14:22:58 +0200168 return (v0 << 24) | (v1 << 16) | (v2 << 8) | v3;
169}
170
Nicolas PLANEL626510c2015-10-12 21:31:16 +1100171static uint64_t m68k_read_disassembler_64(const m68k_info *info, const uint64_t addr)
Daniel Colline8a4e982015-10-04 14:22:58 +0200172{
Nicolas PLANEL97aca802015-10-10 19:55:42 +1100173 const uint64_t v0 = info->code[addr + 0];
174 const uint64_t v1 = info->code[addr + 1];
175 const uint64_t v2 = info->code[addr + 2];
176 const uint64_t v3 = info->code[addr + 3];
177 const uint64_t v4 = info->code[addr + 4];
178 const uint64_t v5 = info->code[addr + 5];
179 const uint64_t v6 = info->code[addr + 6];
180 const uint64_t v7 = info->code[addr + 7];
Daniel Colline8a4e982015-10-04 14:22:58 +0200181 return (v0 << 56) | (v1 << 48) | (v2 << 40) | (v3 << 32) | (v4 << 24) | (v5 << 16) | (v6 << 8) | v7;
182}
183
Nicolas PLANEL626510c2015-10-12 21:31:16 +1100184static unsigned int m68k_read_safe_16(const m68k_info *info, const uint64_t address)
185{
186 const uint64_t addr = (address - info->baseAddress) & info->address_mask;
187 if (addr > (info->code_len - 2)) {
188 return 0xaaaa;
189 }
190 return m68k_read_disassembler_16(info, addr);
191}
192
193static unsigned int m68k_read_safe_32(const m68k_info *info, const uint64_t address)
194{
195 const uint64_t addr = (address - info->baseAddress) & info->address_mask;
196 if (addr > (info->code_len - 4)) {
197 return 0xaaaaaaaa;
198 }
199 return m68k_read_disassembler_32(info, addr);
200}
201
202static uint64_t m68k_read_safe_64(const m68k_info *info, const uint64_t address)
203{
204 const uint64_t addr = (address - info->baseAddress) & info->address_mask;
205 if (addr > (info->code_len - 8)) {
206 return 0xaaaaaaaaaaaaaaaa;
207 }
208 return m68k_read_disassembler_64(info, addr);
209}
210
Daniel Collin2ee675c2015-08-03 18:45:08 +0200211/* ======================================================================== */
212/* =============================== PROTOTYPES ============================= */
213/* ======================================================================== */
214
Daniel Collin2ee675c2015-08-03 18:45:08 +0200215/* make signed integers 100% portably */
216static int make_int_8(int value);
217static int make_int_16(int value);
218
219/* Stuff to build the opcode handler jump table */
220static void build_opcode_table(void);
221static int valid_ea(uint opcode, uint mask);
222static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100223static void d68000_invalid(m68k_info *info);
224static int instruction_is_valid(m68k_info *info, const unsigned int word_check);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200225
226/* used to build opcode handler jump table */
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800227typedef struct {
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100228 void (*opcode_handler)(m68k_info *info); /* handler function */
Daniel Collin2ee675c2015-08-03 18:45:08 +0200229 uint mask; /* mask on opcode */
230 uint match; /* what to match after masking */
231 uint ea_mask; /* what ea modes are allowed */
232 uint mask2; /* mask the 2nd word */
233 uint match2; /* what to match after masking */
234} opcode_struct;
235
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800236typedef struct {
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100237 void (*instruction)(m68k_info *info); /* handler function */
Daniel Collin2ee675c2015-08-03 18:45:08 +0200238 uint word2_mask; /* mask the 2nd word */
239 uint word2_match; /* what to match after masking */
240} instruction_struct;
241
242/* ======================================================================== */
243/* ================================= DATA ================================= */
244/* ======================================================================== */
245
246/* Opcode handler jump table */
247static instruction_struct g_instruction_table[0x10000];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200248
249/* used by ops like asr, ror, addq, etc */
250static uint g_3bit_qdata_table[8] = {8, 1, 2, 3, 4, 5, 6, 7};
251
Nguyen Anh Quynh48157042015-10-04 17:40:46 +0800252static uint g_5bit_data_table[32] = {
Daniel Collin2ee675c2015-08-03 18:45:08 +0200253 32, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
254 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
255};
256
257static m68k_insn s_branch_lut[] = {
258 M68K_INS_INVALID, M68K_INS_INVALID, M68K_INS_BHI, M68K_INS_BLS,
259 M68K_INS_BCC, M68K_INS_BCS, M68K_INS_BNE, M68K_INS_BEQ,
260 M68K_INS_BVC, M68K_INS_BVS, M68K_INS_BPL, M68K_INS_BMI,
261 M68K_INS_BGE, M68K_INS_BLT, M68K_INS_BGT, M68K_INS_BLE,
262};
263
264static m68k_insn s_dbcc_lut[] = {
265 M68K_INS_DBT, M68K_INS_DBF, M68K_INS_DBHI, M68K_INS_DBLS,
266 M68K_INS_DBCC, M68K_INS_DBCS, M68K_INS_DBNE, M68K_INS_DBEQ,
267 M68K_INS_DBVC, M68K_INS_DBVS, M68K_INS_DBPL, M68K_INS_DBMI,
268 M68K_INS_DBGE, M68K_INS_DBLT, M68K_INS_DBGT, M68K_INS_DBLE,
269};
270
271static m68k_insn s_scc_lut[] = {
272 M68K_INS_ST, M68K_INS_SF, M68K_INS_SHI, M68K_INS_SLS,
273 M68K_INS_SCC, M68K_INS_SCS, M68K_INS_SNE, M68K_INS_SEQ,
274 M68K_INS_SVC, M68K_INS_SVS, M68K_INS_SPL, M68K_INS_SMI,
275 M68K_INS_SGE, M68K_INS_SLT, M68K_INS_SGT, M68K_INS_SLE,
276};
277
278static m68k_insn s_trap_lut[] = {
279 M68K_INS_TRAPT, M68K_INS_TRAPF, M68K_INS_TRAPHI, M68K_INS_TRAPLS,
280 M68K_INS_TRAPCC, M68K_INS_TRAPCS, M68K_INS_TRAPNE, M68K_INS_TRAPEQ,
281 M68K_INS_TRAPVC, M68K_INS_TRAPVS, M68K_INS_TRAPPL, M68K_INS_TRAPMI,
282 M68K_INS_TRAPGE, M68K_INS_TRAPLT, M68K_INS_TRAPGT, M68K_INS_TRAPLE,
283};
284
285/* ======================================================================== */
286/* =========================== UTILITY FUNCTIONS ========================== */
287/* ======================================================================== */
288
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100289#define LIMIT_CPU_TYPES(info, ALLOWED_CPU_TYPES) \
290 do { \
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +0800291 if (!(info->type & ALLOWED_CPU_TYPES)) { \
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100292 d68000_invalid(info); \
293 return; \
294 } \
295 } while (0)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200296
Nicolas PLANEL626510c2015-10-12 21:31:16 +1100297static unsigned int peek_imm_8(const m68k_info *info) { return (m68k_read_safe_16((info), (info)->pc)&0xff); }
298static unsigned int peek_imm_16(const m68k_info *info) { return m68k_read_safe_16((info), (info)->pc); }
299static unsigned int peek_imm_32(const m68k_info *info) { return m68k_read_safe_32((info), (info)->pc); }
Nguyen Anh Quynh586e4392016-03-08 00:49:15 +0800300static unsigned int peek_imm_64(const m68k_info *info) { return (unsigned int)m68k_read_safe_64((info), (info)->pc); }
Nicolas PLANELaf1d39d2015-10-08 22:16:39 +1100301
Nicolas PLANEL97aca802015-10-10 19:55:42 +1100302static unsigned int read_imm_8(m68k_info *info) { const unsigned int value = peek_imm_8(info); (info)->pc+=2; return value; }
303static unsigned int read_imm_16(m68k_info *info) { const unsigned int value = peek_imm_16(info); (info)->pc+=2; return value; }
304static unsigned int read_imm_32(m68k_info *info) { const unsigned int value = peek_imm_32(info); (info)->pc+=4; return value; }
305static unsigned int read_imm_64(m68k_info *info) { const unsigned int value = peek_imm_64(info); (info)->pc+=8; return value; }
Daniel Collin2ee675c2015-08-03 18:45:08 +0200306
307/* Fake a split interface */
308#define get_ea_mode_str_8(instruction) get_ea_mode_str(instruction, 0)
309#define get_ea_mode_str_16(instruction) get_ea_mode_str(instruction, 1)
310#define get_ea_mode_str_32(instruction) get_ea_mode_str(instruction, 2)
311
312#define get_imm_str_s8() get_imm_str_s(0)
313#define get_imm_str_s16() get_imm_str_s(1)
314#define get_imm_str_s32() get_imm_str_s(2)
315
316#define get_imm_str_u8() get_imm_str_u(0)
317#define get_imm_str_u16() get_imm_str_u(1)
318#define get_imm_str_u32() get_imm_str_u(2)
319
320
321/* 100% portable signed int generators */
322static int make_int_8(int value)
323{
324 return (value & 0x80) ? value | ~0xff : value & 0xff;
325}
326
327static int make_int_16(int value)
328{
329 return (value & 0x8000) ? value | ~0xffff : value & 0xffff;
330}
331
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100332static void get_with_index_address_mode(m68k_info *info, cs_m68k_op* op, uint instruction, uint size, bool is_pc)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200333{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100334 uint extension = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200335
336 op->address_mode = M68K_AM_AREGI_INDEX_BASE_DISP;
337
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800338 if (EXT_FULL(extension)) {
Daniel Collin2ee675c2015-08-03 18:45:08 +0200339 uint preindex;
340 uint postindex;
341
342 op->mem.base_reg = M68K_REG_INVALID;
343 op->mem.index_reg = M68K_REG_INVALID;
344
345 /* Not sure how to deal with this?
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +0800346 if (EXT_EFFECTIVE_ZERO(extension)) {
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800347 strcpy(mode, "0");
348 break;
349 }
350 */
Daniel Collin2ee675c2015-08-03 18:45:08 +0200351
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100352 op->mem.in_disp = EXT_BASE_DISPLACEMENT_PRESENT(extension) ? (EXT_BASE_DISPLACEMENT_LONG(extension) ? read_imm_32(info) : read_imm_16(info)) : 0;
353 op->mem.out_disp = EXT_OUTER_DISPLACEMENT_PRESENT(extension) ? (EXT_OUTER_DISPLACEMENT_LONG(extension) ? read_imm_32(info) : read_imm_16(info)) : 0;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200354
355 if (EXT_BASE_REGISTER_PRESENT(extension)) {
356 if (is_pc) {
357 op->mem.base_reg = M68K_REG_PC;
358 } else {
359 op->mem.base_reg = M68K_REG_A0 + (instruction & 7);
360 }
361 }
362
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800363 if (EXT_INDEX_REGISTER_PRESENT(extension)) {
Daniel Collin2ee675c2015-08-03 18:45:08 +0200364 if (EXT_INDEX_AR(extension)) {
365 op->mem.index_reg = M68K_REG_A0 + EXT_INDEX_REGISTER(extension);
366 } else {
367 op->mem.index_reg = M68K_REG_D0 + EXT_INDEX_REGISTER(extension);
368 }
369
370 op->mem.index_size = EXT_INDEX_LONG(extension) ? 1 : 0;
371
372 if (EXT_INDEX_SCALE(extension)) {
373 op->mem.scale = 1 << EXT_INDEX_SCALE(extension);
374 }
375 }
376
377 preindex = (extension & 7) > 0 && (extension & 7) < 4;
378 postindex = (extension & 7) > 4;
379
380 if (preindex) {
381 op->address_mode = is_pc ? M68K_AM_PC_MEMI_PRE_INDEX : M68K_AM_MEMI_PRE_INDEX;
Daniel Collin988bb632016-04-10 10:55:21 +0200382 } else if (postindex) {
Daniel Collin2ee675c2015-08-03 18:45:08 +0200383 op->address_mode = is_pc ? M68K_AM_PC_MEMI_POST_INDEX : M68K_AM_MEMI_POST_INDEX;
384 }
385
386 return;
387 }
388
389 op->mem.index_reg = (EXT_INDEX_AR(extension) ? M68K_REG_A0 : M68K_REG_D0) + EXT_INDEX_REGISTER(extension);
Daniel Collin988bb632016-04-10 10:55:21 +0200390 op->mem.index_size = EXT_INDEX_LONG(extension) ? 1 : 0;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200391
392 if (EXT_8BIT_DISPLACEMENT(extension) == 0) {
393 if (is_pc) {
Daniel Collin988bb632016-04-10 10:55:21 +0200394 op->mem.base_reg = M68K_REG_PC;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200395 op->address_mode = M68K_AM_PCI_INDEX_BASE_DISP;
396 } else {
Daniel Collin988bb632016-04-10 10:55:21 +0200397 op->mem.base_reg = M68K_REG_A0 + (instruction & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200398 }
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800399 } else {
Daniel Collin2ee675c2015-08-03 18:45:08 +0200400 if (is_pc) {
Daniel Collin988bb632016-04-10 10:55:21 +0200401 op->mem.base_reg = M68K_REG_PC;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200402 op->address_mode = M68K_AM_PCI_INDEX_8_BIT_DISP;
403 } else {
Daniel Collin988bb632016-04-10 10:55:21 +0200404 op->mem.base_reg = M68K_REG_A0 + (instruction & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200405 op->address_mode = M68K_AM_AREGI_INDEX_8_BIT_DISP;
406 }
407
408 op->mem.disp = extension & 0xff;
409 }
410
411 if (EXT_INDEX_SCALE(extension)) {
412 op->mem.scale = 1 << EXT_INDEX_SCALE(extension);
413 }
414}
415
416/* Make string of effective address mode */
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100417void get_ea_mode_op(m68k_info *info, cs_m68k_op* op, uint instruction, uint size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200418{
419 // default to memory
420
421 op->type = M68K_OP_MEM;
422
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800423 switch (instruction & 0x3f) {
Daniel Collin2ee675c2015-08-03 18:45:08 +0200424 case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07:
Daniel Collin2ee675c2015-08-03 18:45:08 +0200425 /* data register direct */
426 op->address_mode = M68K_AM_REG_DIRECT_DATA;
427 op->reg = M68K_REG_D0 + (instruction & 7);
428 op->type = M68K_OP_REG;
429 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200430
431 case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f:
Daniel Collin2ee675c2015-08-03 18:45:08 +0200432 /* address register direct */
433 op->address_mode = M68K_AM_REG_DIRECT_ADDR;
434 op->reg = M68K_REG_A0 + (instruction & 7);
435 op->type = M68K_OP_REG;
436 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200437
438 case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
Daniel Collin2ee675c2015-08-03 18:45:08 +0200439 /* address register indirect */
440 op->address_mode = M68K_AM_REGI_ADDR;
441 op->reg = M68K_REG_A0 + (instruction & 7);
442 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200443
444 case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
Daniel Collin2ee675c2015-08-03 18:45:08 +0200445 /* address register indirect with postincrement */
446 op->address_mode = M68K_AM_REGI_ADDR_POST_INC;
447 op->reg = M68K_REG_A0 + (instruction & 7);
448 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200449
450 case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
Daniel Collin2ee675c2015-08-03 18:45:08 +0200451 /* address register indirect with predecrement */
452 op->address_mode = M68K_AM_REGI_ADDR_PRE_DEC;
453 op->reg = M68K_REG_A0 + (instruction & 7);
454 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200455
456 case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
Daniel Collin2ee675c2015-08-03 18:45:08 +0200457 /* address register indirect with displacement*/
458 op->address_mode = M68K_AM_REGI_ADDR_DISP;
459 op->mem.base_reg = M68K_REG_A0 + (instruction & 7);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100460 op->mem.disp = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200461 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200462
463 case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
Daniel Collin2ee675c2015-08-03 18:45:08 +0200464 /* address register indirect with index */
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100465 get_with_index_address_mode(info, op, instruction, size, false);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200466 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200467
468 case 0x38:
Daniel Collin2ee675c2015-08-03 18:45:08 +0200469 /* absolute short address */
470 op->address_mode = M68K_AM_ABSOLUTE_DATA_SHORT;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100471 op->imm = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200472 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200473
474 case 0x39:
Daniel Collin2ee675c2015-08-03 18:45:08 +0200475 /* absolute long address */
476 op->address_mode = M68K_AM_ABSOLUTE_DATA_LONG;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100477 op->imm = read_imm_32(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200478 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200479
480 case 0x3a:
Daniel Collin2ee675c2015-08-03 18:45:08 +0200481 /* program counter with displacement */
482 op->address_mode = M68K_AM_PCI_DISP;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100483 op->mem.disp = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200484 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200485
486 case 0x3b:
Daniel Collin2ee675c2015-08-03 18:45:08 +0200487 /* program counter with index */
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100488 get_with_index_address_mode(info, op, instruction, size, true);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200489 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200490
491 case 0x3c:
Daniel Collin2ee675c2015-08-03 18:45:08 +0200492 op->address_mode = M68K_AM_IMMIDIATE;
493 op->type = M68K_OP_IMM;
494
495 if (size == 1)
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100496 op->imm = read_imm_8(info) & 0xff;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200497 else if (size == 2)
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100498 op->imm = read_imm_16(info) & 0xffff;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200499 else if (size == 4)
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100500 op->imm = read_imm_32(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200501 else
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100502 op->imm = read_imm_64(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200503
504 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200505
506 default:
507 break;
508 }
509}
510
Daniel Collin988bb632016-04-10 10:55:21 +0200511static void set_insn_group(m68k_info *info, m68k_group_type group)
512{
513 info->groups[info->groups_count++] = (uint8_t)group;
514}
515
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100516static cs_m68k* build_init_op(m68k_info *info, int opcode, int count, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200517{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100518 cs_m68k* ext;
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800519
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100520 MCInst_setOpcode(info->inst, opcode);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200521
Nicolas PLANELd529ea02015-10-05 20:19:33 +1100522 ext = &info->extension;
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800523
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100524 ext->op_count = count;
525 ext->op_size.type = M68K_SIZE_TYPE_CPU;
526 ext->op_size.cpu_size = size;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200527
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100528 return ext;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200529}
530
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100531static void build_re_gen_1(m68k_info *info, bool isDreg, int opcode, uint8_t size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200532{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800533 cs_m68k_op* op0;
534 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100535 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200536
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100537 op0 = &ext->operands[0];
538 op1 = &ext->operands[1];
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800539
Daniel Collin2ee675c2015-08-03 18:45:08 +0200540 if (isDreg) {
541 op0->address_mode = M68K_AM_REG_DIRECT_DATA;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100542 op0->reg = M68K_REG_D0 + ((info->ir >> 9 ) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200543 } else {
544 op0->address_mode = M68K_AM_REG_DIRECT_ADDR;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100545 op0->reg = M68K_REG_A0 + ((info->ir >> 9 ) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200546 }
547
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100548 get_ea_mode_op(info, op1, info->ir, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200549}
550
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100551static void build_re_1(m68k_info *info, int opcode, uint8_t size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200552{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100553 build_re_gen_1(info, true, opcode, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200554}
555
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100556static void build_er_gen_1(m68k_info *info, bool isDreg, int opcode, uint8_t size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200557{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800558 cs_m68k_op* op0;
559 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100560 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200561
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100562 op0 = &ext->operands[0];
563 op1 = &ext->operands[1];
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800564
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100565 get_ea_mode_op(info, op0, info->ir, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200566
567 if (isDreg) {
568 op1->address_mode = M68K_AM_REG_DIRECT_DATA;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100569 op1->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200570 } else {
571 op1->address_mode = M68K_AM_REG_DIRECT_ADDR;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100572 op1->reg = M68K_REG_A0 + ((info->ir >> 9) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200573 }
574}
575
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100576static void build_rr(m68k_info *info, int opcode, uint8_t size, int imm)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200577{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800578 cs_m68k_op* op0;
579 cs_m68k_op* op1;
580 cs_m68k_op* op2;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100581 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200582
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100583 op0 = &ext->operands[0];
584 op1 = &ext->operands[1];
585 op2 = &ext->operands[2];
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800586
Daniel Collin2ee675c2015-08-03 18:45:08 +0200587 op0->address_mode = M68K_AM_REG_DIRECT_DATA;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100588 op0->reg = M68K_REG_D0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200589
590 op1->address_mode = M68K_AM_REG_DIRECT_DATA;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100591 op1->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200592
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800593 if (imm > 0) {
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100594 ext->op_count = 3;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200595 op2->type = M68K_OP_IMM;
596 op2->address_mode = M68K_AM_IMMIDIATE;
597 op2->imm = imm;
598 }
599}
600
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100601static void build_r(m68k_info *info, int opcode, uint8_t size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200602{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800603 cs_m68k_op* op0;
604 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100605 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200606
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100607 op0 = &ext->operands[0];
608 op1 = &ext->operands[1];
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800609
Daniel Collin2ee675c2015-08-03 18:45:08 +0200610 op0->address_mode = M68K_AM_REG_DIRECT_DATA;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100611 op0->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200612
613 op1->address_mode = M68K_AM_REG_DIRECT_DATA;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100614 op1->reg = M68K_REG_D0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200615}
616
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100617static void build_imm_ea(m68k_info *info, int opcode, uint8_t size, int imm)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200618{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800619 cs_m68k_op* op0;
620 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100621 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200622
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100623 op0 = &ext->operands[0];
624 op1 = &ext->operands[1];
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800625
Daniel Collin2ee675c2015-08-03 18:45:08 +0200626 op0->type = M68K_OP_IMM;
627 op0->address_mode = M68K_AM_IMMIDIATE;
Daniel Collin988bb632016-04-10 10:55:21 +0200628 op0->imm = imm;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200629
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100630 get_ea_mode_op(info, op1, info->ir, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200631}
632
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100633static void build_3bit_d(m68k_info *info, int opcode, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200634{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800635 cs_m68k_op* op0;
636 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100637 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200638
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100639 op0 = &ext->operands[0];
640 op1 = &ext->operands[1];
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800641
Daniel Collin2ee675c2015-08-03 18:45:08 +0200642 op0->type = M68K_OP_IMM;
643 op0->address_mode = M68K_AM_IMMIDIATE;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100644 op0->imm = g_3bit_qdata_table[(info->ir >> 9) & 7];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200645
646 op1->address_mode = M68K_AM_REG_DIRECT_DATA;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100647 op1->reg = M68K_REG_D0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200648}
649
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100650static void build_3bit_ea(m68k_info *info, int opcode, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200651{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800652 cs_m68k_op* op0;
653 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100654 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200655
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100656 op0 = &ext->operands[0];
657 op1 = &ext->operands[1];
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800658
Daniel Collin2ee675c2015-08-03 18:45:08 +0200659 op0->type = M68K_OP_IMM;
660 op0->address_mode = M68K_AM_IMMIDIATE;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100661 op0->imm = g_3bit_qdata_table[(info->ir >> 9) & 7];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200662
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100663 get_ea_mode_op(info, op1, info->ir, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200664}
665
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100666static void build_mm(m68k_info *info, int opcode, uint8_t size, int imm)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200667{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800668 cs_m68k_op* op0;
669 cs_m68k_op* op1;
670 cs_m68k_op* op2;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100671 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200672
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100673 op0 = &ext->operands[0];
674 op1 = &ext->operands[1];
675 op2 = &ext->operands[2];
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800676
Daniel Collin2ee675c2015-08-03 18:45:08 +0200677 op0->address_mode = M68K_AM_REGI_ADDR_PRE_DEC;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100678 op0->reg = M68K_REG_A0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200679
680 op1->address_mode = M68K_AM_REGI_ADDR_PRE_DEC;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100681 op1->reg = M68K_REG_A0 + ((info->ir >> 9) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200682
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800683 if (imm > 0) {
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100684 ext->op_count = 3;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200685 op2->type = M68K_OP_IMM;
686 op2->address_mode = M68K_AM_IMMIDIATE;
687 op2->imm = imm;
688 }
689}
690
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100691static void build_ea(m68k_info *info, int opcode, uint8_t size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200692{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100693 cs_m68k* ext = build_init_op(info, opcode, 1, size);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100694 get_ea_mode_op(info, &ext->operands[0], info->ir, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200695}
696
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100697static void build_ea_a(m68k_info *info, int opcode, uint8_t size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200698{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800699 cs_m68k_op* op0;
700 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100701 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200702
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100703 op0 = &ext->operands[0];
704 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200705
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100706 get_ea_mode_op(info, op0, info->ir, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200707
708 op1->address_mode = M68K_AM_REG_DIRECT_ADDR;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100709 op1->reg = M68K_REG_A0 + ((info->ir >> 9) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200710}
711
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100712static void build_ea_ea(m68k_info *info, int opcode, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200713{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800714 cs_m68k_op* op0;
715 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100716 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200717
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100718 op0 = &ext->operands[0];
719 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200720
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100721 get_ea_mode_op(info, op0, info->ir, size);
722 get_ea_mode_op(info, op1, (((info->ir>>9) & 7) | ((info->ir>>3) & 0x38)), size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200723}
724
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100725static void build_pi_pi(m68k_info *info, int opcode, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200726{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800727 cs_m68k_op* op0;
728 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100729 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200730
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100731 op0 = &ext->operands[0];
732 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200733
734 op0->address_mode = M68K_AM_REGI_ADDR_POST_INC;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100735 op0->reg = M68K_REG_A0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200736
737 op1->address_mode = M68K_AM_REGI_ADDR_POST_INC;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100738 op1->reg = M68K_REG_A0 + ((info->ir >> 9) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200739}
740
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100741static void build_imm_special_reg(m68k_info *info, int opcode, int imm, int size, m68k_reg reg)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200742{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800743 cs_m68k_op* op0;
744 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100745 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200746
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100747 op0 = &ext->operands[0];
748 op1 = &ext->operands[1];
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800749
Daniel Collin2ee675c2015-08-03 18:45:08 +0200750 op0->type = M68K_OP_IMM;
751 op0->address_mode = M68K_AM_IMMIDIATE;
Daniel Collin988bb632016-04-10 10:55:21 +0200752 op0->imm = imm;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200753
754 op1->address_mode = M68K_AM_NONE;
Daniel Collin988bb632016-04-10 10:55:21 +0200755 op1->reg = reg;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200756}
757
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100758static void build_bxx(m68k_info *info, int opcode, int size, int jump_offset)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200759{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800760 cs_m68k_op* op;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100761 cs_m68k* ext = build_init_op(info, opcode, 1, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200762
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100763 op = &ext->operands[0];
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800764
Daniel Collin2ee675c2015-08-03 18:45:08 +0200765 op->type = M68K_OP_IMM;
766 op->address_mode = M68K_AM_IMMIDIATE;
767 op->imm = jump_offset;
Daniel Collin988bb632016-04-10 10:55:21 +0200768
769 set_insn_group(info, M68K_GRP_JUMP);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200770}
771
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100772static void build_bcc(m68k_info *info, int size, int jump_offset)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200773{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100774 build_bxx(info, s_branch_lut[(info->ir >> 8) & 0xf], size, jump_offset);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200775}
776
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100777static void build_trap(m68k_info *info, int size, int jump_offset)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200778{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100779 build_bxx(info, s_trap_lut[(info->ir >> 8) & 0xf], size, jump_offset);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200780}
781
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100782static void build_dbxx(m68k_info *info, int opcode, int size, int jump_offset)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200783{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800784 cs_m68k_op* op0;
785 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100786 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200787
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100788 op0 = &ext->operands[0];
789 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200790
791 op0->address_mode = M68K_AM_REG_DIRECT_DATA;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100792 op0->reg = M68K_REG_D0 + (info->ir & 7);
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800793
Daniel Collin2ee675c2015-08-03 18:45:08 +0200794 op1->type = M68K_OP_IMM;
795 op1->address_mode = M68K_AM_IMMIDIATE;
796 op1->imm = jump_offset;
Daniel Collin988bb632016-04-10 10:55:21 +0200797
798 set_insn_group(info, M68K_GRP_JUMP);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200799}
800
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100801static void build_dbcc(m68k_info *info, int size, int jump_offset)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200802{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100803 build_dbxx(info, s_dbcc_lut[(info->ir >> 8) & 0xf], size, jump_offset);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200804}
805
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100806static void build_d_d_ea(m68k_info *info, int opcode, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200807{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800808 cs_m68k_op* op0;
809 cs_m68k_op* op1;
810 cs_m68k_op* op2;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100811 uint extension = read_imm_16(info);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100812 cs_m68k* ext = build_init_op(info, opcode, 3, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200813
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100814 op0 = &ext->operands[0];
815 op1 = &ext->operands[1];
816 op2 = &ext->operands[2];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200817
818 op0->address_mode = M68K_AM_REG_DIRECT_DATA;
819 op0->reg = M68K_REG_D0 + (extension & 7);
820
821 op1->address_mode = M68K_AM_REG_DIRECT_DATA;
822 op1->reg = M68K_REG_D0 + ((extension >> 6) & 7);
823
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100824 get_ea_mode_op(info, op2, info->ir, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200825}
826
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100827static void build_bitfield_ins(m68k_info *info, int opcode, int has_d_arg)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200828{
829 uint8_t offset;
830 uint8_t width;
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800831 cs_m68k_op* op_ea;
832 cs_m68k_op* op1;
Nicolas PLANELd529ea02015-10-05 20:19:33 +1100833 cs_m68k* ext = build_init_op(info, opcode, 1, 0);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100834 uint extension = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200835
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100836 op_ea = &ext->operands[0];
837 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200838
839 if (BIT_B(extension))
840 offset = (extension >> 6) & 7;
841 else
842 offset = (extension >> 6) & 31;
843
844 if (BIT_5(extension))
845 width = extension & 7;
846 else
847 width = g_5bit_data_table[extension & 31];
848
849 if (has_d_arg) {
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100850 ext->op_count = 2;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200851 op1->address_mode = M68K_AM_REG_DIRECT_DATA;
852 op1->reg = M68K_REG_D0 + ((extension >> 12) & 7);
853 }
854
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100855 get_ea_mode_op(info, op_ea, info->ir, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200856
857 op_ea->mem.bitfield = 1;
858 op_ea->mem.width = width;
859 op_ea->mem.offset = offset;
860}
861
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100862static void build_d(m68k_info *info, int opcode, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200863{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100864 cs_m68k* ext = build_init_op(info, opcode, 1, size);
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800865 cs_m68k_op* op;
866
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100867 op = &ext->operands[0];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200868
869 op->address_mode = M68K_AM_REG_DIRECT_DATA;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100870 op->reg = M68K_REG_D0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200871}
872
873static uint16_t reverse_bits(uint v)
874{
875 uint r = v; // r will be reversed bits of v; first get LSB of v
876 uint s = 16 - 1; // extra shift needed at end
877
Daniel Collin988bb632016-04-10 10:55:21 +0200878 for (v >>= 1; v; v >>= 1) {
Daniel Collin2ee675c2015-08-03 18:45:08 +0200879 r <<= 1;
880 r |= v & 1;
881 s--;
882 }
883
884 return r <<= s; // shift when v's highest bits are zero
885}
886
887static uint8_t reverse_bits_8(uint v)
888{
889 uint r = v; // r will be reversed bits of v; first get LSB of v
890 uint s = 8 - 1; // extra shift needed at end
891
Daniel Collin988bb632016-04-10 10:55:21 +0200892 for (v >>= 1; v; v >>= 1) {
Daniel Collin2ee675c2015-08-03 18:45:08 +0200893 r <<= 1;
894 r |= v & 1;
895 s--;
896 }
897
898 return r <<= s; // shift when v's highest bits are zero
899}
900
901
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100902static void build_movem_re(m68k_info *info, int opcode, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200903{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800904 cs_m68k_op* op0;
905 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100906 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200907
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100908 op0 = &ext->operands[0];
909 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200910
911 op0->type = M68K_OP_REG_BITS;
jmechnich97ae4c32016-03-25 22:04:04 +0100912 op0->register_bits = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200913
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100914 get_ea_mode_op(info, op1, info->ir, size);
jmechnich97ae4c32016-03-25 22:04:04 +0100915
Nguyen Anh Quynh43b69a82016-03-30 09:39:24 +0800916 if (op1->address_mode == M68K_AM_REGI_ADDR_PRE_DEC)
917 op0->register_bits = reverse_bits(op0->register_bits);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200918}
919
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100920static void build_movem_er(m68k_info *info, int opcode, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200921{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800922 cs_m68k_op* op0;
923 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100924 cs_m68k* ext = build_init_op(info, opcode, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200925
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100926 op0 = &ext->operands[0];
927 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200928
Daniel Collin2ee675c2015-08-03 18:45:08 +0200929 op1->type = M68K_OP_REG_BITS;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100930 op1->register_bits = read_imm_16(info);
jmechnich97ae4c32016-03-25 22:04:04 +0100931
932 get_ea_mode_op(info, op0, info->ir, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200933}
934
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100935static void build_imm(m68k_info *info, int opcode, int data)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200936{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800937 cs_m68k_op* op;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100938 cs_m68k* ext = build_init_op(info, opcode, 1, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200939
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100940 MCInst_setOpcode(info->inst, opcode);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200941
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100942 op = &ext->operands[0];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200943
944 op->type = M68K_OP_IMM;
945 op->address_mode = M68K_AM_IMMIDIATE;
946 op->imm = data;
947}
948
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100949static void build_illegal(m68k_info *info, int data)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200950{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100951 build_imm(info, M68K_INS_ILLEGAL, data);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200952}
953
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100954static void build_invalid(m68k_info *info, int data)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200955{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100956 build_imm(info, M68K_INS_INVALID, data);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200957}
958
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100959static void build_cas2(m68k_info *info, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200960{
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800961 uint word3;
962 uint extension;
963 cs_m68k_op* op0;
964 cs_m68k_op* op1;
965 cs_m68k_op* op2;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100966 cs_m68k* ext = build_init_op(info, M68K_INS_CAS2, 3, size);
Nicolas PLANELd529ea02015-10-05 20:19:33 +1100967 int reg_0, reg_1;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200968
969 /* cas2 is the only 3 words instruction, word2 and word3 have the same motif bits to check */
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100970 word3 = peek_imm_32(info) & 0xffff;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +0800971 if (!instruction_is_valid(info, word3))
Daniel Collin2ee675c2015-08-03 18:45:08 +0200972 return;
973
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100974 op0 = &ext->operands[0];
975 op1 = &ext->operands[1];
976 op2 = &ext->operands[2];
Daniel Collin2ee675c2015-08-03 18:45:08 +0200977
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100978 extension = read_imm_32(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +0200979
980 op0->address_mode = M68K_AM_NONE;
981 op0->type = M68K_OP_REG_PAIR;
982 op0->register_bits = (((extension >> 16) & 7) << 4) | (extension & 7);
983
984 op1->address_mode = M68K_AM_NONE;
985 op1->type = M68K_OP_REG_PAIR;
986 op1->register_bits = (((extension >> 22) & 7) << 4) | ((extension >> 6) & 7);
987
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800988 reg_0 = (extension >> 28) & 7;
989 reg_1 = (extension >> 12) & 7;
Daniel Collin2ee675c2015-08-03 18:45:08 +0200990
991 op2->address_mode = M68K_AM_NONE;
992 op2->type = M68K_OP_REG_PAIR;
993 op2->register_bits = ((reg_0 + (BIT_1F(extension) ? 8 : 0)) << 4) |
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +0800994 (reg_1 + (BIT_F(extension) ? 8 : 0));
Daniel Collin2ee675c2015-08-03 18:45:08 +0200995}
996
Nicolas PLANEL3a64e582015-10-04 20:07:57 +1100997static void build_chk2_cmp2(m68k_info *info, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +0200998{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +0800999 cs_m68k_op* op0;
1000 cs_m68k_op* op1;
Nicolas PLANELd529ea02015-10-05 20:19:33 +11001001 cs_m68k* ext = build_init_op(info, M68K_INS_CHK2, 2, size);
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001002
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001003 uint extension = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001004
Daniel Collin2ee675c2015-08-03 18:45:08 +02001005 if (BIT_B(extension))
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001006 MCInst_setOpcode(info->inst, M68K_INS_CHK2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001007 else
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001008 MCInst_setOpcode(info->inst, M68K_INS_CMP2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001009
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001010 op0 = &ext->operands[0];
1011 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02001012
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001013 get_ea_mode_op(info, op0, info->ir, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001014
1015 op1->address_mode = M68K_AM_NONE;
1016 op1->type = M68K_OP_REG;
1017 op1->reg = (BIT_F(extension) ? M68K_REG_A0 : M68K_REG_D0) + ((extension >> 12) & 7);
1018}
1019
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001020static void build_move16(m68k_info *info, int data[2], int modes[2])
Daniel Collin2ee675c2015-08-03 18:45:08 +02001021{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001022 cs_m68k* ext = build_init_op(info, M68K_INS_MOVE16, 2, 0);
Nicolas PLANELd529ea02015-10-05 20:19:33 +11001023 int i;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001024
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08001025 for (i = 0; i < 2; ++i) {
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001026 cs_m68k_op* op = &ext->operands[i];
1027 const int d = data[i];
1028 const int m = modes[i];
Daniel Collin2ee675c2015-08-03 18:45:08 +02001029
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08001030 op->type = M68K_OP_MEM;
1031
Daniel Collin2ee675c2015-08-03 18:45:08 +02001032 if (m == M68K_AM_REGI_ADDR_POST_INC || m == M68K_AM_REG_DIRECT_ADDR) {
1033 op->address_mode = m;
1034 op->reg = M68K_REG_A0 + d;
1035 } else {
1036 op->address_mode = m;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001037 op->imm = d;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001038 }
1039 }
1040}
1041
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001042static void build_link(m68k_info *info, int disp, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001043{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001044 cs_m68k_op* op0;
1045 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001046 cs_m68k* ext = build_init_op(info, M68K_INS_LINK, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001047
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001048 op0 = &ext->operands[0];
1049 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02001050
1051 op0->address_mode = M68K_AM_NONE;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001052 op0->reg = M68K_REG_A0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001053
1054 op1->address_mode = M68K_AM_IMMIDIATE;
1055 op1->type = M68K_OP_IMM;
1056 op1->imm = disp;
1057}
1058
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001059static void build_cpush_cinv(m68k_info *info, int op_offset)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001060{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001061 cs_m68k_op* op0;
1062 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001063 cs_m68k* ext = build_init_op(info, M68K_INS_INVALID, 2, 0);
Nicolas PLANELd529ea02015-10-05 20:19:33 +11001064
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001065 switch ((info->ir >> 3) & 3) { // scope
Nicolas PLANEL858b8cb2015-10-03 21:36:18 +10001066 // Invalid
Daniel Collin988bb632016-04-10 10:55:21 +02001067 case 0:
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001068 d68000_invalid(info);
Nicolas PLANEL858b8cb2015-10-03 21:36:18 +10001069 return;
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08001070 // Line
Daniel Collin2ee675c2015-08-03 18:45:08 +02001071 case 1:
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001072 MCInst_setOpcode(info->inst, op_offset + 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001073 break;
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08001074 // Page
Daniel Collin2ee675c2015-08-03 18:45:08 +02001075 case 2:
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001076 MCInst_setOpcode(info->inst, op_offset + 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001077 break;
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08001078 // All
Daniel Collin2ee675c2015-08-03 18:45:08 +02001079 case 3:
Nicolas PLANELe661bd02015-10-07 17:58:38 +11001080 ext->op_count = 1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001081 MCInst_setOpcode(info->inst, op_offset + 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001082 break;
1083 }
1084
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001085 op0 = &ext->operands[0];
1086 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02001087
1088 op0->address_mode = M68K_AM_IMMIDIATE;
1089 op0->type = M68K_OP_IMM;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001090 op0->imm = (info->ir >> 6) & 3;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001091
1092 op1->type = M68K_OP_MEM;
1093 op1->address_mode = M68K_AM_REG_DIRECT_ADDR;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001094 op1->imm = M68K_REG_A0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001095}
1096
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001097static void build_movep_re(m68k_info *info, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001098{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001099 cs_m68k_op* op0;
1100 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001101 cs_m68k* ext = build_init_op(info, M68K_INS_MOVEP, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001102
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001103 op0 = &ext->operands[0];
1104 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02001105
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001106 op0->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001107
1108 op1->address_mode = M68K_AM_REGI_ADDR_DISP;
1109 op1->type = M68K_OP_MEM;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001110 op1->mem.base_reg = M68K_REG_A0 + (info->ir & 7);
1111 op1->mem.disp = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001112}
1113
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001114static void build_movep_er(m68k_info *info, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001115{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001116 cs_m68k_op* op0;
1117 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001118 cs_m68k* ext = build_init_op(info, M68K_INS_MOVEP, 2, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001119
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001120 op0 = &ext->operands[0];
1121 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02001122
1123 op0->address_mode = M68K_AM_REGI_ADDR_DISP;
1124 op0->type = M68K_OP_MEM;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001125 op0->mem.base_reg = M68K_REG_A0 + (info->ir & 7);
1126 op0->mem.disp = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001127
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001128 op1->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001129}
1130
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001131static void build_moves(m68k_info *info, int size)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001132{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001133 cs_m68k_op* op0;
1134 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001135 cs_m68k* ext = build_init_op(info, M68K_INS_MOVES, 2, size);
Nicolas PLANELd529ea02015-10-05 20:19:33 +11001136 uint extension = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001137
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001138 op0 = &ext->operands[0];
1139 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02001140
1141 if (BIT_B(extension)) {
1142 op0->reg = (BIT_F(extension) ? M68K_REG_A0 : M68K_REG_D0) + ((extension >> 12) & 7);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001143 get_ea_mode_op(info, op1, info->ir, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001144 } else {
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001145 get_ea_mode_op(info, op0, info->ir, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001146 op1->reg = (BIT_F(extension) ? M68K_REG_A0 : M68K_REG_D0) + ((extension >> 12) & 7);
1147 }
1148}
1149
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001150static void build_er_1(m68k_info *info, int opcode, uint8_t size)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001151{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001152 build_er_gen_1(info, true, opcode, size);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001153}
1154
1155/* ======================================================================== */
1156/* ========================= INSTRUCTION HANDLERS ========================= */
1157/* ======================================================================== */
1158/* Instruction handler function names follow this convention:
1159 *
1160 * d68000_NAME_EXTENSIONS(void)
1161 * where NAME is the name of the opcode it handles and EXTENSIONS are any
1162 * extensions for special instances of that opcode.
1163 *
1164 * Examples:
1165 * d68000_add_er_8(): add opcode, from effective address to register,
1166 * size = byte
1167 *
1168 * d68000_asr_s_8(): arithmetic shift right, static count, size = byte
1169 *
1170 *
1171 * Common extensions:
1172 * 8 : size = byte
1173 * 16 : size = word
1174 * 32 : size = long
1175 * rr : register to register
1176 * mm : memory to memory
1177 * r : register
1178 * s : static
1179 * er : effective address -> register
1180 * re : register -> effective address
1181 * ea : using effective address mode of operation
1182 * d : data register direct
1183 * a : address register direct
1184 * ai : address register indirect
1185 * pi : address register indirect with postincrement
1186 * pd : address register indirect with predecrement
1187 * di : address register indirect with displacement
1188 * ix : address register indirect with index
1189 * aw : absolute word
1190 * al : absolute long
1191 */
1192
1193
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001194static void d68000_invalid(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001195{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001196 build_invalid(info, info->ir);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001197}
1198
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001199static void d68000_illegal(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001200{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001201 build_illegal(info, info->ir);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001202}
1203
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001204static void d68000_1010(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001205{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001206 build_invalid(info, info->ir);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001207}
1208
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001209static void d68000_1111(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001210{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001211 build_invalid(info, info->ir);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001212}
1213
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001214static void d68000_abcd_rr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001215{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001216 build_rr(info, M68K_INS_ABCD, 1, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001217}
1218
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001219static void d68000_abcd_mm(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001220{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001221 build_mm(info, M68K_INS_ABCD, 1, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001222}
1223
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001224static void d68000_add_er_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001225{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001226 build_er_1(info, M68K_INS_ADD, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001227}
1228
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001229static void d68000_add_er_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001230{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001231 build_er_1(info, M68K_INS_ADD, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001232}
1233
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001234static void d68000_add_er_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001235{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001236 build_er_1(info, M68K_INS_ADD, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001237}
1238
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001239static void d68000_add_re_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001240{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001241 build_re_1(info, M68K_INS_ADD, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001242}
1243
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001244static void d68000_add_re_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001245{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001246 build_re_1(info, M68K_INS_ADD, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001247}
1248
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001249static void d68000_add_re_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001250{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001251 build_re_1(info, M68K_INS_ADD, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001252}
1253
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001254static void d68000_adda_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001255{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001256 build_ea_a(info, M68K_INS_ADDA, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001257}
1258
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001259static void d68000_adda_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001260{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001261 build_ea_a(info, M68K_INS_ADDA, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001262}
1263
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001264static void d68000_addi_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001265{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001266 build_imm_ea(info, M68K_INS_ADDI, 1, read_imm_8(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001267}
1268
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001269static void d68000_addi_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001270{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001271 build_imm_ea(info, M68K_INS_ADDI, 2, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001272}
1273
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001274static void d68000_addi_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001275{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001276 build_imm_ea(info, M68K_INS_ADDI, 4, read_imm_32(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001277}
1278
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001279static void d68000_addq_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001280{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001281 build_3bit_ea(info, M68K_INS_ADDQ, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001282}
1283
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001284static void d68000_addq_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001285{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001286 build_3bit_ea(info, M68K_INS_ADDQ, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001287}
1288
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001289static void d68000_addq_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001290{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001291 build_3bit_ea(info, M68K_INS_ADDQ, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001292}
1293
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001294static void d68000_addx_rr_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001295{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001296 build_rr(info, M68K_INS_ADDX, 1, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001297}
1298
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001299static void d68000_addx_rr_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001300{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001301 build_rr(info, M68K_INS_ADDX, 2, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001302}
1303
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001304static void d68000_addx_rr_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001305{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001306 build_rr(info, M68K_INS_ADDX, 4, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001307}
1308
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001309static void d68000_addx_mm_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001310{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001311 build_mm(info, M68K_INS_ADDX, 1, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001312}
1313
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001314static void d68000_addx_mm_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001315{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001316 build_mm(info, M68K_INS_ADDX, 2, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001317}
1318
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001319static void d68000_addx_mm_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001320{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001321 build_mm(info, M68K_INS_ADDX, 4, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001322}
1323
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001324static void d68000_and_er_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001325{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001326 build_er_1(info, M68K_INS_AND, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001327}
1328
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001329static void d68000_and_er_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001330{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001331 build_er_1(info, M68K_INS_AND, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001332}
1333
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001334static void d68000_and_er_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001335{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001336 build_er_1(info, M68K_INS_AND, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001337}
1338
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001339static void d68000_and_re_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001340{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001341 build_re_1(info, M68K_INS_AND, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001342}
1343
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001344static void d68000_and_re_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001345{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001346 build_re_1(info, M68K_INS_AND, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001347}
1348
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001349static void d68000_and_re_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001350{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001351 build_re_1(info, M68K_INS_AND, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001352}
1353
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001354static void d68000_andi_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001355{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001356 build_imm_ea(info, M68K_INS_ANDI, 1, read_imm_8(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001357}
1358
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001359static void d68000_andi_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001360{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001361 build_imm_ea(info, M68K_INS_ANDI, 2, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001362}
1363
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001364static void d68000_andi_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001365{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001366 build_imm_ea(info, M68K_INS_ANDI, 4, read_imm_32(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001367}
1368
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001369static void d68000_andi_to_ccr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001370{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001371 build_imm_special_reg(info, M68K_INS_ANDI, read_imm_8(info), 1, M68K_REG_CCR);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001372}
1373
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001374static void d68000_andi_to_sr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001375{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001376 build_imm_special_reg(info, M68K_INS_ANDI, read_imm_16(info), 2, M68K_REG_SR);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001377}
1378
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001379static void d68000_asr_s_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001380{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001381 build_3bit_d(info, M68K_INS_ASR, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001382}
1383
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001384static void d68000_asr_s_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001385{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001386 build_3bit_d(info, M68K_INS_ASR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001387}
1388
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001389static void d68000_asr_s_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001390{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001391 build_3bit_d(info, M68K_INS_ASR, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001392}
1393
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001394static void d68000_asr_r_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001395{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001396 build_r(info, M68K_INS_ASR, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001397}
1398
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001399static void d68000_asr_r_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001400{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001401 build_r(info, M68K_INS_ASR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001402}
1403
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001404static void d68000_asr_r_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001405{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001406 build_r(info, M68K_INS_ASR, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001407}
1408
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001409static void d68000_asr_ea(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001410{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001411 build_ea(info, M68K_INS_ASR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001412}
1413
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001414static void d68000_asl_s_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001415{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001416 build_3bit_d(info, M68K_INS_ASL, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001417}
1418
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001419static void d68000_asl_s_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001420{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001421 build_3bit_d(info, M68K_INS_ASL, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001422}
1423
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001424static void d68000_asl_s_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001425{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001426 build_3bit_d(info, M68K_INS_ASL, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001427}
1428
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001429static void d68000_asl_r_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001430{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001431 build_r(info, M68K_INS_ASL, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001432}
1433
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001434static void d68000_asl_r_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001435{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001436 build_r(info, M68K_INS_ASL, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001437}
1438
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001439static void d68000_asl_r_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001440{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001441 build_r(info, M68K_INS_ASL, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001442}
1443
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001444static void d68000_asl_ea(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001445{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001446 build_ea(info, M68K_INS_ASL, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001447}
1448
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001449static void d68000_bcc_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001450{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001451 uint temp_pc = info->pc;
1452 build_bcc(info, 1, temp_pc + make_int_8(info->ir));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001453}
1454
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001455static void d68000_bcc_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001456{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001457 uint temp_pc = info->pc;
1458 build_bcc(info, 2, temp_pc + make_int_16(read_imm_16(info)));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001459}
1460
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001461static void d68020_bcc_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001462{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001463 uint temp_pc = info->pc;
1464 LIMIT_CPU_TYPES(info, M68020_PLUS);
1465 build_bcc(info, 4, temp_pc + read_imm_32(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001466}
1467
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001468static void d68000_bchg_r(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001469{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001470 build_re_1(info, M68K_INS_BCHG, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001471}
1472
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001473static void d68000_bchg_s(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001474{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001475 build_imm_ea(info, M68K_INS_BCHG, 1, read_imm_8(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001476}
1477
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001478static void d68000_bclr_r(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001479{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001480 build_re_1(info, M68K_INS_BCLR, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001481}
1482
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001483static void d68000_bclr_s(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001484{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001485 build_imm_ea(info, M68K_INS_BCLR, 1, read_imm_8(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001486}
1487
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001488static void d68010_bkpt(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001489{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001490 LIMIT_CPU_TYPES(info, M68010_PLUS);
1491 build_bxx(info, M68K_INS_BKPT, 0, info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001492}
1493
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001494static void d68020_bfchg(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001495{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001496 LIMIT_CPU_TYPES(info, M68020_PLUS);
1497 build_bitfield_ins(info, M68K_INS_BFCHG, false);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001498}
1499
1500
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001501static void d68020_bfclr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001502{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001503 LIMIT_CPU_TYPES(info, M68020_PLUS);
1504 build_bitfield_ins(info, M68K_INS_BFCLR, false);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001505}
1506
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001507static void d68020_bfexts(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001508{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001509 LIMIT_CPU_TYPES(info, M68020_PLUS);
1510 build_bitfield_ins(info, M68K_INS_BFEXTS, true);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001511}
1512
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001513static void d68020_bfextu(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001514{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001515 LIMIT_CPU_TYPES(info, M68020_PLUS);
1516 build_bitfield_ins(info, M68K_INS_BFEXTU, true);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001517}
1518
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001519static void d68020_bfffo(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001520{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001521 LIMIT_CPU_TYPES(info, M68020_PLUS);
1522 build_bitfield_ins(info, M68K_INS_BFFFO, true);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001523}
1524
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001525static void d68020_bfins(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001526{
Nicolas PLANELd529ea02015-10-05 20:19:33 +11001527 cs_m68k* ext = &info->extension;
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001528 cs_m68k_op temp;
1529
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001530 LIMIT_CPU_TYPES(info, M68020_PLUS);
1531 build_bitfield_ins(info, M68K_INS_BFINS, true);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001532
Daniel Collin2ee675c2015-08-03 18:45:08 +02001533 // a bit hacky but we need to flip the args on only this instruction
1534
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001535 temp = ext->operands[0];
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001536 ext->operands[0] = ext->operands[1];
1537 ext->operands[1] = temp;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001538}
1539
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001540static void d68020_bfset(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001541{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001542 LIMIT_CPU_TYPES(info, M68020_PLUS);
1543 build_bitfield_ins(info, M68K_INS_BFSET, false);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001544}
1545
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001546static void d68020_bftst(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001547{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001548 build_bitfield_ins(info, M68K_INS_BFTST, false);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001549}
1550
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001551static void d68000_bra_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001552{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001553 uint temp_pc = info->pc;
1554 build_bxx(info, M68K_INS_BRA, 1, temp_pc + make_int_8(info->ir));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001555}
1556
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001557static void d68000_bra_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001558{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001559 uint temp_pc = info->pc;
1560 build_bxx(info, M68K_INS_BRA, 2, temp_pc + make_int_16(read_imm_16(info)));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001561}
1562
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001563static void d68020_bra_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001564{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001565 uint temp_pc = info->pc;
1566 LIMIT_CPU_TYPES(info, M68020_PLUS);
1567 build_bxx(info, M68K_INS_BRA, 4, temp_pc + read_imm_32(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001568}
1569
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001570static void d68000_bset_r(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001571{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001572 build_re_1(info, M68K_INS_BSET, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001573}
1574
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001575static void d68000_bset_s(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001576{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001577 build_imm_ea(info, M68K_INS_BSET, 1, read_imm_8(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001578}
1579
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001580static void d68000_bsr_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001581{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001582 uint temp_pc = info->pc;
1583 build_bxx(info, M68K_INS_BSR, 1, temp_pc + make_int_8(info->ir));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001584}
1585
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001586static void d68000_bsr_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001587{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001588 uint temp_pc = info->pc;
1589 build_bxx(info, M68K_INS_BSR, 2, temp_pc + make_int_16(read_imm_16(info)));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001590}
1591
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001592static void d68020_bsr_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001593{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001594 uint temp_pc = info->pc;
1595 LIMIT_CPU_TYPES(info, M68020_PLUS);
1596 build_bxx(info, M68K_INS_BSR, 4, temp_pc + peek_imm_32(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001597}
1598
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001599static void d68000_btst_r(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001600{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001601 build_re_1(info, M68K_INS_BTST, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001602}
1603
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001604static void d68000_btst_s(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001605{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001606 build_imm_ea(info, M68K_INS_BTST, 1, read_imm_8(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001607}
1608
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001609static void d68020_callm(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001610{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001611 LIMIT_CPU_TYPES(info, M68020_ONLY);
1612 build_imm_ea(info, M68K_INS_CALLM, 0, read_imm_8(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001613}
1614
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001615static void d68020_cas_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001616{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001617 LIMIT_CPU_TYPES(info, M68020_PLUS);
1618 build_d_d_ea(info, M68K_INS_CAS, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001619}
1620
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001621static void d68020_cas_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001622{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001623 LIMIT_CPU_TYPES(info, M68020_PLUS);
1624 build_d_d_ea(info, M68K_INS_CAS, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001625}
1626
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001627static void d68020_cas_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001628{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001629 LIMIT_CPU_TYPES(info, M68020_PLUS);
1630 build_d_d_ea(info, M68K_INS_CAS, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001631}
1632
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001633static void d68020_cas2_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001634{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001635 build_cas2(info, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001636}
1637
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001638static void d68020_cas2_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001639{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001640 build_cas2(info, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001641}
1642
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001643static void d68000_chk_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001644{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001645 build_er_1(info, M68K_INS_CHK, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001646}
1647
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001648static void d68020_chk_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001649{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001650 LIMIT_CPU_TYPES(info, M68020_PLUS);
1651 build_er_1(info, M68K_INS_CHK, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001652}
1653
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001654static void d68020_chk2_cmp2_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001655{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001656 LIMIT_CPU_TYPES(info, M68020_PLUS);
1657 build_chk2_cmp2(info, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001658}
1659
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001660static void d68020_chk2_cmp2_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001661{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001662 LIMIT_CPU_TYPES(info, M68020_PLUS);
1663 build_chk2_cmp2(info, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001664}
1665
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001666static void d68020_chk2_cmp2_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001667{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001668 LIMIT_CPU_TYPES(info, M68020_PLUS);
1669 build_chk2_cmp2(info, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001670}
1671
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001672static void d68040_cinv(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001673{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001674 LIMIT_CPU_TYPES(info, M68040_PLUS);
1675 build_cpush_cinv(info, M68K_INS_CINVL);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001676}
1677
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001678static void d68000_clr_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001679{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001680 build_ea(info, M68K_INS_CLR, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001681}
1682
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001683static void d68000_clr_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001684{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001685 build_ea(info, M68K_INS_CLR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001686}
1687
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001688static void d68000_clr_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001689{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001690 build_ea(info, M68K_INS_CLR, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001691}
1692
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001693static void d68000_cmp_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001694{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001695 build_er_1(info, M68K_INS_CMP, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001696}
1697
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001698static void d68000_cmp_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001699{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001700 build_er_1(info, M68K_INS_CMP, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001701}
1702
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001703static void d68000_cmp_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001704{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001705 build_er_1(info, M68K_INS_CMP, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001706}
1707
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001708static void d68000_cmpa_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001709{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001710 build_ea_a(info, M68K_INS_CMPA, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001711}
1712
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001713static void d68000_cmpa_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001714{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001715 build_ea_a(info, M68K_INS_CMPA, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001716}
1717
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001718static void d68000_cmpi_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001719{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001720 build_imm_ea(info, M68K_INS_CMPI, 1, read_imm_8(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001721}
1722
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001723static void d68020_cmpi_pcdi_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001724{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001725 LIMIT_CPU_TYPES(info, M68010_PLUS);
1726 build_imm_ea(info, M68K_INS_CMPI, 1, read_imm_8(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001727}
1728
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001729static void d68020_cmpi_pcix_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001730{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001731 LIMIT_CPU_TYPES(info, M68010_PLUS);
1732 build_imm_ea(info, M68K_INS_CMPI, 1, read_imm_8(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001733}
1734
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001735static void d68000_cmpi_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001736{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001737 build_imm_ea(info, M68K_INS_CMPI, 2, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001738}
1739
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001740static void d68020_cmpi_pcdi_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001741{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001742 LIMIT_CPU_TYPES(info, M68010_PLUS);
1743 build_imm_ea(info, M68K_INS_CMPI, 2, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001744}
1745
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001746static void d68020_cmpi_pcix_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001747{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001748 LIMIT_CPU_TYPES(info, M68010_PLUS);
1749 build_imm_ea(info, M68K_INS_CMPI, 2, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001750}
1751
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001752static void d68000_cmpi_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001753{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001754 build_imm_ea(info, M68K_INS_CMPI, 4, read_imm_32(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001755}
1756
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001757static void d68020_cmpi_pcdi_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001758{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001759 LIMIT_CPU_TYPES(info, M68010_PLUS);
1760 build_imm_ea(info, M68K_INS_CMPI, 4, read_imm_32(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001761}
1762
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001763static void d68020_cmpi_pcix_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001764{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001765 LIMIT_CPU_TYPES(info, M68010_PLUS);
1766 build_imm_ea(info, M68K_INS_CMPI, 4, read_imm_32(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001767}
1768
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001769static void d68000_cmpm_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001770{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001771 build_pi_pi(info, M68K_INS_CMPM, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001772}
1773
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001774static void d68000_cmpm_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001775{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001776 build_pi_pi(info, M68K_INS_CMPM, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001777}
1778
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001779static void d68000_cmpm_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001780{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001781 build_pi_pi(info, M68K_INS_CMPM, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001782}
1783
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001784static void d68020_cpbcc_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001785{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001786 cs_m68k_op* op0;
1787 cs_m68k* ext;
1788 uint new_pc;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001789 LIMIT_CPU_TYPES(info, M68020_PLUS);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001790
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001791 new_pc = info->pc;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001792 new_pc += make_int_16(read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02001793
Daniel Collin2ee675c2015-08-03 18:45:08 +02001794 // these are all in row with the extension so just doing a add here is fine
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001795 info->inst->Opcode += (info->ir & 0x2f);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001796
Nicolas PLANELd529ea02015-10-05 20:19:33 +11001797 ext = build_init_op(info, M68K_INS_FBF, 1, 2);
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001798 op0 = &ext->operands[0];
Daniel Collin2ee675c2015-08-03 18:45:08 +02001799
1800 op0->address_mode = M68K_AM_IMMIDIATE;
1801 op0->type = M68K_OP_IMM;
1802 op0->imm = new_pc;
1803}
1804
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001805static void d68020_cpbcc_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001806{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001807 cs_m68k* ext;
1808 cs_m68k_op* op0;
1809 uint new_pc;
1810
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001811 LIMIT_CPU_TYPES(info, M68020_PLUS);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001812
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001813 LIMIT_CPU_TYPES(info, M68020_PLUS);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001814
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001815 new_pc = info->pc;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001816 new_pc += read_imm_32(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001817
Daniel Collin2ee675c2015-08-03 18:45:08 +02001818 // these are all in row with the extension so just doing a add here is fine
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001819 info->inst->Opcode += (info->ir & 0x2f);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001820
Nicolas PLANELd529ea02015-10-05 20:19:33 +11001821 ext = build_init_op(info, M68K_INS_FBF, 1, 4);
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001822 op0 = &ext->operands[0];
Daniel Collin2ee675c2015-08-03 18:45:08 +02001823
1824 op0->type = M68K_OP_IMM;
1825 op0->address_mode = M68K_AM_IMMIDIATE;
1826 op0->imm = new_pc;
1827}
1828
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001829static void d68020_cpdbcc(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001830{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001831 cs_m68k* ext;
1832 cs_m68k_op* op0;
1833 cs_m68k_op* op1;
1834 uint new_pc, ext1, ext2;
1835
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001836 LIMIT_CPU_TYPES(info, M68020_PLUS);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001837
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001838 new_pc = info->pc;
1839 ext1 = read_imm_16(info);
1840 ext2 = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001841 new_pc += make_int_16(ext2) + 2;
1842
Daniel Collin2ee675c2015-08-03 18:45:08 +02001843
1844 // these are all in row with the extension so just doing a add here is fine
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001845 info->inst->Opcode += (ext1 & 0x2f);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001846
Nicolas PLANELd529ea02015-10-05 20:19:33 +11001847 ext = build_init_op(info, M68K_INS_FDBF, 2, 0);
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001848 op0 = &ext->operands[0];
1849 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02001850
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001851 op0->reg = M68K_REG_D0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001852
1853 op1->address_mode = M68K_AM_IMMIDIATE;
1854 op1->type = M68K_OP_IMM;
1855 op1->imm = new_pc;
1856}
1857
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001858static void fmove_fpcr(m68k_info *info, uint extension)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001859{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001860 cs_m68k_op* special;
1861 cs_m68k_op* op_ea;
1862
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001863 int regsel = (extension >> 10) & 0x7;
1864 int dir = (extension >> 13) & 0x1;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001865
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001866 cs_m68k* ext = build_init_op(info, M68K_INS_FMOVE, 2, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001867
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001868 special = &ext->operands[0];
1869 op_ea = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02001870
1871 if (!dir) {
1872 cs_m68k_op* t = special;
1873 special = op_ea;
1874 op_ea = t;
1875 }
1876
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001877 get_ea_mode_op(info, op_ea, info->ir, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001878
Daniel Collin988bb632016-04-10 10:55:21 +02001879 if (regsel & 4)
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001880 special->reg = M68K_REG_FPCR;
Daniel Collin988bb632016-04-10 10:55:21 +02001881 else if (regsel & 2)
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001882 special->reg = M68K_REG_FPSR;
Daniel Collin988bb632016-04-10 10:55:21 +02001883 else if (regsel & 1)
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001884 special->reg = M68K_REG_FPIAR;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001885}
1886
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001887static void fmovem(m68k_info *info, uint extension)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001888{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001889 cs_m68k_op* op_reglist;
1890 cs_m68k_op* op_ea;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001891 int dir = (extension >> 13) & 0x1;
1892 int mode = (extension >> 11) & 0x3;
1893 uint reglist = extension & 0xff;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001894 cs_m68k* ext = build_init_op(info, M68K_INS_FMOVEM, 2, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001895
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001896 op_reglist = &ext->operands[0];
1897 op_ea = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02001898
1899 // flip args around
1900
1901 if (!dir) {
1902 cs_m68k_op* t = op_reglist;
1903 op_reglist = op_ea;
1904 op_ea = t;
1905 }
1906
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001907 get_ea_mode_op(info, op_ea, info->ir, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001908
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08001909 switch (mode) {
Daniel Collin2ee675c2015-08-03 18:45:08 +02001910 case 1 : // Dynamic list in dn register
Daniel Collin2ee675c2015-08-03 18:45:08 +02001911 op_reglist->reg = M68K_REG_D0 + ((reglist >> 4) & 7);
1912 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001913
Daniel Collin988bb632016-04-10 10:55:21 +02001914 case 0 :
Daniel Collin2ee675c2015-08-03 18:45:08 +02001915 op_reglist->address_mode = M68K_AM_NONE;
1916 op_reglist->type = M68K_OP_REG_BITS;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001917 op_reglist->register_bits = reglist << 16;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001918 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001919
1920 case 2 : // Static list
Daniel Collin2ee675c2015-08-03 18:45:08 +02001921 op_reglist->address_mode = M68K_AM_NONE;
1922 op_reglist->type = M68K_OP_REG_BITS;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001923 op_reglist->register_bits = ((uint32_t)reverse_bits_8(reglist)) << 16;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001924 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001925 }
1926}
1927
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001928static void d68020_cpgen(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02001929{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001930 cs_m68k *ext;
1931 cs_m68k_op* op0;
1932 cs_m68k_op* op1;
1933 bool supports_single_op;
1934 uint next;
1935 int rm, src, dst, opmode;
1936
1937
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001938 LIMIT_CPU_TYPES(info, M68020_PLUS);
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08001939
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001940 supports_single_op = true;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001941
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001942 next = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001943
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001944 rm = (next >> 14) & 0x1;
1945 src = (next >> 10) & 0x7;
1946 dst = (next >> 7) & 0x7;
1947 opmode = next & 0x3f;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001948
1949 // special handling for fmovecr
1950
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001951 if (BITFIELD(info->ir, 5, 0) == 0 && BITFIELD(next, 15, 10) == 0x17) {
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001952 cs_m68k_op* op0;
1953 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001954 cs_m68k* ext = build_init_op(info, M68K_INS_FMOVECR, 2, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001955
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001956 op0 = &ext->operands[0];
1957 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02001958
1959 op0->address_mode = M68K_AM_IMMIDIATE;
1960 op0->type = M68K_OP_IMM;
1961 op0->imm = next & 0x3f;
1962
1963 op1->reg = M68K_REG_FP0 + ((next >> 7) & 7);
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001964
Daniel Collin2ee675c2015-08-03 18:45:08 +02001965 return;
1966 }
1967
1968 // deal with extended move stuff
1969
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08001970 switch ((next >> 13) & 0x7) {
Daniel Collin2ee675c2015-08-03 18:45:08 +02001971 // fmovem fpcr
Daniel Collin2ee675c2015-08-03 18:45:08 +02001972 case 0x4: // FMOVEM ea, FPCR
1973 case 0x5: // FMOVEM FPCR, ea
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001974 fmove_fpcr(info, next);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001975 return;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001976
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001977 // fmovem list
Daniel Collin2ee675c2015-08-03 18:45:08 +02001978 case 0x6:
1979 case 0x7:
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001980 fmovem(info, next);
Daniel Collin2ee675c2015-08-03 18:45:08 +02001981 return;
Daniel Collin2ee675c2015-08-03 18:45:08 +02001982 }
1983
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08001984 // See comment bellow on why this is being done
Daniel Collin2ee675c2015-08-03 18:45:08 +02001985
1986 if ((next >> 6) & 1)
1987 opmode &= ~4;
1988
1989 // special handling of some instructions here
Daniel Collin2ee675c2015-08-03 18:45:08 +02001990
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08001991 switch (opmode) {
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11001992 case 0x00: MCInst_setOpcode(info->inst, M68K_INS_FMOVE); supports_single_op = false; break;
1993 case 0x01: MCInst_setOpcode(info->inst, M68K_INS_FINT); break;
1994 case 0x02: MCInst_setOpcode(info->inst, M68K_INS_FSINH); break;
1995 case 0x03: MCInst_setOpcode(info->inst, M68K_INS_FINTRZ); break;
1996 case 0x04: MCInst_setOpcode(info->inst, M68K_INS_FSQRT); break;
1997 case 0x06: MCInst_setOpcode(info->inst, M68K_INS_FLOGNP1); break;
1998 case 0x08: MCInst_setOpcode(info->inst, M68K_INS_FETOXM1); break;
1999 case 0x09: MCInst_setOpcode(info->inst, M68K_INS_FATANH); break;
2000 case 0x0a: MCInst_setOpcode(info->inst, M68K_INS_FATAN); break;
2001 case 0x0c: MCInst_setOpcode(info->inst, M68K_INS_FASIN); break;
2002 case 0x0d: MCInst_setOpcode(info->inst, M68K_INS_FATANH); break;
2003 case 0x0e: MCInst_setOpcode(info->inst, M68K_INS_FSIN); break;
2004 case 0x0f: MCInst_setOpcode(info->inst, M68K_INS_FTAN); break;
2005 case 0x10: MCInst_setOpcode(info->inst, M68K_INS_FETOX); break;
2006 case 0x11: MCInst_setOpcode(info->inst, M68K_INS_FTWOTOX); break;
2007 case 0x12: MCInst_setOpcode(info->inst, M68K_INS_FTENTOX); break;
2008 case 0x14: MCInst_setOpcode(info->inst, M68K_INS_FLOGN); break;
2009 case 0x15: MCInst_setOpcode(info->inst, M68K_INS_FLOG10); break;
2010 case 0x16: MCInst_setOpcode(info->inst, M68K_INS_FLOG2); break;
2011 case 0x18: MCInst_setOpcode(info->inst, M68K_INS_FABS); break;
2012 case 0x19: MCInst_setOpcode(info->inst, M68K_INS_FCOSH); break;
2013 case 0x1a: MCInst_setOpcode(info->inst, M68K_INS_FNEG); break;
2014 case 0x1c: MCInst_setOpcode(info->inst, M68K_INS_FACOS); break;
2015 case 0x1d: MCInst_setOpcode(info->inst, M68K_INS_FCOS); break;
2016 case 0x1e: MCInst_setOpcode(info->inst, M68K_INS_FGETEXP); break;
2017 case 0x1f: MCInst_setOpcode(info->inst, M68K_INS_FGETMAN); break;
2018 case 0x20: MCInst_setOpcode(info->inst, M68K_INS_FDIV); supports_single_op = false; break;
2019 case 0x21: MCInst_setOpcode(info->inst, M68K_INS_FMOD); supports_single_op = false; break;
2020 case 0x22: MCInst_setOpcode(info->inst, M68K_INS_FADD); supports_single_op = false; break;
2021 case 0x23: MCInst_setOpcode(info->inst, M68K_INS_FMUL); supports_single_op = false; break;
2022 case 0x24: MCInst_setOpcode(info->inst, M68K_INS_FSGLDIV); supports_single_op = false; break;
2023 case 0x25: MCInst_setOpcode(info->inst, M68K_INS_FREM); break;
2024 case 0x26: MCInst_setOpcode(info->inst, M68K_INS_FSCALE); break;
2025 case 0x27: MCInst_setOpcode(info->inst, M68K_INS_FSGLMUL); break;
2026 case 0x28: MCInst_setOpcode(info->inst, M68K_INS_FSUB); supports_single_op = false; break;
2027 case 0x38: MCInst_setOpcode(info->inst, M68K_INS_FCMP); supports_single_op = false; break;
2028 case 0x3a: MCInst_setOpcode(info->inst, M68K_INS_FTST); break;
Daniel Collin988bb632016-04-10 10:55:21 +02002029 default:
Daniel Collin1bca0542016-04-10 16:16:28 +02002030 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002031 }
2032
2033 // Some trickery here! It's not documented but if bit 6 is set this is a s/d opcode and then
2034 // if bit 2 is set it's a d. As we already have set our opcode in the code above we can just
2035 // offset it as the following 2 op codes (if s/d is supported) will always be directly after it
2036
2037 if ((next >> 6) & 1) {
2038 if ((next >> 2) & 1)
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002039 info->inst->Opcode += 2;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002040 else
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002041 info->inst->Opcode += 1;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002042 }
2043
Nicolas PLANELd529ea02015-10-05 20:19:33 +11002044 ext = &info->extension;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002045
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002046 ext->op_count = 2;
2047 ext->op_size.type = M68K_SIZE_TYPE_CPU;
2048 ext->op_size.cpu_size = 0;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002049
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002050 op0 = &ext->operands[0];
2051 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002052
2053 if (rm == 0 && supports_single_op && src == dst) {
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002054 ext->op_count = 1;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002055 op0->reg = M68K_REG_FP0 + dst;
2056 return;
2057 }
2058
2059 if (rm == 1) {
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08002060 switch (src) {
Daniel Collin988bb632016-04-10 10:55:21 +02002061 case 0x00 :
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002062 ext->op_size.cpu_size = M68K_CPU_SIZE_LONG;
2063 get_ea_mode_op(info, op0, info->ir, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002064 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002065
Daniel Collin988bb632016-04-10 10:55:21 +02002066 case 0x06 :
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002067 ext->op_size.cpu_size = M68K_CPU_SIZE_BYTE;
2068 get_ea_mode_op(info, op0, info->ir, 1);
2069 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002070
Daniel Collin988bb632016-04-10 10:55:21 +02002071 case 0x04 :
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002072 ext->op_size.cpu_size = M68K_CPU_SIZE_WORD;
2073 get_ea_mode_op(info, op0, info->ir, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002074 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002075
Daniel Collin988bb632016-04-10 10:55:21 +02002076 case 0x01 :
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002077 ext->op_size.type = M68K_SIZE_TYPE_FPU;
2078 ext->op_size.fpu_size = M68K_FPU_SIZE_SINGLE;
2079 get_ea_mode_op(info, op0, info->ir, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002080 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002081
2082 case 0x05:
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002083 ext->op_size.type = M68K_SIZE_TYPE_FPU;
2084 ext->op_size.fpu_size = M68K_FPU_SIZE_DOUBLE;
2085 get_ea_mode_op(info, op0, info->ir, 8);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002086 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002087
2088 default :
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002089 ext->op_size.type = M68K_SIZE_TYPE_FPU;
2090 ext->op_size.fpu_size = M68K_FPU_SIZE_EXTENDED;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002091 break;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002092 }
2093 } else {
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002094 op0->reg = M68K_REG_FP0 + src;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002095 }
2096
2097 op1->reg = M68K_REG_FP0 + dst;
2098}
2099
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002100static void d68020_cprestore(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002101{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002102 cs_m68k* ext;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002103 LIMIT_CPU_TYPES(info, M68020_PLUS);
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002104
2105 ext = build_init_op(info, M68K_INS_FRESTORE, 1, 0);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002106 get_ea_mode_op(info, &ext->operands[0], info->ir, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002107}
2108
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002109static void d68020_cpsave(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002110{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002111 cs_m68k* ext;
2112
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002113 LIMIT_CPU_TYPES(info, M68020_PLUS);
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002114
2115 ext = build_init_op(info, M68K_INS_FSAVE, 1, 0);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002116 get_ea_mode_op(info, &ext->operands[0], info->ir, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002117}
2118
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002119static void d68020_cpscc(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002120{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002121 cs_m68k* ext;
2122
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002123 LIMIT_CPU_TYPES(info, M68020_PLUS);
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002124 ext = build_init_op(info, M68K_INS_FSF, 1, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002125
2126 // these are all in row with the extension so just doing a add here is fine
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002127 info->inst->Opcode += (read_imm_16(info) & 0x2f);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002128
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002129 get_ea_mode_op(info, &ext->operands[0], info->ir, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002130}
2131
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002132static void d68020_cptrapcc_0(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002133{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002134 uint extension1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002135 LIMIT_CPU_TYPES(info, M68020_PLUS);
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002136
2137 extension1 = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002138
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002139 build_init_op(info, M68K_INS_FTRAPF, 0, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002140
2141 // these are all in row with the extension so just doing a add here is fine
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002142 info->inst->Opcode += (extension1 & 0x2f);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002143}
2144
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002145static void d68020_cptrapcc_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002146{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002147 uint extension1, extension2;
2148 cs_m68k_op* op0;
2149 cs_m68k* ext;
2150
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002151 LIMIT_CPU_TYPES(info, M68020_PLUS);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002152
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002153 extension1 = read_imm_16(info);
2154 extension2 = read_imm_16(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002155
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002156 ext = build_init_op(info, M68K_INS_FTRAPF, 1, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002157
2158 // these are all in row with the extension so just doing a add here is fine
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002159 info->inst->Opcode += (extension1 & 0x2f);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002160
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002161 op0 = &ext->operands[0];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002162
2163 op0->address_mode = M68K_AM_IMMIDIATE;
2164 op0->type = M68K_OP_IMM;
2165 op0->imm = extension2;
2166}
2167
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002168static void d68020_cptrapcc_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002169{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002170 uint extension1, extension2;
2171 cs_m68k* ext;
2172 cs_m68k_op* op0;
2173
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002174 LIMIT_CPU_TYPES(info, M68020_PLUS);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002175
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002176 extension1 = read_imm_16(info);
2177 extension2 = read_imm_32(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002178
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002179 ext = build_init_op(info, M68K_INS_FTRAPF, 1, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002180
2181 // these are all in row with the extension so just doing a add here is fine
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002182 info->inst->Opcode += (extension1 & 0x2f);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002183
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002184 op0 = &ext->operands[0];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002185
2186 op0->address_mode = M68K_AM_IMMIDIATE;
2187 op0->type = M68K_OP_IMM;
2188 op0->imm = extension2;
2189}
2190
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002191static void d68040_cpush(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002192{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002193 LIMIT_CPU_TYPES(info, M68040_PLUS);
2194 build_cpush_cinv(info, M68K_INS_CPUSHL);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002195}
2196
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002197static void d68000_dbra(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002198{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002199 uint temp_pc = info->pc;
2200 build_dbxx(info, M68K_INS_DBRA, 0, temp_pc + make_int_16(read_imm_16(info)));
Daniel Collin2ee675c2015-08-03 18:45:08 +02002201}
2202
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002203static void d68000_dbcc(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002204{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002205 uint temp_pc = info->pc;
2206 build_dbcc(info, 0, temp_pc + make_int_16(read_imm_16(info)));
Daniel Collin2ee675c2015-08-03 18:45:08 +02002207}
2208
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002209static void d68000_divs(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002210{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002211 build_er_1(info, M68K_INS_DIVS, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002212}
2213
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002214static void d68000_divu(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002215{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002216 build_er_1(info, M68K_INS_DIVU, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002217}
2218
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002219static void d68020_divl(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002220{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002221 uint extension, insn_signed;
2222 cs_m68k* ext;
2223 cs_m68k_op* op0;
2224 cs_m68k_op* op1;
2225 uint reg_0, reg_1;
2226
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002227 LIMIT_CPU_TYPES(info, M68020_PLUS);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002228
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002229 extension = read_imm_16(info);
2230 insn_signed = 0;
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08002231
Daniel Collin2ee675c2015-08-03 18:45:08 +02002232 if (BIT_B((extension)))
2233 insn_signed = 1;
2234
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002235 ext = build_init_op(info, insn_signed ? M68K_INS_DIVS : M68K_INS_DIVU, 2, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002236
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002237 op0 = &ext->operands[0];
2238 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002239
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002240 get_ea_mode_op(info, op0, info->ir, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002241
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002242 reg_0 = extension & 7;
2243 reg_1 = (extension >> 12) & 7;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002244
2245 op1->address_mode = M68K_AM_NONE;
2246 op1->type = M68K_OP_REG_PAIR;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002247 op1->register_bits = (reg_0 << 4) | reg_1;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002248
2249 if ((reg_0 == reg_1) || !BIT_A(extension)) {
2250 op1->type = M68K_OP_REG;
2251 op1->reg = M68K_REG_D0 + reg_1;
2252 }
2253}
2254
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002255static void d68000_eor_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002256{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002257 build_re_1(info, M68K_INS_EOR, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002258}
2259
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002260static void d68000_eor_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002261{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002262 build_re_1(info, M68K_INS_EOR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002263}
2264
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002265static void d68000_eor_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002266{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002267 build_re_1(info, M68K_INS_EOR, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002268}
2269
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002270static void d68000_eori_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002271{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002272 build_imm_ea(info, M68K_INS_EORI, 1, read_imm_8(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02002273}
2274
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002275static void d68000_eori_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002276{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002277 build_imm_ea(info, M68K_INS_EORI, 2, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02002278}
2279
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002280static void d68000_eori_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002281{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002282 build_imm_ea(info, M68K_INS_EORI, 4, read_imm_32(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02002283}
2284
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002285static void d68000_eori_to_ccr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002286{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002287 build_imm_special_reg(info, M68K_INS_EORI, read_imm_8(info), 1, M68K_REG_CCR);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002288}
2289
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002290static void d68000_eori_to_sr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002291{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002292 build_imm_special_reg(info, M68K_INS_EORI, read_imm_16(info), 2, M68K_REG_SR);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002293}
2294
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002295static void d68000_exg_dd(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002296{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002297 build_r(info, M68K_INS_EXG, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002298}
2299
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002300static void d68000_exg_aa(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002301{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002302 cs_m68k_op* op0;
2303 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002304 cs_m68k* ext = build_init_op(info, M68K_INS_EXG, 2, 4);
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002305
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002306 op0 = &ext->operands[0];
2307 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002308
2309 op0->address_mode = M68K_AM_NONE;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002310 op0->reg = M68K_REG_A0 + ((info->ir >> 9) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002311
2312 op1->address_mode = M68K_AM_NONE;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002313 op1->reg = M68K_REG_A0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002314}
2315
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002316static void d68000_exg_da(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002317{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002318 cs_m68k_op* op0;
2319 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002320 cs_m68k* ext = build_init_op(info, M68K_INS_EXG, 2, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002321
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002322 op0 = &ext->operands[0];
2323 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002324
2325 op0->address_mode = M68K_AM_NONE;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002326 op0->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002327
2328 op1->address_mode = M68K_AM_NONE;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002329 op1->reg = M68K_REG_A0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002330}
2331
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002332static void d68000_ext_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002333{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002334 build_d(info, M68K_INS_EXT, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002335}
2336
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002337static void d68000_ext_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002338{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002339 build_d(info, M68K_INS_EXT, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002340}
2341
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002342static void d68020_extb_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002343{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002344 LIMIT_CPU_TYPES(info, M68020_PLUS);
2345 build_d(info, M68K_INS_EXTB, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002346}
2347
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002348static void d68000_jmp(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002349{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002350 cs_m68k* ext = build_init_op(info, M68K_INS_JMP, 1, 0);
Daniel Collin1bca0542016-04-10 16:16:28 +02002351 set_insn_group(info, M68K_GRP_JUMP);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002352 get_ea_mode_op(info, &ext->operands[0], info->ir, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002353}
2354
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002355static void d68000_jsr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002356{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002357 cs_m68k* ext = build_init_op(info, M68K_INS_JSR, 1, 0);
Daniel Collin1bca0542016-04-10 16:16:28 +02002358 set_insn_group(info, M68K_GRP_JUMP);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002359 get_ea_mode_op(info, &ext->operands[0], info->ir, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002360}
2361
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002362static void d68000_lea(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002363{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002364 build_ea_a(info, M68K_INS_LEA, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002365}
2366
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002367static void d68000_link_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002368{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002369 build_link(info, read_imm_16(info), 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002370}
2371
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002372static void d68020_link_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002373{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002374 LIMIT_CPU_TYPES(info, M68020_PLUS);
2375 build_link(info, read_imm_32(info), 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002376}
2377
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002378static void d68000_lsr_s_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002379{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002380 build_3bit_d(info, M68K_INS_LSR, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002381}
2382
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002383static void d68000_lsr_s_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002384{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002385 build_3bit_d(info, M68K_INS_LSR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002386}
2387
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002388static void d68000_lsr_s_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002389{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002390 build_3bit_d(info, M68K_INS_LSR, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002391}
2392
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002393static void d68000_lsr_r_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002394{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002395 build_r(info, M68K_INS_LSR, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002396}
2397
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002398static void d68000_lsr_r_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002399{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002400 build_r(info, M68K_INS_LSR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002401}
2402
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002403static void d68000_lsr_r_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002404{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002405 build_r(info, M68K_INS_LSR, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002406}
2407
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002408static void d68000_lsr_ea(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002409{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002410 build_ea(info, M68K_INS_LSR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002411}
2412
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002413static void d68000_lsl_s_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002414{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002415 build_3bit_d(info, M68K_INS_LSL, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002416}
2417
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002418static void d68000_lsl_s_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002419{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002420 build_3bit_d(info, M68K_INS_LSL, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002421}
2422
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002423static void d68000_lsl_s_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002424{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002425 build_3bit_d(info, M68K_INS_LSL, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002426}
2427
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002428static void d68000_lsl_r_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002429{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002430 build_r(info, M68K_INS_LSL, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002431}
2432
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002433static void d68000_lsl_r_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002434{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002435 build_r(info, M68K_INS_LSL, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002436}
2437
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002438static void d68000_lsl_r_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002439{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002440 build_r(info, M68K_INS_LSL, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002441}
2442
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002443static void d68000_lsl_ea(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002444{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002445 build_ea(info, M68K_INS_LSL, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002446}
2447
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002448static void d68000_move_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002449{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002450 build_ea_ea(info, M68K_INS_MOVE, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002451}
2452
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002453static void d68000_move_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002454{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002455 build_ea_ea(info, M68K_INS_MOVE, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002456}
2457
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002458static void d68000_move_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002459{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002460 build_ea_ea(info, M68K_INS_MOVE, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002461}
2462
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002463static void d68000_movea_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002464{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002465 build_ea_a(info, M68K_INS_MOVEA, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002466}
2467
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002468static void d68000_movea_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002469{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002470 build_ea_a(info, M68K_INS_MOVEA, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002471}
2472
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002473static void d68000_move_to_ccr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002474{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002475 cs_m68k_op* op0;
2476 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002477 cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002478
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002479 op0 = &ext->operands[0];
2480 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002481
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002482 get_ea_mode_op(info, op0, info->ir, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002483
2484 op1->address_mode = M68K_AM_NONE;
2485 op1->reg = M68K_REG_CCR;
2486}
2487
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002488static void d68010_move_fr_ccr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002489{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002490 cs_m68k_op* op0;
2491 cs_m68k_op* op1;
2492 cs_m68k* ext;
2493
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002494 LIMIT_CPU_TYPES(info, M68010_PLUS);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002495
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002496 ext = build_init_op(info, M68K_INS_MOVE, 2, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002497
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002498 op0 = &ext->operands[0];
2499 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002500
2501 op0->address_mode = M68K_AM_NONE;
2502 op0->reg = M68K_REG_CCR;
2503
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002504 get_ea_mode_op(info, op1, info->ir, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002505}
2506
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002507static void d68000_move_fr_sr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002508{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002509 cs_m68k_op* op0;
2510 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002511 cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002512
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002513 op0 = &ext->operands[0];
2514 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002515
2516 op0->address_mode = M68K_AM_NONE;
2517 op0->reg = M68K_REG_SR;
2518
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002519 get_ea_mode_op(info, op1, info->ir, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002520}
2521
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002522static void d68000_move_to_sr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002523{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002524 cs_m68k_op* op0;
2525 cs_m68k_op* op1;
2526 cs_m68k* ext;
2527
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002528 LIMIT_CPU_TYPES(info, M68010_PLUS);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002529
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002530 ext = build_init_op(info, M68K_INS_MOVE, 2, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002531
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002532 op0 = &ext->operands[0];
2533 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002534
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002535 get_ea_mode_op(info, op0, info->ir, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002536
2537 op1->address_mode = M68K_AM_NONE;
2538 op1->reg = M68K_REG_SR;
2539}
2540
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002541static void d68000_move_fr_usp(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002542{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002543 cs_m68k_op* op0;
2544 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002545 cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002546
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002547 op0 = &ext->operands[0];
2548 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002549
2550 op0->address_mode = M68K_AM_NONE;
2551 op0->reg = M68K_REG_USP;
2552
2553 op1->address_mode = M68K_AM_NONE;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002554 op1->reg = M68K_REG_A0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002555}
2556
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002557static void d68000_move_to_usp(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002558{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002559 cs_m68k_op* op0;
2560 cs_m68k_op* op1;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002561 cs_m68k* ext = build_init_op(info, M68K_INS_MOVE, 2, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002562
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002563 op0 = &ext->operands[0];
2564 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002565
2566 op0->address_mode = M68K_AM_NONE;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002567 op0->reg = M68K_REG_A0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002568
2569 op1->address_mode = M68K_AM_NONE;
2570 op1->reg = M68K_REG_USP;
2571}
2572
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002573static void d68010_movec(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002574{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002575 uint extension;
2576 m68k_reg reg;
2577 cs_m68k* ext;
2578 cs_m68k_op* op0;
2579 cs_m68k_op* op1;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002580
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002581
2582 LIMIT_CPU_TYPES(info, M68010_PLUS);
2583
2584 extension = read_imm_16(info);
2585 reg = M68K_REG_INVALID;
2586
2587 ext = build_init_op(info, M68K_INS_MOVEC, 2, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002588
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002589 op0 = &ext->operands[0];
2590 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002591
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08002592 switch (extension & 0xfff) {
Daniel Collin2ee675c2015-08-03 18:45:08 +02002593 case 0x000: reg = M68K_REG_SFC; break;
2594 case 0x001: reg = M68K_REG_DFC; break;
2595 case 0x800: reg = M68K_REG_USP; break;
2596 case 0x801: reg = M68K_REG_VBR; break;
2597 case 0x002: reg = M68K_REG_CACR; break;
2598 case 0x802: reg = M68K_REG_CAAR; break;
2599 case 0x803: reg = M68K_REG_MSP; break;
2600 case 0x804: reg = M68K_REG_ISP; break;
2601 case 0x003: reg = M68K_REG_TC; break;
2602 case 0x004: reg = M68K_REG_ITT0; break;
2603 case 0x005: reg = M68K_REG_ITT1; break;
2604 case 0x006: reg = M68K_REG_DTT0; break;
2605 case 0x007: reg = M68K_REG_DTT1; break;
2606 case 0x805: reg = M68K_REG_MMUSR; break;
2607 case 0x806: reg = M68K_REG_URP; break;
2608 case 0x807: reg = M68K_REG_SRP; break;
2609 }
2610
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002611 if (BIT_1(info->ir)) {
Daniel Collin2ee675c2015-08-03 18:45:08 +02002612 op0->reg = (BIT_F(extension) ? M68K_REG_A0 : M68K_REG_D0) + ((extension >> 12) & 7);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002613 op1->reg = reg;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002614 } else {
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002615 op0->reg = reg;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002616 op1->reg = (BIT_F(extension) ? M68K_REG_A0 : M68K_REG_D0) + ((extension >> 12) & 7);
2617 }
2618}
2619
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002620static void d68000_movem_pd_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002621{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002622 build_movem_re(info, M68K_INS_MOVEM, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002623}
2624
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002625static void d68000_movem_pd_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002626{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002627 build_movem_re(info, M68K_INS_MOVEM, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002628}
2629
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002630static void d68000_movem_er_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002631{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002632 build_movem_er(info, M68K_INS_MOVEM, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002633}
2634
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002635static void d68000_movem_er_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002636{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002637 build_movem_er(info, M68K_INS_MOVEM, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002638}
2639
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002640static void d68000_movem_re_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002641{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002642 build_movem_re(info, M68K_INS_MOVEM, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002643}
2644
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002645static void d68000_movem_re_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002646{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002647 build_movem_re(info, M68K_INS_MOVEM, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002648}
2649
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002650static void d68000_movep_re_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002651{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002652 build_movep_re(info, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002653}
2654
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002655static void d68000_movep_re_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002656{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002657 build_movep_re(info, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002658}
2659
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002660static void d68000_movep_er_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002661{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002662 build_movep_er(info, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002663}
2664
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002665static void d68000_movep_er_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002666{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002667 build_movep_er(info, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002668}
2669
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002670static void d68010_moves_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002671{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002672 LIMIT_CPU_TYPES(info, M68010_PLUS);
2673 build_moves(info, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002674}
2675
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002676static void d68010_moves_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002677{
2678 //uint extension;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002679 LIMIT_CPU_TYPES(info, M68010_PLUS);
2680 build_moves(info, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002681}
2682
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002683static void d68010_moves_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002684{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002685 LIMIT_CPU_TYPES(info, M68010_PLUS);
2686 build_moves(info, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002687}
2688
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002689static void d68000_moveq(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002690{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002691 cs_m68k_op* op0;
2692 cs_m68k_op* op1;
2693
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002694 cs_m68k* ext = build_init_op(info, M68K_INS_MOVEQ, 2, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002695
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002696 op0 = &ext->operands[0];
2697 op1 = &ext->operands[1];
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08002698
Daniel Collin2ee675c2015-08-03 18:45:08 +02002699 op0->type = M68K_OP_IMM;
2700 op0->address_mode = M68K_AM_IMMIDIATE;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002701 op0->imm = (info->ir & 0xff);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002702
2703 op1->address_mode = M68K_AM_REG_DIRECT_DATA;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002704 op1->reg = M68K_REG_D0 + ((info->ir >> 9) & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002705}
2706
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002707static void d68040_move16_pi_pi(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002708{
Daniel Collin25d2ea62015-10-05 16:31:06 +02002709 int data[] = { info->ir & 7, (read_imm_16(info) >> 12) & 7 };
Daniel Collin2ee675c2015-08-03 18:45:08 +02002710 int modes[] = { M68K_AM_REGI_ADDR_POST_INC, M68K_AM_REGI_ADDR_POST_INC };
2711
Daniel Collin25d2ea62015-10-05 16:31:06 +02002712 LIMIT_CPU_TYPES(info, M68040_PLUS);
2713
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002714 build_move16(info, data, modes);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002715}
2716
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002717static void d68040_move16_pi_al(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002718{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002719 int data[] = { info->ir & 7, read_imm_32(info) };
Daniel Collin2ee675c2015-08-03 18:45:08 +02002720 int modes[] = { M68K_AM_REGI_ADDR_POST_INC, M68K_AM_ABSOLUTE_DATA_LONG };
2721
Daniel Collin25d2ea62015-10-05 16:31:06 +02002722 LIMIT_CPU_TYPES(info, M68040_PLUS);
2723
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002724 build_move16(info, data, modes);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002725}
2726
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002727static void d68040_move16_al_pi(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002728{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002729 int data[] = { read_imm_32(info), info->ir & 7 };
Daniel Collin2ee675c2015-08-03 18:45:08 +02002730 int modes[] = { M68K_AM_ABSOLUTE_DATA_LONG, M68K_AM_REGI_ADDR_POST_INC };
2731
Daniel Collin25d2ea62015-10-05 16:31:06 +02002732 LIMIT_CPU_TYPES(info, M68040_PLUS);
2733
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002734 build_move16(info, data, modes);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002735}
2736
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002737static void d68040_move16_ai_al(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002738{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002739 int data[] = { info->ir & 7, read_imm_32(info) };
Daniel Collin2ee675c2015-08-03 18:45:08 +02002740 int modes[] = { M68K_AM_REG_DIRECT_ADDR, M68K_AM_ABSOLUTE_DATA_LONG };
2741
Daniel Collin25d2ea62015-10-05 16:31:06 +02002742 LIMIT_CPU_TYPES(info, M68040_PLUS);
2743
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002744 build_move16(info, data, modes);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002745}
2746
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002747static void d68040_move16_al_ai(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002748{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002749 int data[] = { read_imm_32(info), info->ir & 7 };
Daniel Collin2ee675c2015-08-03 18:45:08 +02002750 int modes[] = { M68K_AM_ABSOLUTE_DATA_LONG, M68K_AM_REG_DIRECT_ADDR };
2751
Daniel Collin25d2ea62015-10-05 16:31:06 +02002752 LIMIT_CPU_TYPES(info, M68040_PLUS);
2753
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002754 build_move16(info, data, modes);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002755}
2756
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002757static void d68000_muls(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002758{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002759 build_er_1(info, M68K_INS_MULS, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002760}
2761
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002762static void d68000_mulu(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002763{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002764 build_er_1(info, M68K_INS_MULU, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002765}
2766
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002767static void d68020_mull(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002768{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002769 uint extension, insn_signed;
2770 cs_m68k* ext;
2771 cs_m68k_op* op0;
2772 cs_m68k_op* op1;
2773 uint reg_0, reg_1;
2774
2775
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002776 LIMIT_CPU_TYPES(info, M68020_PLUS);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002777
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002778 extension = read_imm_16(info);
2779 insn_signed = 0;
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08002780
Daniel Collin2ee675c2015-08-03 18:45:08 +02002781 if (BIT_B((extension)))
2782 insn_signed = 1;
2783
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002784 ext = build_init_op(info, insn_signed ? M68K_INS_MULS : M68K_INS_MULU, 2, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002785
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002786 op0 = &ext->operands[0];
2787 op1 = &ext->operands[1];
Daniel Collin2ee675c2015-08-03 18:45:08 +02002788
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002789 get_ea_mode_op(info, op0, info->ir, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002790
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08002791 reg_0 = extension & 7;
2792 reg_1 = (extension >> 12) & 7;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002793
2794 op1->address_mode = M68K_AM_NONE;
2795 op1->type = M68K_OP_REG_PAIR;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002796 op1->register_bits = (reg_0 << 4) | reg_1;
Daniel Collin2ee675c2015-08-03 18:45:08 +02002797
2798 if (!BIT_A(extension)) {
2799 op1->type = M68K_OP_REG;
2800 op1->reg = M68K_REG_D0 + reg_1;
2801 }
2802}
2803
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002804static void d68000_nbcd(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002805{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002806 build_ea(info, M68K_INS_NBCD, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002807}
2808
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002809static void d68000_neg_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002810{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002811 build_ea(info, M68K_INS_NEG, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002812}
2813
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002814static void d68000_neg_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002815{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002816 build_ea(info, M68K_INS_NEG, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002817}
2818
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002819static void d68000_neg_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002820{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002821 build_ea(info, M68K_INS_NEG, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002822}
2823
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002824static void d68000_negx_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002825{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002826 build_ea(info, M68K_INS_NEGX, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002827}
2828
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002829static void d68000_negx_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002830{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002831 build_ea(info, M68K_INS_NEGX, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002832}
2833
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002834static void d68000_negx_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002835{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002836 build_ea(info, M68K_INS_NEGX, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002837}
2838
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002839static void d68000_nop(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002840{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002841 MCInst_setOpcode(info->inst, M68K_INS_NOP);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002842}
2843
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002844static void d68000_not_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002845{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002846 build_ea(info, M68K_INS_NOT, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002847}
2848
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002849static void d68000_not_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002850{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002851 build_ea(info, M68K_INS_NOT, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002852}
2853
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002854static void d68000_not_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002855{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002856 build_ea(info, M68K_INS_NOT, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002857}
2858
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002859static void d68000_or_er_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002860{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002861 build_er_1(info, M68K_INS_OR, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002862}
2863
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002864static void d68000_or_er_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002865{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002866 build_er_1(info, M68K_INS_OR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002867}
2868
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002869static void d68000_or_er_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002870{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002871 build_er_1(info, M68K_INS_OR, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002872}
2873
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002874static void d68000_or_re_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002875{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002876 build_re_1(info, M68K_INS_OR, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002877}
2878
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002879static void d68000_or_re_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002880{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002881 build_re_1(info, M68K_INS_OR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002882}
2883
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002884static void d68000_or_re_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002885{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002886 build_re_1(info, M68K_INS_OR, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002887}
2888
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002889static void d68000_ori_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002890{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002891 build_imm_ea(info, M68K_INS_ORI, 1, read_imm_8(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02002892}
2893
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002894static void d68000_ori_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002895{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002896 build_imm_ea(info, M68K_INS_ORI, 2, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02002897}
2898
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002899static void d68000_ori_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002900{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002901 build_imm_ea(info, M68K_INS_ORI, 4, read_imm_32(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02002902}
2903
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002904static void d68000_ori_to_ccr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002905{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002906 build_imm_special_reg(info, M68K_INS_ORI, read_imm_8(info), 1, M68K_REG_CCR);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002907}
2908
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002909static void d68000_ori_to_sr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002910{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002911 build_imm_special_reg(info, M68K_INS_ORI, read_imm_16(info), 2, M68K_REG_SR);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002912}
2913
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002914static void d68020_pack_rr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002915{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002916 LIMIT_CPU_TYPES(info, M68020_PLUS);
2917 build_rr(info, M68K_INS_PACK, 0, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02002918}
2919
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002920static void d68020_pack_mm(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002921{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002922 LIMIT_CPU_TYPES(info, M68020_PLUS);
2923 build_mm(info, M68K_INS_PACK, 0, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02002924}
2925
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002926static void d68000_pea(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002927{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002928 build_ea(info, M68K_INS_PEA, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002929}
2930
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002931static void d68000_reset(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002932{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002933 MCInst_setOpcode(info->inst, M68K_INS_RESET);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002934}
2935
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002936static void d68000_ror_s_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002937{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002938 build_3bit_d(info, M68K_INS_ROR, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002939}
2940
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002941static void d68000_ror_s_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002942{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002943 build_3bit_d(info, M68K_INS_ROR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002944}
2945
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002946static void d68000_ror_s_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002947{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002948 build_3bit_d(info, M68K_INS_ROR, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002949}
2950
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002951static void d68000_ror_r_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002952{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002953 build_r(info, M68K_INS_ROR, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002954}
2955
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002956static void d68000_ror_r_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002957{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002958 build_r(info, M68K_INS_ROR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002959}
2960
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002961static void d68000_ror_r_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002962{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002963 build_r(info, M68K_INS_ROR, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002964}
2965
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002966static void d68000_ror_ea(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002967{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002968 build_ea(info, M68K_INS_ROR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002969}
2970
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002971static void d68000_rol_s_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002972{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002973 build_3bit_d(info, M68K_INS_ROL, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002974}
2975
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002976static void d68000_rol_s_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002977{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002978 build_3bit_d(info, M68K_INS_ROL, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002979}
2980
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002981static void d68000_rol_s_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002982{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002983 build_3bit_d(info, M68K_INS_ROL, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002984}
2985
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002986static void d68000_rol_r_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002987{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002988 build_r(info, M68K_INS_ROL, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002989}
2990
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002991static void d68000_rol_r_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002992{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002993 build_r(info, M68K_INS_ROL, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002994}
2995
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002996static void d68000_rol_r_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02002997{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11002998 build_r(info, M68K_INS_ROL, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02002999}
3000
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003001static void d68000_rol_ea(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003002{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003003 build_ea(info, M68K_INS_ROL, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003004}
3005
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003006static void d68000_roxr_s_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003007{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003008 build_3bit_d(info, M68K_INS_ROXR, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003009}
3010
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003011static void d68000_roxr_s_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003012{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003013 build_3bit_d(info, M68K_INS_ROXR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003014}
3015
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003016static void d68000_roxr_s_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003017{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003018 build_3bit_d(info, M68K_INS_ROXR, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003019}
3020
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003021static void d68000_roxr_r_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003022{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003023 build_3bit_d(info, M68K_INS_ROXR, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003024}
3025
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003026static void d68000_roxr_r_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003027{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003028 build_r(info, M68K_INS_ROXR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003029}
3030
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003031static void d68000_roxr_r_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003032{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003033 build_r(info, M68K_INS_ROXR, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003034}
3035
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003036static void d68000_roxr_ea(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003037{
jmechnichab108642016-04-03 13:50:28 +02003038 build_ea(info, M68K_INS_ROXR, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003039}
3040
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003041static void d68000_roxl_s_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003042{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003043 build_3bit_d(info, M68K_INS_ROXL, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003044}
3045
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003046static void d68000_roxl_s_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003047{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003048 build_3bit_d(info, M68K_INS_ROXL, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003049}
3050
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003051static void d68000_roxl_s_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003052{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003053 build_3bit_d(info, M68K_INS_ROXL, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003054}
3055
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003056static void d68000_roxl_r_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003057{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003058 build_r(info, M68K_INS_ROXL, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003059}
3060
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003061static void d68000_roxl_r_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003062{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003063 build_r(info, M68K_INS_ROXL, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003064}
3065
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003066static void d68000_roxl_r_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003067{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003068 build_r(info, M68K_INS_ROXL, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003069}
3070
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003071static void d68000_roxl_ea(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003072{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003073 build_ea(info, M68K_INS_ROXL, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003074}
3075
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003076static void d68010_rtd(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003077{
Daniel Collin988bb632016-04-10 10:55:21 +02003078 set_insn_group(info, M68K_GRP_RET);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003079 LIMIT_CPU_TYPES(info, M68010_PLUS);
3080 build_bxx(info, M68K_INS_RTD, 0, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02003081}
3082
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003083static void d68000_rte(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003084{
Daniel Collin988bb632016-04-10 10:55:21 +02003085 set_insn_group(info, M68K_GRP_IRET);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003086 MCInst_setOpcode(info->inst, M68K_INS_RTE);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003087}
3088
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003089static void d68020_rtm(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003090{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08003091 cs_m68k* ext;
3092 cs_m68k_op* op;
3093
Daniel Collin988bb632016-04-10 10:55:21 +02003094 set_insn_group(info, M68K_GRP_RET);
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08003095
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003096 LIMIT_CPU_TYPES(info, M68020_ONLY);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003097
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003098 build_bxx(info, M68K_INS_RTM, 0, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003099
Nicolas PLANELd529ea02015-10-05 20:19:33 +11003100 ext = &info->extension;
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08003101 op = &ext->operands[0];
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08003102
Daniel Collin2ee675c2015-08-03 18:45:08 +02003103 op->address_mode = M68K_AM_NONE;
3104 op->type = M68K_OP_REG;
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08003105
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003106 if (BIT_3(info->ir)) {
3107 op->reg = M68K_REG_A0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003108 } else {
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003109 op->reg = M68K_REG_D0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003110 }
3111}
3112
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003113static void d68000_rtr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003114{
Daniel Collin988bb632016-04-10 10:55:21 +02003115 set_insn_group(info, M68K_GRP_RET);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003116 MCInst_setOpcode(info->inst, M68K_INS_RTR);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003117}
3118
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003119static void d68000_rts(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003120{
Daniel Collin988bb632016-04-10 10:55:21 +02003121 set_insn_group(info, M68K_GRP_RET);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003122 MCInst_setOpcode(info->inst, M68K_INS_RTS);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003123}
3124
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003125static void d68000_sbcd_rr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003126{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003127 build_rr(info, M68K_INS_SBCD, 1, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003128}
3129
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003130static void d68000_sbcd_mm(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003131{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003132 build_mm(info, M68K_INS_SBCD, 0, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02003133}
3134
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003135static void d68000_scc(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003136{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003137 cs_m68k* ext = build_init_op(info, s_scc_lut[(info->ir >> 8) & 0xf], 1, 1);
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003138 get_ea_mode_op(info, &ext->operands[0], info->ir, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003139}
3140
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003141static void d68000_stop(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003142{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003143 build_bxx(info, M68K_INS_STOP, 0, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02003144}
3145
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003146static void d68000_sub_er_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003147{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003148 build_er_1(info, M68K_INS_SUB, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003149}
3150
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003151static void d68000_sub_er_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003152{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003153 build_er_1(info, M68K_INS_SUB, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003154}
3155
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003156static void d68000_sub_er_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003157{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003158 build_er_1(info, M68K_INS_SUB, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003159}
3160
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003161static void d68000_sub_re_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003162{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003163 build_re_1(info, M68K_INS_SUB, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003164}
3165
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003166static void d68000_sub_re_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003167{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003168 build_re_1(info, M68K_INS_SUB, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003169}
3170
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003171static void d68000_sub_re_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003172{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003173 build_re_1(info, M68K_INS_SUB, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003174}
3175
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003176static void d68000_suba_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003177{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003178 build_ea_a(info, M68K_INS_SUBA, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003179}
3180
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003181static void d68000_suba_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003182{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003183 build_ea_a(info, M68K_INS_SUBA, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003184}
3185
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003186static void d68000_subi_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003187{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003188 build_imm_ea(info, M68K_INS_SUBI, 1, read_imm_8(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02003189}
3190
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003191static void d68000_subi_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003192{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003193 build_imm_ea(info, M68K_INS_SUBI, 2, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02003194}
3195
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003196static void d68000_subi_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003197{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003198 build_imm_ea(info, M68K_INS_SUBI, 4, read_imm_32(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02003199}
3200
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003201static void d68000_subq_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003202{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003203 build_3bit_ea(info, M68K_INS_SUBQ, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003204}
3205
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003206static void d68000_subq_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003207{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003208 build_3bit_ea(info, M68K_INS_SUBQ, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003209}
3210
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003211static void d68000_subq_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003212{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003213 build_3bit_ea(info, M68K_INS_SUBQ, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003214}
3215
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003216static void d68000_subx_rr_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003217{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003218 build_rr(info, M68K_INS_SUBX, 1, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003219}
3220
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003221static void d68000_subx_rr_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003222{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003223 build_rr(info, M68K_INS_SUBX, 2, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003224}
3225
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003226static void d68000_subx_rr_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003227{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003228 build_rr(info, M68K_INS_SUBX, 4, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003229}
3230
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003231static void d68000_subx_mm_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003232{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003233 build_mm(info, M68K_INS_SUBX, 1, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003234}
3235
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003236static void d68000_subx_mm_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003237{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003238 build_mm(info, M68K_INS_SUBX, 2, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003239}
3240
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003241static void d68000_subx_mm_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003242{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003243 build_mm(info, M68K_INS_SUBX, 4, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003244}
3245
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003246static void d68000_swap(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003247{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003248 build_d(info, M68K_INS_SWAP, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003249}
3250
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003251static void d68000_tas(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003252{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003253 build_ea(info, M68K_INS_TAS, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003254}
3255
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003256static void d68000_trap(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003257{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003258 build_bxx(info, M68K_INS_TRAP, 0, info->ir&0xf);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003259}
3260
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003261static void d68020_trapcc_0(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003262{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003263 LIMIT_CPU_TYPES(info, M68020_PLUS);
3264 build_trap(info, 0, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003265
Nicolas PLANELd529ea02015-10-05 20:19:33 +11003266 info->extension.op_count = 0;
Daniel Collin2ee675c2015-08-03 18:45:08 +02003267}
3268
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003269static void d68020_trapcc_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003270{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003271 LIMIT_CPU_TYPES(info, M68020_PLUS);
3272 build_trap(info, 2, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02003273}
3274
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003275static void d68020_trapcc_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003276{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003277 LIMIT_CPU_TYPES(info, M68020_PLUS);
3278 build_trap(info, 4, read_imm_32(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02003279}
3280
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003281static void d68000_trapv(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003282{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003283 MCInst_setOpcode(info->inst, M68K_INS_TRAPV);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003284}
3285
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003286static void d68000_tst_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003287{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003288 build_ea(info, M68K_INS_TST, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003289}
3290
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003291static void d68020_tst_pcdi_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003292{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003293 LIMIT_CPU_TYPES(info, M68020_PLUS);
3294 build_ea(info, M68K_INS_TST, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003295}
3296
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003297static void d68020_tst_pcix_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003298{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003299 LIMIT_CPU_TYPES(info, M68020_PLUS);
3300 build_ea(info, M68K_INS_TST, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003301}
3302
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003303static void d68020_tst_i_8(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003304{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003305 LIMIT_CPU_TYPES(info, M68020_PLUS);
3306 build_ea(info, M68K_INS_TST, 1);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003307}
3308
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003309static void d68000_tst_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003310{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003311 build_ea(info, M68K_INS_TST, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003312}
3313
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003314static void d68020_tst_a_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003315{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003316 LIMIT_CPU_TYPES(info, M68020_PLUS);
3317 build_ea(info, M68K_INS_TST, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003318}
3319
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003320static void d68020_tst_pcdi_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003321{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003322 LIMIT_CPU_TYPES(info, M68020_PLUS);
3323 build_ea(info, M68K_INS_TST, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003324}
3325
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003326static void d68020_tst_pcix_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003327{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003328 LIMIT_CPU_TYPES(info, M68020_PLUS);
3329 build_ea(info, M68K_INS_TST, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003330}
3331
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003332static void d68020_tst_i_16(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003333{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003334 LIMIT_CPU_TYPES(info, M68020_PLUS);
3335 build_ea(info, M68K_INS_TST, 2);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003336}
3337
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003338static void d68000_tst_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003339{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003340 build_ea(info, M68K_INS_TST, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003341}
3342
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003343static void d68020_tst_a_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003344{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003345 LIMIT_CPU_TYPES(info, M68020_PLUS);
3346 build_ea(info, M68K_INS_TST, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003347}
3348
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003349static void d68020_tst_pcdi_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003350{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003351 LIMIT_CPU_TYPES(info, M68020_PLUS);
3352 build_ea(info, M68K_INS_TST, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003353}
3354
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003355static void d68020_tst_pcix_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003356{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003357 LIMIT_CPU_TYPES(info, M68020_PLUS);
3358 build_ea(info, M68K_INS_TST, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003359}
3360
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003361static void d68020_tst_i_32(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003362{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003363 LIMIT_CPU_TYPES(info, M68020_PLUS);
3364 build_ea(info, M68K_INS_TST, 4);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003365}
3366
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003367static void d68000_unlk(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003368{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08003369 cs_m68k_op* op;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003370 cs_m68k* ext = build_init_op(info, M68K_INS_UNLK, 1, 0);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003371
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08003372 op = &ext->operands[0];
Daniel Collin2ee675c2015-08-03 18:45:08 +02003373
3374 op->address_mode = M68K_AM_REG_DIRECT_ADDR;
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003375 op->reg = M68K_REG_A0 + (info->ir & 7);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003376}
3377
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003378static void d68020_unpk_rr(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003379{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003380 LIMIT_CPU_TYPES(info, M68020_PLUS);
3381 build_rr(info, M68K_INS_UNPK, 0, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02003382}
3383
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003384static void d68020_unpk_mm(m68k_info *info)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003385{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003386 LIMIT_CPU_TYPES(info, M68020_PLUS);
3387 build_mm(info, M68K_INS_UNPK, 0, read_imm_16(info));
Daniel Collin2ee675c2015-08-03 18:45:08 +02003388}
3389
3390/* ======================================================================== */
3391/* ======================= INSTRUCTION TABLE BUILDER ====================== */
3392/* ======================================================================== */
3393
3394/* EA Masks:
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08003395 800 = data register direct
3396 400 = address register direct
3397 200 = address register indirect
3398 100 = ARI postincrement
3399 80 = ARI pre-decrement
3400 40 = ARI displacement
3401 20 = ARI index
3402 10 = absolute short
3403 8 = absolute long
3404 4 = immediate / sr
3405 2 = pc displacement
3406 1 = pc idx
3407 */
Daniel Collin2ee675c2015-08-03 18:45:08 +02003408
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08003409static opcode_struct g_opcode_info[] = {
3410 /* opcode handler mask match ea_mask mask2 match2*/
Daniel Collin2ee675c2015-08-03 18:45:08 +02003411 {d68000_1010 , 0xf000, 0xa000, 0x000},
3412 {d68000_1111 , 0xf000, 0xf000, 0x000},
3413 {d68000_abcd_rr , 0xf1f8, 0xc100, 0x000},
3414 {d68000_abcd_mm , 0xf1f8, 0xc108, 0x000},
3415 {d68000_add_er_8 , 0xf1c0, 0xd000, 0xbff},
3416 {d68000_add_er_16 , 0xf1c0, 0xd040, 0xfff},
3417 {d68000_add_er_32 , 0xf1c0, 0xd080, 0xfff},
3418 {d68000_add_re_8 , 0xf1c0, 0xd100, 0x3f8},
3419 {d68000_add_re_16 , 0xf1c0, 0xd140, 0x3f8},
3420 {d68000_add_re_32 , 0xf1c0, 0xd180, 0x3f8},
3421 {d68000_adda_16 , 0xf1c0, 0xd0c0, 0xfff},
3422 {d68000_adda_32 , 0xf1c0, 0xd1c0, 0xfff},
3423 {d68000_addi_8 , 0xffc0, 0x0600, 0xbf8},
3424 {d68000_addi_16 , 0xffc0, 0x0640, 0xbf8},
3425 {d68000_addi_32 , 0xffc0, 0x0680, 0xbf8},
3426 {d68000_addq_8 , 0xf1c0, 0x5000, 0xbf8},
3427 {d68000_addq_16 , 0xf1c0, 0x5040, 0xff8},
3428 {d68000_addq_32 , 0xf1c0, 0x5080, 0xff8},
3429 {d68000_addx_rr_8 , 0xf1f8, 0xd100, 0x000},
3430 {d68000_addx_rr_16 , 0xf1f8, 0xd140, 0x000},
3431 {d68000_addx_rr_32 , 0xf1f8, 0xd180, 0x000},
3432 {d68000_addx_mm_8 , 0xf1f8, 0xd108, 0x000},
3433 {d68000_addx_mm_16 , 0xf1f8, 0xd148, 0x000},
3434 {d68000_addx_mm_32 , 0xf1f8, 0xd188, 0x000},
3435 {d68000_and_er_8 , 0xf1c0, 0xc000, 0xbff},
3436 {d68000_and_er_16 , 0xf1c0, 0xc040, 0xbff},
3437 {d68000_and_er_32 , 0xf1c0, 0xc080, 0xbff},
3438 {d68000_and_re_8 , 0xf1c0, 0xc100, 0x3f8},
3439 {d68000_and_re_16 , 0xf1c0, 0xc140, 0x3f8},
3440 {d68000_and_re_32 , 0xf1c0, 0xc180, 0x3f8},
3441 {d68000_andi_to_ccr , 0xffff, 0x023c, 0x000, 0xff00, 0x0000},
3442 {d68000_andi_to_sr , 0xffff, 0x027c, 0x000},
3443 {d68000_andi_8 , 0xffc0, 0x0200, 0xbf8},
3444 {d68000_andi_16 , 0xffc0, 0x0240, 0xbf8},
3445 {d68000_andi_32 , 0xffc0, 0x0280, 0xbf8},
3446 {d68000_asr_s_8 , 0xf1f8, 0xe000, 0x000},
3447 {d68000_asr_s_16 , 0xf1f8, 0xe040, 0x000},
3448 {d68000_asr_s_32 , 0xf1f8, 0xe080, 0x000},
3449 {d68000_asr_r_8 , 0xf1f8, 0xe020, 0x000},
3450 {d68000_asr_r_16 , 0xf1f8, 0xe060, 0x000},
3451 {d68000_asr_r_32 , 0xf1f8, 0xe0a0, 0x000},
3452 {d68000_asr_ea , 0xffc0, 0xe0c0, 0x3f8},
3453 {d68000_asl_s_8 , 0xf1f8, 0xe100, 0x000},
3454 {d68000_asl_s_16 , 0xf1f8, 0xe140, 0x000},
3455 {d68000_asl_s_32 , 0xf1f8, 0xe180, 0x000},
3456 {d68000_asl_r_8 , 0xf1f8, 0xe120, 0x000},
3457 {d68000_asl_r_16 , 0xf1f8, 0xe160, 0x000},
3458 {d68000_asl_r_32 , 0xf1f8, 0xe1a0, 0x000},
3459 {d68000_asl_ea , 0xffc0, 0xe1c0, 0x3f8},
3460 {d68000_bcc_8 , 0xf000, 0x6000, 0x000},
3461 {d68000_bcc_16 , 0xf0ff, 0x6000, 0x000},
3462 {d68020_bcc_32 , 0xf0ff, 0x60ff, 0x000},
3463 {d68000_bchg_r , 0xf1c0, 0x0140, 0xbf8},
3464 {d68000_bchg_s , 0xffc0, 0x0840, 0xbf8, 0xff00, 0x0000},
3465 {d68000_bclr_r , 0xf1c0, 0x0180, 0xbf8},
3466 {d68000_bclr_s , 0xffc0, 0x0880, 0xbf8, 0xff00, 0x0000},
3467 {d68020_bfchg , 0xffc0, 0xeac0, 0xa78, 0xf000, 0x0000},
3468 {d68020_bfclr , 0xffc0, 0xecc0, 0xa78, 0xf000, 0x0000},
3469 {d68020_bfexts , 0xffc0, 0xebc0, 0xa7b, 0x8000, 0x0000},
3470 {d68020_bfextu , 0xffc0, 0xe9c0, 0xa7b, 0x8000, 0x0000},
3471 {d68020_bfffo , 0xffc0, 0xedc0, 0xa7b, 0x8000, 0x0000},
3472 {d68020_bfins , 0xffc0, 0xefc0, 0xa78, 0x8000, 0x0000},
3473 {d68020_bfset , 0xffc0, 0xeec0, 0xa78, 0xf000, 0x0000},
3474 {d68020_bftst , 0xffc0, 0xe8c0, 0xa7b, 0xf000, 0x0000},
3475 {d68010_bkpt , 0xfff8, 0x4848, 0x000},
3476 {d68000_bra_8 , 0xff00, 0x6000, 0x000},
3477 {d68000_bra_16 , 0xffff, 0x6000, 0x000},
3478 {d68020_bra_32 , 0xffff, 0x60ff, 0x000},
3479 {d68000_bset_r , 0xf1c0, 0x01c0, 0xbf8},
3480 {d68000_bset_s , 0xffc0, 0x08c0, 0xbf8, 0xfe00, 0x0000 },
3481 {d68000_bsr_8 , 0xff00, 0x6100, 0x000},
3482 {d68000_bsr_16 , 0xffff, 0x6100, 0x000},
3483 {d68020_bsr_32 , 0xffff, 0x61ff, 0x000},
3484 {d68000_btst_r , 0xf1c0, 0x0100, 0xbff},
3485 {d68000_btst_s , 0xffc0, 0x0800, 0xbfb, 0xff00, 0x0000},
3486 {d68020_callm , 0xffc0, 0x06c0, 0x27b, 0xff00, 0x0000},
3487 {d68020_cas_8 , 0xffc0, 0x0ac0, 0x3f8, 0xfe38, 0x0000},
3488 {d68020_cas_16 , 0xffc0, 0x0cc0, 0x3f8, 0xfe38, 0x0000},
3489 {d68020_cas_32 , 0xffc0, 0x0ec0, 0x3f8, 0xfe38, 0x0000},
3490 {d68020_cas2_16 , 0xffff, 0x0cfc, 0x000, 0x0e38, 0x0000/*, 0x0e38, 0x0000 */},
3491 {d68020_cas2_32 , 0xffff, 0x0efc, 0x000, 0x0e38, 0x0000/*, 0x0e38, 0x0000 */},
3492 {d68000_chk_16 , 0xf1c0, 0x4180, 0xbff},
3493 {d68020_chk_32 , 0xf1c0, 0x4100, 0xbff},
3494 {d68020_chk2_cmp2_8 , 0xffc0, 0x00c0, 0x27b, 0x07ff, 0x0000},
3495 {d68020_chk2_cmp2_16 , 0xffc0, 0x02c0, 0x27b, 0x07ff, 0x0000},
3496 {d68020_chk2_cmp2_32 , 0xffc0, 0x04c0, 0x27b, 0x07ff, 0x0000},
3497 {d68040_cinv , 0xff20, 0xf400, 0x000},
3498 {d68000_clr_8 , 0xffc0, 0x4200, 0xbf8},
3499 {d68000_clr_16 , 0xffc0, 0x4240, 0xbf8},
3500 {d68000_clr_32 , 0xffc0, 0x4280, 0xbf8},
3501 {d68000_cmp_8 , 0xf1c0, 0xb000, 0xbff},
3502 {d68000_cmp_16 , 0xf1c0, 0xb040, 0xfff},
3503 {d68000_cmp_32 , 0xf1c0, 0xb080, 0xfff},
3504 {d68000_cmpa_16 , 0xf1c0, 0xb0c0, 0xfff},
3505 {d68000_cmpa_32 , 0xf1c0, 0xb1c0, 0xfff},
3506 {d68000_cmpi_8 , 0xffc0, 0x0c00, 0xbf8},
3507 {d68020_cmpi_pcdi_8 , 0xffff, 0x0c3a, 0x000},
3508 {d68020_cmpi_pcix_8 , 0xffff, 0x0c3b, 0x000},
3509 {d68000_cmpi_16 , 0xffc0, 0x0c40, 0xbf8},
3510 {d68020_cmpi_pcdi_16 , 0xffff, 0x0c7a, 0x000},
3511 {d68020_cmpi_pcix_16 , 0xffff, 0x0c7b, 0x000},
3512 {d68000_cmpi_32 , 0xffc0, 0x0c80, 0xbf8},
3513 {d68020_cmpi_pcdi_32 , 0xffff, 0x0cba, 0x000},
3514 {d68020_cmpi_pcix_32 , 0xffff, 0x0cbb, 0x000},
3515 {d68000_cmpm_8 , 0xf1f8, 0xb108, 0x000},
3516 {d68000_cmpm_16 , 0xf1f8, 0xb148, 0x000},
3517 {d68000_cmpm_32 , 0xf1f8, 0xb188, 0x000},
3518 {d68020_cpbcc_16 , 0xf1c0, 0xf080, 0x000},
3519 {d68020_cpbcc_32 , 0xf1c0, 0xf0c0, 0x000},
3520 {d68020_cpdbcc , 0xf1f8, 0xf048, 0x000},
3521 {d68020_cpgen , 0xf1c0, 0xf000, 0x000},
3522 {d68020_cprestore , 0xf1c0, 0xf140, 0x37f},
3523 {d68020_cpsave , 0xf1c0, 0xf100, 0x2f8},
3524 {d68020_cpscc , 0xf1c0, 0xf040, 0xbf8},
3525 {d68020_cptrapcc_0 , 0xf1ff, 0xf07c, 0x000},
3526 {d68020_cptrapcc_16 , 0xf1ff, 0xf07a, 0x000},
3527 {d68020_cptrapcc_32 , 0xf1ff, 0xf07b, 0x000},
3528 {d68040_cpush , 0xff20, 0xf420, 0x000},
3529 {d68000_dbcc , 0xf0f8, 0x50c8, 0x000},
3530 {d68000_dbra , 0xfff8, 0x51c8, 0x000},
3531 {d68000_divs , 0xf1c0, 0x81c0, 0xbff},
3532 {d68000_divu , 0xf1c0, 0x80c0, 0xbff},
3533 {d68020_divl , 0xff80, 0x4c00, 0xbff, 0x83f8, 0x0000},
3534 {d68000_eor_8 , 0xf1c0, 0xb100, 0xbf8},
3535 {d68000_eor_16 , 0xf1c0, 0xb140, 0xbf8},
3536 {d68000_eor_32 , 0xf1c0, 0xb180, 0xbf8},
3537 {d68000_eori_to_ccr , 0xffff, 0x0a3c, 0x000, 0xff00, 0x0000},
3538 {d68000_eori_to_sr , 0xffff, 0x0a7c, 0x000},
3539 {d68000_eori_8 , 0xffc0, 0x0a00, 0xbf8},
3540 {d68000_eori_16 , 0xffc0, 0x0a40, 0xbf8},
3541 {d68000_eori_32 , 0xffc0, 0x0a80, 0xbf8},
3542 {d68000_exg_dd , 0xf1f8, 0xc140, 0x000},
3543 {d68000_exg_aa , 0xf1f8, 0xc148, 0x000},
3544 {d68000_exg_da , 0xf1f8, 0xc188, 0x000},
3545 {d68020_extb_32 , 0xfff8, 0x49c0, 0x000},
3546 {d68000_ext_16 , 0xfff8, 0x4880, 0x000},
3547 {d68000_ext_32 , 0xfff8, 0x48c0, 0x000},
3548 {d68000_illegal , 0xffff, 0x4afc, 0x000},
3549 {d68000_jmp , 0xffc0, 0x4ec0, 0x27b},
3550 {d68000_jsr , 0xffc0, 0x4e80, 0x27b},
3551 {d68000_lea , 0xf1c0, 0x41c0, 0x27b},
3552 {d68000_link_16 , 0xfff8, 0x4e50, 0x000},
3553 {d68020_link_32 , 0xfff8, 0x4808, 0x000},
3554 {d68000_lsr_s_8 , 0xf1f8, 0xe008, 0x000},
3555 {d68000_lsr_s_16 , 0xf1f8, 0xe048, 0x000},
3556 {d68000_lsr_s_32 , 0xf1f8, 0xe088, 0x000},
3557 {d68000_lsr_r_8 , 0xf1f8, 0xe028, 0x000},
3558 {d68000_lsr_r_16 , 0xf1f8, 0xe068, 0x000},
3559 {d68000_lsr_r_32 , 0xf1f8, 0xe0a8, 0x000},
3560 {d68000_lsr_ea , 0xffc0, 0xe2c0, 0x3f8},
3561 {d68000_lsl_s_8 , 0xf1f8, 0xe108, 0x000},
3562 {d68000_lsl_s_16 , 0xf1f8, 0xe148, 0x000},
3563 {d68000_lsl_s_32 , 0xf1f8, 0xe188, 0x000},
3564 {d68000_lsl_r_8 , 0xf1f8, 0xe128, 0x000},
3565 {d68000_lsl_r_16 , 0xf1f8, 0xe168, 0x000},
3566 {d68000_lsl_r_32 , 0xf1f8, 0xe1a8, 0x000},
3567 {d68000_lsl_ea , 0xffc0, 0xe3c0, 0x3f8},
3568 {d68000_move_8 , 0xf000, 0x1000, 0xbff},
3569 {d68000_move_16 , 0xf000, 0x3000, 0xfff},
3570 {d68000_move_32 , 0xf000, 0x2000, 0xfff},
3571 {d68000_movea_16 , 0xf1c0, 0x3040, 0xfff},
3572 {d68000_movea_32 , 0xf1c0, 0x2040, 0xfff},
3573 {d68000_move_to_ccr , 0xffc0, 0x44c0, 0xbff},
3574 {d68010_move_fr_ccr , 0xffc0, 0x42c0, 0xbf8},
3575 {d68000_move_to_sr , 0xffc0, 0x46c0, 0xbff},
3576 {d68000_move_fr_sr , 0xffc0, 0x40c0, 0xbf8},
3577 {d68000_move_to_usp , 0xfff8, 0x4e60, 0x000},
3578 {d68000_move_fr_usp , 0xfff8, 0x4e68, 0x000},
3579 {d68010_movec , 0xfffe, 0x4e7a, 0x000},
3580 {d68000_movem_pd_16 , 0xfff8, 0x48a0, 0x000},
3581 {d68000_movem_pd_32 , 0xfff8, 0x48e0, 0x000},
3582 {d68000_movem_re_16 , 0xffc0, 0x4880, 0x2f8},
3583 {d68000_movem_re_32 , 0xffc0, 0x48c0, 0x2f8},
3584 {d68000_movem_er_16 , 0xffc0, 0x4c80, 0x37b},
3585 {d68000_movem_er_32 , 0xffc0, 0x4cc0, 0x37b},
3586 {d68000_movep_er_16 , 0xf1f8, 0x0108, 0x000},
3587 {d68000_movep_er_32 , 0xf1f8, 0x0148, 0x000},
3588 {d68000_movep_re_16 , 0xf1f8, 0x0188, 0x000},
3589 {d68000_movep_re_32 , 0xf1f8, 0x01c8, 0x000},
3590 {d68010_moves_8 , 0xffc0, 0x0e00, 0x3f8, 0x07ff, 0x0000},
3591 {d68010_moves_16 , 0xffc0, 0x0e40, 0x3f8, 0x07ff, 0x0000},
3592 {d68010_moves_32 , 0xffc0, 0x0e80, 0x3f8, 0x07ff, 0x0000},
3593 {d68000_moveq , 0xf100, 0x7000, 0x000},
3594 {d68040_move16_pi_pi , 0xfff8, 0xf620, 0x000, 0x8fff, 0x8000},
3595 {d68040_move16_pi_al , 0xfff8, 0xf600, 0x000},
3596 {d68040_move16_al_pi , 0xfff8, 0xf608, 0x000},
3597 {d68040_move16_ai_al , 0xfff8, 0xf610, 0x000},
3598 {d68040_move16_al_ai , 0xfff8, 0xf618, 0x000},
3599 {d68000_muls , 0xf1c0, 0xc1c0, 0xbff},
3600 {d68000_mulu , 0xf1c0, 0xc0c0, 0xbff},
3601 {d68020_mull , 0xffc0, 0x4c00, 0xbff, 0x83f8, 0x0000},
3602 {d68000_nbcd , 0xffc0, 0x4800, 0xbf8},
3603 {d68000_neg_8 , 0xffc0, 0x4400, 0xbf8},
3604 {d68000_neg_16 , 0xffc0, 0x4440, 0xbf8},
3605 {d68000_neg_32 , 0xffc0, 0x4480, 0xbf8},
3606 {d68000_negx_8 , 0xffc0, 0x4000, 0xbf8},
3607 {d68000_negx_16 , 0xffc0, 0x4040, 0xbf8},
3608 {d68000_negx_32 , 0xffc0, 0x4080, 0xbf8},
3609 {d68000_nop , 0xffff, 0x4e71, 0x000},
3610 {d68000_not_8 , 0xffc0, 0x4600, 0xbf8},
3611 {d68000_not_16 , 0xffc0, 0x4640, 0xbf8},
3612 {d68000_not_32 , 0xffc0, 0x4680, 0xbf8},
3613 {d68000_or_er_8 , 0xf1c0, 0x8000, 0xbff},
3614 {d68000_or_er_16 , 0xf1c0, 0x8040, 0xbff},
3615 {d68000_or_er_32 , 0xf1c0, 0x8080, 0xbff},
3616 {d68000_or_re_8 , 0xf1c0, 0x8100, 0x3f8},
3617 {d68000_or_re_16 , 0xf1c0, 0x8140, 0x3f8},
3618 {d68000_or_re_32 , 0xf1c0, 0x8180, 0x3f8},
3619 {d68000_ori_to_ccr , 0xffff, 0x003c, 0x000, 0xff00, 0x0000},
3620 {d68000_ori_to_sr , 0xffff, 0x007c, 0x000},
3621 {d68000_ori_8 , 0xffc0, 0x0000, 0xbf8},
3622 {d68000_ori_16 , 0xffc0, 0x0040, 0xbf8},
3623 {d68000_ori_32 , 0xffc0, 0x0080, 0xbf8},
3624 {d68020_pack_rr , 0xf1f8, 0x8140, 0x000},
3625 {d68020_pack_mm , 0xf1f8, 0x8148, 0x000},
3626 {d68000_pea , 0xffc0, 0x4840, 0x27b},
3627 {d68000_reset , 0xffff, 0x4e70, 0x000},
3628 {d68000_ror_s_8 , 0xf1f8, 0xe018, 0x000},
3629 {d68000_ror_s_16 , 0xf1f8, 0xe058, 0x000},
3630 {d68000_ror_s_32 , 0xf1f8, 0xe098, 0x000},
3631 {d68000_ror_r_8 , 0xf1f8, 0xe038, 0x000},
3632 {d68000_ror_r_16 , 0xf1f8, 0xe078, 0x000},
3633 {d68000_ror_r_32 , 0xf1f8, 0xe0b8, 0x000},
3634 {d68000_ror_ea , 0xffc0, 0xe6c0, 0x3f8},
3635 {d68000_rol_s_8 , 0xf1f8, 0xe118, 0x000},
3636 {d68000_rol_s_16 , 0xf1f8, 0xe158, 0x000},
3637 {d68000_rol_s_32 , 0xf1f8, 0xe198, 0x000},
3638 {d68000_rol_r_8 , 0xf1f8, 0xe138, 0x000},
3639 {d68000_rol_r_16 , 0xf1f8, 0xe178, 0x000},
3640 {d68000_rol_r_32 , 0xf1f8, 0xe1b8, 0x000},
3641 {d68000_rol_ea , 0xffc0, 0xe7c0, 0x3f8},
3642 {d68000_roxr_s_8 , 0xf1f8, 0xe010, 0x000},
3643 {d68000_roxr_s_16 , 0xf1f8, 0xe050, 0x000},
3644 {d68000_roxr_s_32 , 0xf1f8, 0xe090, 0x000},
3645 {d68000_roxr_r_8 , 0xf1f8, 0xe030, 0x000},
3646 {d68000_roxr_r_16 , 0xf1f8, 0xe070, 0x000},
3647 {d68000_roxr_r_32 , 0xf1f8, 0xe0b0, 0x000},
3648 {d68000_roxr_ea , 0xffc0, 0xe4c0, 0x3f8},
3649 {d68000_roxl_s_8 , 0xf1f8, 0xe110, 0x000},
3650 {d68000_roxl_s_16 , 0xf1f8, 0xe150, 0x000},
3651 {d68000_roxl_s_32 , 0xf1f8, 0xe190, 0x000},
3652 {d68000_roxl_r_8 , 0xf1f8, 0xe130, 0x000},
3653 {d68000_roxl_r_16 , 0xf1f8, 0xe170, 0x000},
3654 {d68000_roxl_r_32 , 0xf1f8, 0xe1b0, 0x000},
3655 {d68000_roxl_ea , 0xffc0, 0xe5c0, 0x3f8},
3656 {d68010_rtd , 0xffff, 0x4e74, 0x000},
3657 {d68000_rte , 0xffff, 0x4e73, 0x000},
3658 {d68020_rtm , 0xfff0, 0x06c0, 0x000},
3659 {d68000_rtr , 0xffff, 0x4e77, 0x000},
3660 {d68000_rts , 0xffff, 0x4e75, 0x000},
3661 {d68000_sbcd_rr , 0xf1f8, 0x8100, 0x000},
3662 {d68000_sbcd_mm , 0xf1f8, 0x8108, 0x000},
3663 {d68000_scc , 0xf0c0, 0x50c0, 0xbf8},
3664 {d68000_stop , 0xffff, 0x4e72, 0x000},
3665 {d68000_sub_er_8 , 0xf1c0, 0x9000, 0xbff},
3666 {d68000_sub_er_16 , 0xf1c0, 0x9040, 0xfff},
3667 {d68000_sub_er_32 , 0xf1c0, 0x9080, 0xfff},
3668 {d68000_sub_re_8 , 0xf1c0, 0x9100, 0x3f8},
3669 {d68000_sub_re_16 , 0xf1c0, 0x9140, 0x3f8},
3670 {d68000_sub_re_32 , 0xf1c0, 0x9180, 0x3f8},
3671 {d68000_suba_16 , 0xf1c0, 0x90c0, 0xfff},
3672 {d68000_suba_32 , 0xf1c0, 0x91c0, 0xfff},
3673 {d68000_subi_8 , 0xffc0, 0x0400, 0xbf8},
3674 {d68000_subi_16 , 0xffc0, 0x0440, 0xbf8},
3675 {d68000_subi_32 , 0xffc0, 0x0480, 0xbf8},
3676 {d68000_subq_8 , 0xf1c0, 0x5100, 0xbf8},
3677 {d68000_subq_16 , 0xf1c0, 0x5140, 0xff8},
3678 {d68000_subq_32 , 0xf1c0, 0x5180, 0xff8},
3679 {d68000_subx_rr_8 , 0xf1f8, 0x9100, 0x000},
3680 {d68000_subx_rr_16 , 0xf1f8, 0x9140, 0x000},
3681 {d68000_subx_rr_32 , 0xf1f8, 0x9180, 0x000},
3682 {d68000_subx_mm_8 , 0xf1f8, 0x9108, 0x000},
3683 {d68000_subx_mm_16 , 0xf1f8, 0x9148, 0x000},
3684 {d68000_subx_mm_32 , 0xf1f8, 0x9188, 0x000},
3685 {d68000_swap , 0xfff8, 0x4840, 0x000},
3686 {d68000_tas , 0xffc0, 0x4ac0, 0xbf8},
3687 {d68000_trap , 0xfff0, 0x4e40, 0x000},
3688 {d68020_trapcc_0 , 0xf0ff, 0x50fc, 0x000},
3689 {d68020_trapcc_16 , 0xf0ff, 0x50fa, 0x000},
3690 {d68020_trapcc_32 , 0xf0ff, 0x50fb, 0x000},
3691 {d68000_trapv , 0xffff, 0x4e76, 0x000},
3692 {d68000_tst_8 , 0xffc0, 0x4a00, 0xbf8},
3693 {d68020_tst_pcdi_8 , 0xffff, 0x4a3a, 0x000},
3694 {d68020_tst_pcix_8 , 0xffff, 0x4a3b, 0x000},
3695 {d68020_tst_i_8 , 0xffff, 0x4a3c, 0x000},
3696 {d68000_tst_16 , 0xffc0, 0x4a40, 0xbf8},
3697 {d68020_tst_a_16 , 0xfff8, 0x4a48, 0x000},
3698 {d68020_tst_pcdi_16 , 0xffff, 0x4a7a, 0x000},
3699 {d68020_tst_pcix_16 , 0xffff, 0x4a7b, 0x000},
3700 {d68020_tst_i_16 , 0xffff, 0x4a7c, 0x000},
3701 {d68000_tst_32 , 0xffc0, 0x4a80, 0xbf8},
3702 {d68020_tst_a_32 , 0xfff8, 0x4a88, 0x000},
3703 {d68020_tst_pcdi_32 , 0xffff, 0x4aba, 0x000},
3704 {d68020_tst_pcix_32 , 0xffff, 0x4abb, 0x000},
3705 {d68020_tst_i_32 , 0xffff, 0x4abc, 0x000},
3706 {d68000_unlk , 0xfff8, 0x4e58, 0x000},
3707 {d68020_unpk_rr , 0xf1f8, 0x8180, 0x000},
3708 {d68020_unpk_mm , 0xf1f8, 0x8188, 0x000},
3709 {0, 0, 0, 0}
3710};
3711
3712/* Check if opcode is using a valid ea mode */
3713static int valid_ea(uint opcode, uint mask)
3714{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08003715 if (mask == 0)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003716 return 1;
3717
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08003718 switch(opcode & 0x3f) {
Daniel Collin2ee675c2015-08-03 18:45:08 +02003719 case 0x00: case 0x01: case 0x02: case 0x03:
3720 case 0x04: case 0x05: case 0x06: case 0x07:
3721 return (mask & 0x800) != 0;
3722 case 0x08: case 0x09: case 0x0a: case 0x0b:
3723 case 0x0c: case 0x0d: case 0x0e: case 0x0f:
3724 return (mask & 0x400) != 0;
3725 case 0x10: case 0x11: case 0x12: case 0x13:
3726 case 0x14: case 0x15: case 0x16: case 0x17:
3727 return (mask & 0x200) != 0;
3728 case 0x18: case 0x19: case 0x1a: case 0x1b:
3729 case 0x1c: case 0x1d: case 0x1e: case 0x1f:
3730 return (mask & 0x100) != 0;
3731 case 0x20: case 0x21: case 0x22: case 0x23:
3732 case 0x24: case 0x25: case 0x26: case 0x27:
3733 return (mask & 0x080) != 0;
3734 case 0x28: case 0x29: case 0x2a: case 0x2b:
3735 case 0x2c: case 0x2d: case 0x2e: case 0x2f:
3736 return (mask & 0x040) != 0;
3737 case 0x30: case 0x31: case 0x32: case 0x33:
3738 case 0x34: case 0x35: case 0x36: case 0x37:
3739 return (mask & 0x020) != 0;
3740 case 0x38:
3741 return (mask & 0x010) != 0;
3742 case 0x39:
3743 return (mask & 0x008) != 0;
3744 case 0x3a:
3745 return (mask & 0x002) != 0;
3746 case 0x3b:
3747 return (mask & 0x001) != 0;
3748 case 0x3c:
3749 return (mask & 0x004) != 0;
3750 }
3751 return 0;
3752
3753}
3754
3755/* Used by qsort */
3756static int DECL_SPEC compare_nof_true_bits(const void *aptr, const void *bptr)
3757{
3758 uint a = ((const opcode_struct*)aptr)->mask;
3759 uint b = ((const opcode_struct*)bptr)->mask;
3760
3761 a = ((a & 0xAAAA) >> 1) + (a & 0x5555);
3762 a = ((a & 0xCCCC) >> 2) + (a & 0x3333);
3763 a = ((a & 0xF0F0) >> 4) + (a & 0x0F0F);
3764 a = ((a & 0xFF00) >> 8) + (a & 0x00FF);
3765
3766 b = ((b & 0xAAAA) >> 1) + (b & 0x5555);
3767 b = ((b & 0xCCCC) >> 2) + (b & 0x3333);
3768 b = ((b & 0xF0F0) >> 4) + (b & 0x0F0F);
3769 b = ((b & 0xFF00) >> 8) + (b & 0x00FF);
3770
3771 return b - a; /* reversed to get greatest to least sorting */
3772}
3773
3774/* build the opcode handler jump table */
3775static void build_opcode_table(void)
3776{
3777 uint i;
3778 uint opcode;
3779 opcode_struct* ostruct;
3780 uint opcode_info_length = 0;
3781
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003782 /* Already initialized ? */
3783 if (g_instruction_table[0].instruction != NULL) {
3784 return;
3785 }
3786
Daniel Collin2ee675c2015-08-03 18:45:08 +02003787 for(ostruct = g_opcode_info;ostruct->opcode_handler != 0;ostruct++)
3788 opcode_info_length++;
3789
3790 qsort((void *)g_opcode_info, opcode_info_length, sizeof(g_opcode_info[0]), compare_nof_true_bits);
3791
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08003792 for(i=0;i<0x10000;i++) {
Daniel Collin2ee675c2015-08-03 18:45:08 +02003793 g_instruction_table[i].instruction = d68000_invalid; /* default to invalid, undecoded opcode */
3794 opcode = i;
3795 /* search through opcode info for a match */
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08003796 for(ostruct = g_opcode_info;ostruct->opcode_handler != 0;ostruct++) {
Daniel Collin2ee675c2015-08-03 18:45:08 +02003797 /* match opcode mask and allowed ea modes */
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003798 if ((opcode & ostruct->mask) == ostruct->match) {
Daniel Collin2ee675c2015-08-03 18:45:08 +02003799 /* Handle destination ea for move instructions */
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003800 if ((ostruct->opcode_handler == d68000_move_8 ||
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08003801 ostruct->opcode_handler == d68000_move_16 ||
3802 ostruct->opcode_handler == d68000_move_32) &&
3803 !valid_ea(((opcode>>9)&7) | ((opcode>>3)&0x38), 0xbf8))
3804 continue;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003805 if (valid_ea(opcode, ostruct->ea_mask)) {
Daniel Collin2ee675c2015-08-03 18:45:08 +02003806 g_instruction_table[i].instruction = ostruct->opcode_handler;
3807 g_instruction_table[i].word2_mask = ostruct->mask2;
3808 g_instruction_table[i].word2_match = ostruct->match2;
3809 break;
3810 }
3811 }
3812 }
3813 }
3814}
3815
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003816static int instruction_is_valid(m68k_info *info, const unsigned int word_check)
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08003817{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003818 const unsigned int instruction = info->ir;
Daniel Collin2ee675c2015-08-03 18:45:08 +02003819 instruction_struct *i = &g_instruction_table[instruction];
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08003820
Nicolas PLANELb9f66d62015-10-08 15:35:39 +11003821 if ( (i->word2_mask && ((word_check & i->word2_mask) != i->word2_match)) ||
3822 (i->instruction == d68000_invalid) ) {
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003823 d68000_invalid(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003824 return 0;
3825 }
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08003826
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08003827 return 1;
Daniel Collin2ee675c2015-08-03 18:45:08 +02003828}
3829
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003830static void m68k_setup_internals(m68k_info* info, MCInst* inst, unsigned int pc, unsigned int cpu_type)
3831{
3832 info->inst = inst;
3833 info->pc = pc;
3834 info->ir = 0;
3835 info->type = cpu_type;
3836 info->address_mask = 0xffffffff;
3837
3838 switch(info->type) {
3839 case M68K_CPU_TYPE_68000:
3840 info->type = TYPE_68000;
3841 info->address_mask = 0x00ffffff;
3842 break;
3843 case M68K_CPU_TYPE_68010:
3844 info->type = TYPE_68010;
3845 info->address_mask = 0x00ffffff;
3846 break;
3847 case M68K_CPU_TYPE_68EC020:
3848 info->type = TYPE_68020;
3849 info->address_mask = 0x00ffffff;
3850 break;
3851 case M68K_CPU_TYPE_68020:
3852 info->type = TYPE_68020;
3853 info->address_mask = 0xffffffff;
3854 break;
3855 case M68K_CPU_TYPE_68030:
3856 info->type = TYPE_68030;
3857 info->address_mask = 0xffffffff;
3858 break;
3859 case M68K_CPU_TYPE_68040:
3860 info->type = TYPE_68040;
3861 info->address_mask = 0xffffffff;
3862 break;
3863 default:
3864 info->address_mask = 0;
3865 return;
3866 }
3867}
3868
Daniel Collin2ee675c2015-08-03 18:45:08 +02003869/* ======================================================================== */
3870/* ================================= API ================================== */
3871/* ======================================================================== */
3872
3873/* Disasemble one instruction at pc and store in str_buff */
Nicolas PLANELee756262015-10-05 19:26:30 +11003874static unsigned int m68k_disassemble(m68k_info *info, uint64_t pc)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003875{
Nicolas PLANELee756262015-10-05 19:26:30 +11003876 MCInst *inst = info->inst;
Nicolas PLANELd529ea02015-10-05 20:19:33 +11003877 cs_m68k* ext = &info->extension;
3878 int i;
Daniel Collin988bb632016-04-10 10:55:21 +02003879
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003880 inst->Opcode = M68K_INS_INVALID;
Daniel Collin2ee675c2015-08-03 18:45:08 +02003881
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003882 build_opcode_table();
3883
Nicolas PLANELd529ea02015-10-05 20:19:33 +11003884 memset(ext, 0, sizeof(cs_m68k));
3885 ext->op_size.type = M68K_SIZE_TYPE_CPU;
Daniel Collin988bb632016-04-10 10:55:21 +02003886
Nicolas PLANELd529ea02015-10-05 20:19:33 +11003887 for (i = 0; i < M68K_OPERAND_COUNT; ++i)
3888 ext->operands[i].type = M68K_OP_REG;
Daniel Collin2ee675c2015-08-03 18:45:08 +02003889
Nicolas PLANELb9f66d62015-10-08 15:35:39 +11003890 info->ir = peek_imm_16(info);
3891 if (instruction_is_valid(info, peek_imm_32(info) & 0xffff)) {
3892 info->ir = read_imm_16(info);
Nicolas PLANELee756262015-10-05 19:26:30 +11003893 g_instruction_table[info->ir].instruction(info);
Daniel Collin2ee675c2015-08-03 18:45:08 +02003894 }
3895
Daniel Collin25d2ea62015-10-05 16:31:06 +02003896 return info->pc - (unsigned int)pc;
Daniel Collin2ee675c2015-08-03 18:45:08 +02003897}
3898
Nicolas PLANELee756262015-10-05 19:26:30 +11003899bool M68K_getInstruction(csh ud, const uint8_t* code, size_t code_len, MCInst* instr, uint16_t* size, uint64_t address, void* inst_info)
Daniel Colline8a4e982015-10-04 14:22:58 +02003900{
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08003901#ifdef M68K_DEBUG
3902 SStream ss;
3903#endif
Daniel Colline8a4e982015-10-04 14:22:58 +02003904 int s;
3905 int cpu_type = M68K_CPU_TYPE_68000;
Nicolas PLANEL44cc3d02015-10-05 21:56:39 +11003906 cs_struct* handle = instr->csh;
Daniel Collin988bb632016-04-10 10:55:21 +02003907 m68k_info *info = (m68k_info*)handle->printer_info;
Nicolas PLANELee756262015-10-05 19:26:30 +11003908
Daniel Collin1bca0542016-04-10 16:16:28 +02003909 info->groups_count = 0;
Nicolas PLANELee756262015-10-05 19:26:30 +11003910 info->code = code;
Nicolas PLANEL8daac3a2015-10-08 16:34:25 +11003911 info->code_len = code_len;
Nicolas PLANELee756262015-10-05 19:26:30 +11003912 info->baseAddress = address;
Daniel Colline8a4e982015-10-04 14:22:58 +02003913
3914 if (handle->mode & CS_MODE_M68K_010)
3915 cpu_type = M68K_CPU_TYPE_68010;
3916 if (handle->mode & CS_MODE_M68K_020)
3917 cpu_type = M68K_CPU_TYPE_68020;
3918 if (handle->mode & CS_MODE_M68K_030)
3919 cpu_type = M68K_CPU_TYPE_68030;
3920 if (handle->mode & CS_MODE_M68K_040)
3921 cpu_type = M68K_CPU_TYPE_68040;
3922 if (handle->mode & CS_MODE_M68K_060)
3923 cpu_type = M68K_CPU_TYPE_68040; // 060 = 040 for now
3924
Daniel Collin25d2ea62015-10-05 16:31:06 +02003925 m68k_setup_internals(info, instr, (unsigned int)address, cpu_type);
Nicolas PLANELee756262015-10-05 19:26:30 +11003926 s = m68k_disassemble(info, address);
Daniel Colline8a4e982015-10-04 14:22:58 +02003927
3928 if (s == 0) {
3929 *size = 2;
3930 return false;
3931 }
3932
3933#ifdef M68K_DEBUG
Daniel Colline8a4e982015-10-04 14:22:58 +02003934 SStream_Init(&ss);
3935 M68K_printInst(instr, &ss, info);
3936#endif
3937
Daniel Collin988bb632016-04-10 10:55:21 +02003938 // Make sure we always stay within range
Daniel Collin25d2ea62015-10-05 16:31:06 +02003939 if (s > (int)code_len)
Nguyen Anh Quynh918215d2016-03-08 11:08:20 +08003940 *size = (uint16_t)code_len;
Daniel Colline8a4e982015-10-04 14:22:58 +02003941 else
3942 *size = (uint16_t)s;
3943
3944 return true;
3945}
3946
Daniel Collin2ee675c2015-08-03 18:45:08 +02003947#if 0
3948
3949// Currently not used
3950
3951/* Check if the instruction is a valid one */
3952unsigned int m68k_is_valid_instruction(unsigned int instruction, unsigned int cpu_type)
3953{
Nicolas PLANEL3a64e582015-10-04 20:07:57 +11003954 build_opcode_table();
Daniel Collin2ee675c2015-08-03 18:45:08 +02003955
3956 instruction &= 0xffff;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003957 if (g_instruction_table[instruction] == d68000_invalid)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003958 return 0;
3959
Nguyen Anh Quynh7d5badd2015-10-04 21:45:50 +08003960 switch(cpu_type) {
Daniel Collin2ee675c2015-08-03 18:45:08 +02003961 case M68K_CPU_TYPE_68000:
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003962 if (g_instruction_table[instruction] == d68010_bkpt)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003963 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003964 if (g_instruction_table[instruction] == d68010_move_fr_ccr)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003965 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003966 if (g_instruction_table[instruction] == d68010_movec)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003967 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003968 if (g_instruction_table[instruction] == d68010_moves_8)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003969 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003970 if (g_instruction_table[instruction] == d68010_moves_16)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003971 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003972 if (g_instruction_table[instruction] == d68010_moves_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003973 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003974 if (g_instruction_table[instruction] == d68010_rtd)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003975 return 0;
3976 case M68K_CPU_TYPE_68010:
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003977 if (g_instruction_table[instruction] == d68020_bcc_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003978 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003979 if (g_instruction_table[instruction] == d68020_bfchg)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003980 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003981 if (g_instruction_table[instruction] == d68020_bfclr)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003982 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003983 if (g_instruction_table[instruction] == d68020_bfexts)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003984 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003985 if (g_instruction_table[instruction] == d68020_bfextu)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003986 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003987 if (g_instruction_table[instruction] == d68020_bfffo)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003988 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003989 if (g_instruction_table[instruction] == d68020_bfins)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003990 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003991 if (g_instruction_table[instruction] == d68020_bfset)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003992 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003993 if (g_instruction_table[instruction] == d68020_bftst)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003994 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003995 if (g_instruction_table[instruction] == d68020_bra_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003996 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003997 if (g_instruction_table[instruction] == d68020_bsr_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02003998 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08003999 if (g_instruction_table[instruction] == d68020_callm)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004000 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004001 if (g_instruction_table[instruction] == d68020_cas_8)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004002 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004003 if (g_instruction_table[instruction] == d68020_cas_16)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004004 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004005 if (g_instruction_table[instruction] == d68020_cas_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004006 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004007 if (g_instruction_table[instruction] == d68020_cas2_16)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004008 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004009 if (g_instruction_table[instruction] == d68020_cas2_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004010 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004011 if (g_instruction_table[instruction] == d68020_chk_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004012 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004013 if (g_instruction_table[instruction] == d68020_chk2_cmp2_8)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004014 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004015 if (g_instruction_table[instruction] == d68020_chk2_cmp2_16)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004016 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004017 if (g_instruction_table[instruction] == d68020_chk2_cmp2_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004018 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004019 if (g_instruction_table[instruction] == d68020_cmpi_pcdi_8)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004020 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004021 if (g_instruction_table[instruction] == d68020_cmpi_pcix_8)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004022 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004023 if (g_instruction_table[instruction] == d68020_cmpi_pcdi_16)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004024 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004025 if (g_instruction_table[instruction] == d68020_cmpi_pcix_16)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004026 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004027 if (g_instruction_table[instruction] == d68020_cmpi_pcdi_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004028 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004029 if (g_instruction_table[instruction] == d68020_cmpi_pcix_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004030 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004031 if (g_instruction_table[instruction] == d68020_cpbcc_16)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004032 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004033 if (g_instruction_table[instruction] == d68020_cpbcc_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004034 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004035 if (g_instruction_table[instruction] == d68020_cpdbcc)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004036 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004037 if (g_instruction_table[instruction] == d68020_cpgen)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004038 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004039 if (g_instruction_table[instruction] == d68020_cprestore)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004040 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004041 if (g_instruction_table[instruction] == d68020_cpsave)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004042 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004043 if (g_instruction_table[instruction] == d68020_cpscc)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004044 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004045 if (g_instruction_table[instruction] == d68020_cptrapcc_0)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004046 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004047 if (g_instruction_table[instruction] == d68020_cptrapcc_16)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004048 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004049 if (g_instruction_table[instruction] == d68020_cptrapcc_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004050 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004051 if (g_instruction_table[instruction] == d68020_divl)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004052 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004053 if (g_instruction_table[instruction] == d68020_extb_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004054 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004055 if (g_instruction_table[instruction] == d68020_link_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004056 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004057 if (g_instruction_table[instruction] == d68020_mull)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004058 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004059 if (g_instruction_table[instruction] == d68020_pack_rr)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004060 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004061 if (g_instruction_table[instruction] == d68020_pack_mm)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004062 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004063 if (g_instruction_table[instruction] == d68020_rtm)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004064 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004065 if (g_instruction_table[instruction] == d68020_trapcc_0)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004066 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004067 if (g_instruction_table[instruction] == d68020_trapcc_16)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004068 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004069 if (g_instruction_table[instruction] == d68020_trapcc_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004070 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004071 if (g_instruction_table[instruction] == d68020_tst_pcdi_8)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004072 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004073 if (g_instruction_table[instruction] == d68020_tst_pcix_8)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004074 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004075 if (g_instruction_table[instruction] == d68020_tst_i_8)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004076 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004077 if (g_instruction_table[instruction] == d68020_tst_a_16)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004078 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004079 if (g_instruction_table[instruction] == d68020_tst_pcdi_16)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004080 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004081 if (g_instruction_table[instruction] == d68020_tst_pcix_16)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004082 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004083 if (g_instruction_table[instruction] == d68020_tst_i_16)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004084 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004085 if (g_instruction_table[instruction] == d68020_tst_a_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004086 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004087 if (g_instruction_table[instruction] == d68020_tst_pcdi_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004088 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004089 if (g_instruction_table[instruction] == d68020_tst_pcix_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004090 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004091 if (g_instruction_table[instruction] == d68020_tst_i_32)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004092 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004093 if (g_instruction_table[instruction] == d68020_unpk_rr)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004094 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004095 if (g_instruction_table[instruction] == d68020_unpk_mm)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004096 return 0;
4097 case M68K_CPU_TYPE_68EC020:
4098 case M68K_CPU_TYPE_68020:
4099 case M68K_CPU_TYPE_68030:
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004100 if (g_instruction_table[instruction] == d68040_cinv)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004101 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004102 if (g_instruction_table[instruction] == d68040_cpush)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004103 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004104 if (g_instruction_table[instruction] == d68040_move16_pi_pi)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004105 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004106 if (g_instruction_table[instruction] == d68040_move16_pi_al)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004107 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004108 if (g_instruction_table[instruction] == d68040_move16_al_pi)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004109 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004110 if (g_instruction_table[instruction] == d68040_move16_ai_al)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004111 return 0;
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004112 if (g_instruction_table[instruction] == d68040_move16_al_ai)
Daniel Collin2ee675c2015-08-03 18:45:08 +02004113 return 0;
4114 }
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08004115
Nguyen Anh Quynh58fe7cd2015-10-05 16:05:17 +08004116 if (cpu_type != M68K_CPU_TYPE_68020 && cpu_type != M68K_CPU_TYPE_68EC020 &&
Nguyen Anh Quynhac63d5b2015-10-04 14:34:51 +08004117 (g_instruction_table[instruction] == d68020_callm ||
4118 g_instruction_table[instruction] == d68020_rtm))
Daniel Collin2ee675c2015-08-03 18:45:08 +02004119 return 0;
4120
4121 return 1;
4122}
Daniel Collinfc63aca2015-10-04 14:12:59 +02004123#endif
4124