Coverage Report

Created: 2025-11-16 06:38

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