Coverage Report

Created: 2024-09-08 06:22

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