Coverage Report

Created: 2025-12-05 06:11

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