Coverage Report

Created: 2025-10-28 07:02

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