Coverage Report

Created: 2025-11-24 06:12

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