Coverage Report

Created: 2025-07-09 06:32

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