target/m68k: Enable disassembly via capstone
Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Richard Henderson committed
Aug 8, 2026 at 16:12 UTC
89faaa51812765f1a8be59abe704bc88cfbdd17b
2 files changed
+84
-1
include/disas/capstone.h
+20
@@ -14,6 +14,7 @@
14
15
#define CS_ARCH_ARM -1
16
#define CS_ARCH_ARM64 -1
17
+#define CS_ARCH_M68K -1
18
#define CS_ARCH_MIPS -1
19
#define CS_ARCH_X86 -1
20
#define CS_ARCH_PPC -1
@@ -28,6 +29,12 @@
29
#define CS_MODE_THUMB 0
30
#define CS_MODE_MCLASS 0
31
#define CS_MODE_V8 0
32
+#define CS_MODE_M68K_000 0
33
+#define CS_MODE_M68K_010 0
34
+#define CS_MODE_M68K_020 0
35
+#define CS_MODE_M68K_030 0
36
+#define CS_MODE_M68K_040 0
37
+#define CS_MODE_M68K_060 0
38
#define CS_MODE_MICRO 0
39
#define CS_MODE_MIPS3 0
40
#define CS_MODE_MIPS32R6 0
@@ -44,6 +51,19 @@
51
#define CS_MODE_LOONGARCH64 0
52
#endif
53
54
+#if CS_API_MAJOR < 6
55
+#define CS_MODE_M68K_CF_ISA_A 0
56
+#define CS_MODE_M68K_CF_ISA_A_PLUS 0
57
+#define CS_MODE_M68K_CF_ISA_B 0
58
+#define CS_MODE_M68K_CF_ISA_C 0
59
+#define CS_MODE_M68K_CF_USP 0
60
+#define CS_MODE_M68K_CF_DIV 0
61
+#define CS_MODE_M68K_CF_MAC 0
62
+#define CS_MODE_M68K_CF_EMAC 0
63
+#define CS_MODE_M68K_CF_EMAC_B 0
64
+#define CS_MODE_M68K_CF_FPU 0
65
+#endif
66
+
67
#if CS_API_MAJOR < 5
68
#define CS_ARCH_RISCV -1
69
#define CS_MODE_RISCV32 0
target/m68k/cpu.c
+64
-1
@@ -22,7 +22,7 @@
22
#include "accel/tcg/cpu-ops.h"
23
#include "fpu/softfloat.h"
24
#include "qapi/error.h"
25
-
25
+#include "disas/capstone.h"
26
#ifndef CONFIG_USER_ONLY
27
#include "migration/vmstate.h"
28
#include "monitor/hmp.h"
@@ -182,9 +182,72 @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
182
183
static void m68k_cpu_disas_set_info(const CPUState *cs, disassemble_info *info)
184
{
185
+ CPUM68KState *env = cpu_env((CPUState *)cs);
186
+ int cap_mode = 0;
187
+
188
info->print_insn = print_insn_m68k;
189
info->endian = BFD_ENDIAN_BIG;
190
info->mach = 0;
191
+
192
+ /* m68k support in capstone prior to v6 is unusably bad */
193
+ if (CS_API_MAJOR < 6) {
194
+ return;
195
+ }
196
+
197
+ info->cap_arch = CS_ARCH_M68K;
198
+ info->cap_insn_unit = 2;
199
+
200
+ if (m68k_feature(env, M68K_FEATURE_M68K)) {
201
+ /*
202
+ * m68k insns may have up to 11 words, and 5 words are common.
203
+ * Choosing 12 bytes splits after 6 words and disassembly
204
+ * uses no more than 2 lines.
205
+ */
206
+ info->cap_insn_split = 12;
207
+ if (m68k_feature(env, M68K_FEATURE_M68060)) {
208
+ cap_mode = CS_MODE_M68K_060;
209
+ } else if (m68k_feature(env, M68K_FEATURE_M68040)) {
210
+ cap_mode = CS_MODE_M68K_040;
211
+ } else if (m68k_feature(env, M68K_FEATURE_M68030)) {
212
+ cap_mode = CS_MODE_M68K_030;
213
+ } else if (m68k_feature(env, M68K_FEATURE_M68020)) {
214
+ cap_mode = CS_MODE_M68K_020;
215
+ } else if (m68k_feature(env, M68K_FEATURE_M68010)) {
216
+ cap_mode = CS_MODE_M68K_010;
217
+ } else {
218
+ cap_mode = CS_MODE_M68K_000;
219
+ }
220
+ } else {
221
+ /* ColdFire insns may have up to 3 words. */
222
+ info->cap_insn_split = 6;
223
+ if (m68k_feature(env, M68K_FEATURE_CF_ISA_A)) {
224
+ cap_mode |= CS_MODE_M68K_CF_ISA_A;
225
+ cap_mode |= CS_MODE_M68K_CF_DIV;
226
+ }
227
+ if (m68k_feature(env, M68K_FEATURE_CF_ISA_B)) {
228
+ cap_mode |= CS_MODE_M68K_CF_ISA_B;
229
+ }
230
+ if (m68k_feature(env, M68K_FEATURE_CF_ISA_APLUSC)) {
231
+ cap_mode |= CS_MODE_M68K_CF_ISA_A_PLUS;
232
+ cap_mode |= CS_MODE_M68K_CF_ISA_C;
233
+ }
234
+ if (m68k_feature(env, M68K_FEATURE_USP)) {
235
+ cap_mode |= CS_MODE_M68K_CF_USP;
236
+ }
237
+ if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
238
+ cap_mode |= CS_MODE_M68K_CF_FPU;
239
+ }
240
+ if (m68k_feature(env, M68K_FEATURE_CF_MAC)) {
241
+ cap_mode |= CS_MODE_M68K_CF_MAC;
242
+ }
243
+ if (m68k_feature(env, M68K_FEATURE_CF_EMAC)) {
244
+ cap_mode |= CS_MODE_M68K_CF_EMAC;
245
+ }
246
+ if (m68k_feature(env, M68K_FEATURE_CF_EMAC_B)) {
247
+ cap_mode |= CS_MODE_M68K_CF_EMAC_B;
248
+ }
249
+ }
250
+ info->cap_mode = cap_mode;
251
}
252
253
/* CPU models */