Coverage Report

Created: 2026-04-12 06:30

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