Coverage Report

Created: 2025-10-28 07:02

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