Coverage Report

Created: 2026-01-10 06:34

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