Coverage Report

Created: 2026-01-10 06:34

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