Coverage Report

Created: 2026-03-03 06:15

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