Coverage Report

Created: 2026-03-13 06:50

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