Coverage Report

Created: 2026-01-09 06:55

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