Coverage Report

Created: 2025-12-14 06:36

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