Coverage Report

Created: 2023-12-08 06:05

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