Coverage Report

Created: 2026-02-26 07:11

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