Coverage Report

Created: 2026-01-17 06:58

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