Coverage Report

Created: 2025-08-29 06:29

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