Coverage Report

Created: 2025-10-10 06:20

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