Coverage Report

Created: 2025-10-14 06:42

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