Coverage Report

Created: 2025-11-11 06:33

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