Coverage Report

Created: 2026-01-12 07:13

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