Coverage Report

Created: 2026-03-11 06:06

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