Coverage Report

Created: 2026-01-09 06:55

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