Coverage Report

Created: 2025-12-05 06:11

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