Coverage Report

Created: 2026-03-03 06:15

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