Coverage Report

Created: 2025-12-14 06:36

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