Coverage Report

Created: 2026-03-03 06:14

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