Coverage Report

Created: 2025-07-01 07:03

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