Coverage Report

Created: 2026-01-17 06:58

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