Coverage Report

Created: 2025-10-12 06:32

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