Coverage Report

Created: 2025-10-10 06:20

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