Coverage Report

Created: 2025-10-12 06:32

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