Coverage Report

Created: 2025-11-09 07:00

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