Coverage Report

Created: 2026-04-12 06:30

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