Coverage Report

Created: 2025-11-11 06:33

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