Coverage Report

Created: 2026-02-26 07:11

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