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