Coverage Report

Created: 2025-11-09 07:00

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