/src/capstonenext/arch/M68K/M68KDisassembler.h
Line | Count | Source |
1 | | /* Capstone Disassembly Engine */ |
2 | | /* M68K Backend by Daniel Collin <daniel@collin.com> 2015-2016 */ |
3 | | |
4 | | #ifndef CS_M68KDISASSEMBLER_H |
5 | | #define CS_M68KDISASSEMBLER_H |
6 | | |
7 | | #include "../../MCInst.h" |
8 | | |
9 | | /* ======================================================================== */ |
10 | | /* ============================ GENERAL DEFINES =========================== */ |
11 | | /* ======================================================================== */ |
12 | | |
13 | | /* Bit Isolation Functions */ |
14 | 3.67k | #define BIT_0(A) ((A) & 0x00000001) |
15 | | #define BIT_1(A) ((A) & 0x00000002) |
16 | | #define BIT_2(A) ((A) & 0x00000004) |
17 | 0 | #define BIT_3(A) ((A) & 0x00000008) |
18 | | #define BIT_4(A) ((A) & 0x00000010) |
19 | 1.61k | #define BIT_5(A) ((A) & 0x00000020) |
20 | 11.7k | #define BIT_6(A) ((A) & 0x00000040) |
21 | 11.7k | #define BIT_7(A) ((A) & 0x00000080) |
22 | 26.9k | #define BIT_8(A) ((A) & 0x00000100) |
23 | | #define BIT_9(A) ((A) & 0x00000200) |
24 | 1.38k | #define BIT_A(A) ((A) & 0x00000400) |
25 | 25.9k | #define BIT_B(A) ((A) & 0x00000800) |
26 | | #define BIT_C(A) ((A) & 0x00001000) |
27 | | #define BIT_D(A) ((A) & 0x00002000) |
28 | | #define BIT_E(A) ((A) & 0x00004000) |
29 | 28.4k | #define BIT_F(A) ((A) & 0x00008000) |
30 | | #define BIT_10(A) ((A) & 0x00010000) |
31 | | #define BIT_11(A) ((A) & 0x00020000) |
32 | | #define BIT_12(A) ((A) & 0x00040000) |
33 | | #define BIT_13(A) ((A) & 0x00080000) |
34 | | #define BIT_14(A) ((A) & 0x00100000) |
35 | | #define BIT_15(A) ((A) & 0x00200000) |
36 | | #define BIT_16(A) ((A) & 0x00400000) |
37 | | #define BIT_17(A) ((A) & 0x00800000) |
38 | | #define BIT_18(A) ((A) & 0x01000000) |
39 | | #define BIT_19(A) ((A) & 0x02000000) |
40 | | #define BIT_1A(A) ((A) & 0x04000000) |
41 | | #define BIT_1B(A) ((A) & 0x08000000) |
42 | | #define BIT_1C(A) ((A) & 0x10000000) |
43 | | #define BIT_1D(A) ((A) & 0x20000000) |
44 | | #define BIT_1E(A) ((A) & 0x40000000) |
45 | 1.21k | #define BIT_1F(A) ((A) & 0x80000000) |
46 | | |
47 | | /* These are the M68K feature masks understood by this disassembler. */ |
48 | | #define M68000_ONLY CS_MODE_M68K_000 |
49 | | |
50 | | #define M68010_ONLY CS_MODE_M68K_010 |
51 | 344k | #define M68010_LESS (CS_MODE_M68K_000 | CS_MODE_M68K_010) |
52 | | #define M68010_PLUS \ |
53 | | (CS_MODE_M68K_010 | CS_MODE_M68K_020 | CS_MODE_M68K_030 | \ |
54 | | CS_MODE_M68K_040 | CS_MODE_M68K_060) |
55 | | |
56 | | #define M68020_ONLY CS_MODE_M68K_020 |
57 | | #define M68020_LESS (CS_MODE_M68K_010 | CS_MODE_M68K_020) |
58 | | #define M68020_PLUS \ |
59 | | (CS_MODE_M68K_020 | CS_MODE_M68K_030 | CS_MODE_M68K_040 | \ |
60 | | CS_MODE_M68K_060) |
61 | | |
62 | | #define M68030_ONLY CS_MODE_M68K_030 |
63 | | #define M68030_LESS (CS_MODE_M68K_010 | CS_MODE_M68K_020 | CS_MODE_M68K_030) |
64 | | #define M68030_PLUS (CS_MODE_M68K_030 | CS_MODE_M68K_040 | CS_MODE_M68K_060) |
65 | | |
66 | 640 | #define M68040_PLUS (CS_MODE_M68K_040 | CS_MODE_M68K_060) |
67 | | |
68 | | typedef uint32_t m68k_feature_mask; |
69 | | |
70 | | /* Extension word formats */ |
71 | | #define EXT_8BIT_DISPLACEMENT(A) ((A) & 0xff) |
72 | 26.9k | #define EXT_FULL(A) BIT_8(A) |
73 | | #define EXT_EFFECTIVE_ZERO(A) (((A) & 0xe4) == 0xc4 || ((A) & 0xe2) == 0xc0) |
74 | 11.7k | #define EXT_BASE_REGISTER_PRESENT(A) (!BIT_7(A)) |
75 | 11.7k | #define EXT_INDEX_REGISTER_PRESENT(A) (!BIT_6(A)) |
76 | 22.1k | #define EXT_INDEX_REGISTER(A) (((A) >> 12) & 7) |
77 | | #define EXT_INDEX_PRE_POST(A) (EXT_INDEX_REGISTER_PRESENT(A) && (A) & 3) |
78 | | #define EXT_INDEX_PRE(A) \ |
79 | | (EXT_INDEX_REGISTER_PRESENT(A) && ((A) & 7) < 4 && ((A) & 7) != 0) |
80 | | #define EXT_INDEX_POST(A) (EXT_INDEX_REGISTER_PRESENT(A) && ((A) & 7) > 4) |
81 | 36.8k | #define EXT_INDEX_SCALE(A) (((A) >> 9) & 3) |
82 | 22.1k | #define EXT_INDEX_LONG(A) BIT_B(A) |
83 | 22.1k | #define EXT_INDEX_AR(A) BIT_F(A) |
84 | 35.2k | #define EXT_BASE_DISPLACEMENT_PRESENT(A) (((A) & 0x30) > 0x10) |
85 | | #define EXT_BASE_DISPLACEMENT_WORD(A) (((A) & 0x30) == 0x20) |
86 | 13.4k | #define EXT_BASE_DISPLACEMENT_LONG(A) (((A) & 0x30) == 0x30) |
87 | | /* Outer displacement is present when I/IS[1:0] (bits 1-0) is 2 (word) or 3 (long). |
88 | | * This applies regardless of the IS bit (bit 6): when index is suppressed, |
89 | | * I/IS values 5-7 mirror 1-3 (just indirect instead of postindexed). |
90 | | * The old check ((A) & 0x47) < 0x44 incorrectly excluded IS=1 cases |
91 | | * (I/IS=6,7) which DO have outer displacements per the M68K spec. |
92 | | */ |
93 | 35.2k | #define EXT_OUTER_DISPLACEMENT_PRESENT(A) (((A) & 3) > 1) |
94 | | #define EXT_OUTER_DISPLACEMENT_WORD(A) (((A) & 3) == 2) |
95 | 6.32k | #define EXT_OUTER_DISPLACEMENT_LONG(A) (((A) & 3) == 3) |
96 | | |
97 | | #define IS_BITSET(val, b) ((val) & (1 << (b))) |
98 | 13.1k | #define BITFIELD_MASK(sb, eb) (((1 << ((sb) + 1)) - 1) & (~((1 << (eb)) - 1))) |
99 | 13.1k | #define BITFIELD(val, sb, eb) ((BITFIELD_MASK(sb, eb) & (val)) >> (eb)) |
100 | | |
101 | | /* Bitfield offset/width encoding. |
102 | | * Public decode macros (M68K_BF_*) live in <capstone/m68k.h>. |
103 | | * Internal aliases kept for brevity within arch code. */ |
104 | | #define M68K_BITFIELD_REG_FLAG M68K_BF_REG_FLAG |
105 | | #define M68K_BITFIELD_IS_REG(v) M68K_BF_IS_REG(v) |
106 | | #define M68K_BITFIELD_REG_NUM(v) M68K_BF_REG_NUM(v) |
107 | 1.46k | #define M68K_BITFIELD_ENCODE_REG(regnum) (((regnum) & 7) | M68K_BF_REG_FLAG) |
108 | | |
109 | | /* ── Coprocessor ID (CpID) ─────────────────────────────────────────── |
110 | | * Bits 11:9 of the F-line instruction word select the coprocessor. */ |
111 | 33.4k | #define M68K_CPID(info) (((info)->ir >> 9) & 7) |
112 | | |
113 | 27.7k | #define M68K_CPID_MMU 0 /* PMMU (68030/68851) */ |
114 | 19.8k | #define M68K_CPID_FPU 1 /* FPU (68881/68882/internal) */ |
115 | 1.87k | #define M68K_CPID_CACHE 2 /* Cache ops -- cinvl/cpushl on 68040+ */ |
116 | | |
117 | | /* ── IR bit-field helpers ──────────────────────────────────────────── |
118 | | * Extract commonly-used fields from the first instruction word. */ |
119 | | |
120 | | /* Coprocessor conditional predicate field (bits 5:0). |
121 | | * |
122 | | * Reference: Motorola MC68881/MC68882 Floating-Point Coprocessor User's |
123 | | * Manual, first edition (1987), sections 4.7.2-4.7.3, Tables 4-20 and |
124 | | * 4-22, pages 4-129 through 4-134. A reference copy is available at: |
125 | | * https://www.bitsavers.org/components/motorola/68000/68020/MC68881_MC68882_Floating-Point_Coprocessor_Users_Manual_1ed_1987.pdf |
126 | | */ |
127 | 6.23k | #define M68K_COPROCESSOR_CONDITION_MASK 0x3f |
128 | | |
129 | | static inline uint32_t m68k_coprocessor_condition(uint32_t word) |
130 | 6.23k | { |
131 | 6.23k | return word & M68K_COPROCESSOR_CONDITION_MASK; |
132 | 6.23k | } Unexecuted instantiation: M68KModule.c:m68k_coprocessor_condition M68KDisassembler.c:m68k_coprocessor_condition Line | Count | Source | 130 | 6.23k | { | 131 | 6.23k | return word & M68K_COPROCESSOR_CONDITION_MASK; | 132 | 6.23k | } |
Unexecuted instantiation: M68KInstPrinter.c:m68k_coprocessor_condition |
133 | | |
134 | | /* 4-bit condition selector used by Bcc/DBcc/Scc/TRAPcc. */ |
135 | 17.6k | #define M68K_IR_CONDITION_NIBBLE(info) (((info)->ir >> 8) & 0xf) |
136 | 0 | #define M68K_CONDITION_FALSE 1 |
137 | | |
138 | | /* cinv/cpush: select cpush(1) vs cinv(0) -- bit 5 of IR. */ |
139 | 102 | #define M68K_IR_IS_CPUSH(info) (((info)->ir >> 5) & 1) |
140 | | |
141 | | /* cinv/cpush: cache scope -- bits 4:3 of IR (0=invalid,1=line,2=page,3=all). */ |
142 | 2.15k | #define M68K_IR_CACHE_SCOPE(info) (((info)->ir >> 3) & 3) |
143 | | |
144 | | /* cinv/cpush: cache selector -- bits 7:6 of IR (DC/IC/BC). */ |
145 | 1.76k | #define M68K_IR_CACHE_SEL(info) (((info)->ir >> 6) & 3) |
146 | | |
147 | | /* ── FPU extension-word bit-field helpers ──────────────────────────── |
148 | | * The FPU command word is the 16-bit extension following the F-line. */ |
149 | | |
150 | | /* R/M bit (bit 14): 1 = source from EA, 0 = source from FP register. */ |
151 | 7.34k | #define M68K_FEXT_RM(ext) (((ext) >> 14) & 1) |
152 | | |
153 | | /* Type / command class (bits 15:13). */ |
154 | 14.3k | #define M68K_FEXT_TYPE(ext) (((ext) >> 13) & 7) |
155 | | |
156 | | /* Source specifier (bits 12:10) -- data format when R/M=1. */ |
157 | 7.34k | #define M68K_FEXT_SRC(ext) (((ext) >> 10) & 7) |
158 | | |
159 | | /* Destination FP register (bits 9:7). */ |
160 | 7.68k | #define M68K_FEXT_DST(ext) (((ext) >> 7) & 7) |
161 | | |
162 | | /* Opmode (bits 5:0) -- FPU operation selector. */ |
163 | 7.68k | #define M68K_FEXT_OPMODE(ext) ((ext) & 0x3f) |
164 | | |
165 | | /* Single/double precision flag (bit 6) -- 68040+ only. */ |
166 | 13.4k | #define M68K_FEXT_SD_FLAG(ext) (((ext) >> 6) & 1) |
167 | | |
168 | | /* FMOVECR signature: bits 15:10 == 0x17 (010111b). */ |
169 | 1.50k | #define M68K_FEXT_IS_FMOVECR(ext) (BITFIELD((ext), 15, 10) == 0x17) |
170 | | |
171 | | /* Register-select field for FMOVE to/from FPCR/FPSR/FPIAR (bits 12:10). */ |
172 | 506 | #define M68K_FEXT_REGSEL(ext) (((ext) >> 10) & 7) |
173 | | |
174 | | /* Direction bit for FMOVE FPCR (bit 13): 0 = ea->fpcr, 1 = fpcr->ea. */ |
175 | 2.81k | #define M68K_FEXT_DIR(ext) (((ext) >> 13) & 1) |
176 | | |
177 | | /* FMOVEM register-list encoding. |
178 | | * |
179 | | * Bits 12:11 select static/dynamic and predecrement versus |
180 | | * postincrement-or-control forms. A static list occupies bits 7:0; a dynamic |
181 | | * list has the reserved-bit format 0rrr0000, with Dn in bits 6:4. |
182 | | * |
183 | | * Reference: Motorola MC68881/MC68882 Floating-Point Coprocessor User's |
184 | | * Manual, first edition (1987), section 4.7.1.6, Table 4-18, pages 4-126 |
185 | | * through 4-128: |
186 | | * https://www.bitsavers.org/components/motorola/68000/68020/MC68881_MC68882_Floating-Point_Coprocessor_Users_Manual_1ed_1987.pdf |
187 | | */ |
188 | | typedef enum { |
189 | | M68K_FMOVEM_MODE_STATIC_PREDECREMENT = 0, |
190 | | M68K_FMOVEM_MODE_DYNAMIC_PREDECREMENT = 1, |
191 | | M68K_FMOVEM_MODE_STATIC_POSTINCREMENT_OR_CONTROL = 2, |
192 | | M68K_FMOVEM_MODE_DYNAMIC_POSTINCREMENT_OR_CONTROL = 3, |
193 | | } m68k_fmovem_mode; |
194 | | |
195 | | static inline m68k_fmovem_mode m68k_fmovem_get_mode(uint32_t extension) |
196 | 1.76k | { |
197 | 1.76k | return (m68k_fmovem_mode)BITFIELD(extension, 12, 11); |
198 | 1.76k | } Unexecuted instantiation: M68KModule.c:m68k_fmovem_get_mode M68KDisassembler.c:m68k_fmovem_get_mode Line | Count | Source | 196 | 1.76k | { | 197 | 1.76k | return (m68k_fmovem_mode)BITFIELD(extension, 12, 11); | 198 | 1.76k | } |
Unexecuted instantiation: M68KInstPrinter.c:m68k_fmovem_get_mode |
199 | | |
200 | | static inline uint32_t m68k_fmovem_register_list(uint32_t extension) |
201 | 881 | { |
202 | 881 | return BITFIELD(extension, 7, 0); |
203 | 881 | } Unexecuted instantiation: M68KModule.c:m68k_fmovem_register_list M68KDisassembler.c:m68k_fmovem_register_list Line | Count | Source | 201 | 881 | { | 202 | 881 | return BITFIELD(extension, 7, 0); | 203 | 881 | } |
Unexecuted instantiation: M68KInstPrinter.c:m68k_fmovem_register_list |
204 | | |
205 | | static inline bool |
206 | | m68k_fmovem_dynamic_reserved_bits_are_zero(uint32_t extension) |
207 | 259 | { |
208 | 259 | return BITFIELD(extension, 7, 7) == 0 && BITFIELD(extension, 3, 0) == 0; |
209 | 259 | } Unexecuted instantiation: M68KModule.c:m68k_fmovem_dynamic_reserved_bits_are_zero M68KDisassembler.c:m68k_fmovem_dynamic_reserved_bits_are_zero Line | Count | Source | 207 | 259 | { | 208 | 259 | return BITFIELD(extension, 7, 7) == 0 && BITFIELD(extension, 3, 0) == 0; | 209 | 259 | } |
Unexecuted instantiation: M68KInstPrinter.c:m68k_fmovem_dynamic_reserved_bits_are_zero |
210 | | |
211 | | static inline uint32_t m68k_fmovem_dynamic_register(uint32_t extension) |
212 | 248 | { |
213 | 248 | return BITFIELD(extension, 6, 4); |
214 | 248 | } Unexecuted instantiation: M68KModule.c:m68k_fmovem_dynamic_register M68KDisassembler.c:m68k_fmovem_dynamic_register Line | Count | Source | 212 | 248 | { | 213 | 248 | return BITFIELD(extension, 6, 4); | 214 | 248 | } |
Unexecuted instantiation: M68KInstPrinter.c:m68k_fmovem_dynamic_register |
215 | | |
216 | | /* ── FPU condition-code mask ───────────────────────────────────────── |
217 | | * The FPU defines predicates 0xxxxx; 1xxxxx encodings are reserved |
218 | | * aliases that evaluate identically. Use the low five bits to index the |
219 | | * contiguous FBcc/FDBcc/FScc/FTRAPcc opcode ranges. See the manual |
220 | | * reference above. */ |
221 | 5.14k | #define M68K_FPU_CONDITION_INDEX_MASK 0x1f |
222 | | |
223 | | static inline uint32_t m68k_fpu_condition_index(uint32_t word) |
224 | 5.14k | { |
225 | 5.14k | return word & M68K_FPU_CONDITION_INDEX_MASK; |
226 | 5.14k | } Unexecuted instantiation: M68KModule.c:m68k_fpu_condition_index M68KDisassembler.c:m68k_fpu_condition_index Line | Count | Source | 224 | 5.14k | { | 225 | 5.14k | return word & M68K_FPU_CONDITION_INDEX_MASK; | 226 | 5.14k | } |
Unexecuted instantiation: M68KInstPrinter.c:m68k_fpu_condition_index |
227 | | |
228 | | /* Maximum valid condition codes per coprocessor. */ |
229 | 3.90k | #define M68K_PMMU_MAX_COND 16 |
230 | | |
231 | | /* ── FPU source-format constants (bits 12:10 of ext word) ───────────*/ |
232 | 203 | #define M68K_FPSRC_LONG 0x00 /* .l -- 32-bit integer */ |
233 | 799 | #define M68K_FPSRC_SINGLE 0x01 /* .s -- 32-bit IEEE single */ |
234 | 226 | #define M68K_FPSRC_EXTENDED 0x02 /* .x -- 96-bit extended real */ |
235 | 70 | #define M68K_FPSRC_PACKED 0x03 /* .p -- 96-bit packed decimal */ |
236 | 123 | #define M68K_FPSRC_WORD 0x04 /* .w -- 16-bit integer */ |
237 | 157 | #define M68K_FPSRC_DOUBLE 0x05 /* .d -- 64-bit IEEE double */ |
238 | 616 | #define M68K_FPSRC_BYTE 0x06 /* .b -- 8-bit integer */ |
239 | | |
240 | | /* ── FPU special raw opmodes (before SD-flag masking) ─────────────── |
241 | | * FSSQRT/FDSQRT have raw 7-bit opmodes 0x41/0x45. After the 6-bit |
242 | | * truncation (& 0x3f) they become 0x01/0x05 with the SD flag set. */ |
243 | 2.24k | #define M68K_FPOP_FSSQRT_RAW 0x01 /* 0x41 & 0x3f */ |
244 | 2.13k | #define M68K_FPOP_FDSQRT_RAW 0x05 /* 0x45 & 0x3f */ |
245 | | |
246 | | /* ── Feature guard macros ──────────────────────────────────────────── |
247 | | * These reference the `info` parameter available at each call site. |
248 | | * They early-return from the calling function on guard mismatch. */ |
249 | | |
250 | | #define LIMIT_FEATURE(info, FEATURES) \ |
251 | 85.9k | do { \ |
252 | 85.9k | if (!m68k_has_feature(info, FEATURES)) { \ |
253 | 46.3k | d68000_invalid(info); \ |
254 | 46.3k | return; \ |
255 | 46.3k | } \ |
256 | 85.9k | } while (0) |
257 | | |
258 | | /* Like LIMIT_FEATURE but also reverses the instruction word consumption, |
259 | | * so the invalid instruction produces size=0 (not decoded) instead of size=2. |
260 | | * Use for handlers that replace d68000_invalid in the dispatch table. */ |
261 | | #define LIMIT_FEATURE_UNDECODED(info, FEATURES) \ |
262 | 4 | do { \ |
263 | 4 | if (!m68k_has_feature(info, FEATURES)) { \ |
264 | 4 | info->pc -= 2; \ |
265 | 4 | d68000_invalid(info); \ |
266 | 4 | return; \ |
267 | 4 | } \ |
268 | 4 | } while (0) |
269 | | |
270 | | /* Like LIMIT_FEATURE but also rejects a feature subset. CPU32 implies 68020 |
271 | | * but lacks some 68020 instructions (CAS, CAS2, CHK.L, PACK, UNPK). */ |
272 | | #define LIMIT_FEATURE_EXCLUDING(info, FEATURES, EXCLUDED_FEATURES) \ |
273 | 13.6k | do { \ |
274 | 13.6k | if (!m68k_has_feature(info, FEATURES) || \ |
275 | 13.6k | m68k_has_feature(info, EXCLUDED_FEATURES)) { \ |
276 | 4.97k | d68000_invalid(info); \ |
277 | 4.97k | return; \ |
278 | 4.97k | } \ |
279 | 13.6k | } while (0) |
280 | | |
281 | | /* Require CpID == FPU. Rejects all other coprocessor IDs. |
282 | | * Used by cpDBcc, cpScc, cpTRAPcc handlers. */ |
283 | | #define REQUIRE_CPID_FPU(info) \ |
284 | 4.78k | do { \ |
285 | 4.78k | if (M68K_CPID(info) != M68K_CPID_FPU) { \ |
286 | 2.35k | d68000_invalid(info); \ |
287 | 2.35k | return; \ |
288 | 2.35k | } \ |
289 | 4.78k | } while (0) |
290 | | |
291 | | /* ── EA / immediate convenience aliases ───────────────────────────── |
292 | | * Shorthand wrappers around the sized get_ea_mode_str / get_imm_str |
293 | | * functions. These expand at the call site where 'info' is in scope. */ |
294 | | |
295 | | /* Fake a split interface */ |
296 | | #define get_ea_mode_str_8(instruction) get_ea_mode_str(instruction, 0) |
297 | | #define get_ea_mode_str_16(instruction) get_ea_mode_str(instruction, 1) |
298 | | #define get_ea_mode_str_32(instruction) get_ea_mode_str(instruction, 2) |
299 | | |
300 | | #define get_imm_str_s8() get_imm_str_s(0) |
301 | | #define get_imm_str_s16() get_imm_str_s(1) |
302 | | #define get_imm_str_s32() get_imm_str_s(2) |
303 | | |
304 | | #define get_imm_str_u8() get_imm_str_u(0) |
305 | | #define get_imm_str_u16() get_imm_str_u(1) |
306 | | #define get_imm_str_u32() get_imm_str_u(2) |
307 | | |
308 | | /* ── Operand access shorthands ────────────────────────────────────── |
309 | | * Quick access to the operand array and instruction size via `info`. */ |
310 | | #define IOPS(I) (&info->extension.operands[(I)]) |
311 | 5.21k | #define ISIZE (info->extension.op_size.cpu_size) |
312 | | |
313 | | /* ======================================================================== */ |
314 | | /* ============================ INTERNAL TYPES ============================ */ |
315 | | /* ======================================================================== */ |
316 | | |
317 | | /* Private, For internal use only */ |
318 | | typedef struct m68k_info { |
319 | | const uint8_t *code; |
320 | | size_t code_len; |
321 | | uint64_t baseAddress; |
322 | | MCInst *inst; |
323 | | uint32_t pc; /* program counter */ |
324 | | uint32_t ir; /* instruction register */ |
325 | | m68k_feature_mask features; |
326 | | uint32_t address_mask; /* Address mask to simulate address lines */ |
327 | | cs_m68k extension; |
328 | | uint16_t regs_read |
329 | | [MAX_IMPL_R_REGS]; // list of implicit registers read by this insn |
330 | | uint8_t regs_read_count; // number of implicit registers read by this insn |
331 | | uint16_t regs_write |
332 | | [MAX_IMPL_W_REGS]; // list of implicit registers modified by this insn |
333 | | uint8_t regs_write_count; // number of implicit registers modified by this insn |
334 | | uint8_t groups[MAX_NUM_GROUPS]; |
335 | | uint8_t groups_count; |
336 | | } m68k_info; |
337 | | |
338 | | static inline bool m68k_has_feature(const m68k_info *info, |
339 | | m68k_feature_mask features) |
340 | 463k | { |
341 | 463k | m68k_feature_mask available = info->features; |
342 | | |
343 | 463k | if (available & CS_MODE_M68K_CPU32) |
344 | 0 | available |= CS_MODE_M68K_020; |
345 | 463k | if (available & CS_MODE_M68K_CF_ISA_A_PLUS) |
346 | 0 | available |= CS_MODE_M68K_CF_ISA_A; |
347 | 463k | if (available & CS_MODE_M68K_CF_ISA_B) |
348 | 0 | available |= CS_MODE_M68K_CF_ISA_A | CS_MODE_M68K_CF_ISA_A_PLUS; |
349 | 463k | if (available & CS_MODE_M68K_CF_ISA_C) |
350 | 0 | available |= CS_MODE_M68K_CF_ISA_A; |
351 | 463k | if (available & CS_MODE_M68K_CF_EMAC) |
352 | 0 | available |= CS_MODE_M68K_CF_MAC; |
353 | 463k | if (available & CS_MODE_M68K_CF_EMAC_B) |
354 | 0 | available |= CS_MODE_M68K_CF_EMAC | CS_MODE_M68K_CF_MAC; |
355 | | |
356 | 463k | return (available & features) != 0; |
357 | 463k | } Unexecuted instantiation: M68KModule.c:m68k_has_feature M68KDisassembler.c:m68k_has_feature Line | Count | Source | 340 | 463k | { | 341 | 463k | m68k_feature_mask available = info->features; | 342 | | | 343 | 463k | if (available & CS_MODE_M68K_CPU32) | 344 | 0 | available |= CS_MODE_M68K_020; | 345 | 463k | if (available & CS_MODE_M68K_CF_ISA_A_PLUS) | 346 | 0 | available |= CS_MODE_M68K_CF_ISA_A; | 347 | 463k | if (available & CS_MODE_M68K_CF_ISA_B) | 348 | 0 | available |= CS_MODE_M68K_CF_ISA_A | CS_MODE_M68K_CF_ISA_A_PLUS; | 349 | 463k | if (available & CS_MODE_M68K_CF_ISA_C) | 350 | 0 | available |= CS_MODE_M68K_CF_ISA_A; | 351 | 463k | if (available & CS_MODE_M68K_CF_EMAC) | 352 | 0 | available |= CS_MODE_M68K_CF_MAC; | 353 | 463k | if (available & CS_MODE_M68K_CF_EMAC_B) | 354 | 0 | available |= CS_MODE_M68K_CF_EMAC | CS_MODE_M68K_CF_MAC; | 355 | | | 356 | 463k | return (available & features) != 0; | 357 | 463k | } |
Unexecuted instantiation: M68KInstPrinter.c:m68k_has_feature |
358 | | |
359 | | bool M68K_getInstruction(csh ud, const uint8_t *code, size_t code_len, |
360 | | MCInst *instr, uint16_t *size, uint64_t address, |
361 | | void *info); |
362 | | |
363 | | #endif |