Coverage Report

Created: 2025-08-28 06:43

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