Coverage Report

Created: 2025-11-24 06:12

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