Coverage Report

Created: 2026-01-12 07:13

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