Coverage Report

Created: 2026-03-13 06:50

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