Coverage Report

Created: 2025-11-16 06:38

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