Commit 89faaa5181 for qemu.org

commit 89faaa51812765f1a8be59abe704bc88cfbdd17b
Author: Richard Henderson <richard.henderson@linaro.org>
Date:   Sat Aug 8 16:12:43 2026 -0700

    target/m68k: Enable disassembly via capstone

    Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
    Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

diff --git a/include/disas/capstone.h b/include/disas/capstone.h
index 87f8f6181f..3d6f90d816 100644
--- a/include/disas/capstone.h
+++ b/include/disas/capstone.h
@@ -14,6 +14,7 @@

 #define CS_ARCH_ARM     -1
 #define CS_ARCH_ARM64   -1
+#define CS_ARCH_M68K    -1
 #define CS_ARCH_MIPS    -1
 #define CS_ARCH_X86     -1
 #define CS_ARCH_PPC     -1
@@ -28,6 +29,12 @@
 #define CS_MODE_THUMB            0
 #define CS_MODE_MCLASS           0
 #define CS_MODE_V8               0
+#define CS_MODE_M68K_000         0
+#define CS_MODE_M68K_010         0
+#define CS_MODE_M68K_020         0
+#define CS_MODE_M68K_030         0
+#define CS_MODE_M68K_040         0
+#define CS_MODE_M68K_060         0
 #define CS_MODE_MICRO            0
 #define CS_MODE_MIPS3            0
 #define CS_MODE_MIPS32R6         0
@@ -44,6 +51,19 @@
 #define CS_MODE_LOONGARCH64      0
 #endif

+#if CS_API_MAJOR < 6
+#define CS_MODE_M68K_CF_ISA_A    0
+#define CS_MODE_M68K_CF_ISA_A_PLUS 0
+#define CS_MODE_M68K_CF_ISA_B    0
+#define CS_MODE_M68K_CF_ISA_C    0
+#define CS_MODE_M68K_CF_USP      0
+#define CS_MODE_M68K_CF_DIV      0
+#define CS_MODE_M68K_CF_MAC      0
+#define CS_MODE_M68K_CF_EMAC     0
+#define CS_MODE_M68K_CF_EMAC_B   0
+#define CS_MODE_M68K_CF_FPU      0
+#endif
+
 #if CS_API_MAJOR < 5
 #define CS_ARCH_RISCV           -1
 #define CS_MODE_RISCV32          0
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index ce2707dee5..6012dc3186 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -22,7 +22,7 @@
 #include "accel/tcg/cpu-ops.h"
 #include "fpu/softfloat.h"
 #include "qapi/error.h"
-
+#include "disas/capstone.h"
 #ifndef CONFIG_USER_ONLY
 #include "migration/vmstate.h"
 #include "monitor/hmp.h"
@@ -182,9 +182,72 @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)

 static void m68k_cpu_disas_set_info(const CPUState *cs, disassemble_info *info)
 {
+    CPUM68KState *env = cpu_env((CPUState *)cs);
+    int cap_mode = 0;
+
     info->print_insn = print_insn_m68k;
     info->endian = BFD_ENDIAN_BIG;
     info->mach = 0;
+
+    /* m68k support in capstone prior to v6 is unusably bad */
+    if (CS_API_MAJOR < 6) {
+        return;
+    }
+
+    info->cap_arch = CS_ARCH_M68K;
+    info->cap_insn_unit = 2;
+
+    if (m68k_feature(env, M68K_FEATURE_M68K)) {
+        /*
+         * m68k insns may have up to 11 words, and 5 words are common.
+         * Choosing 12 bytes splits after 6 words and disassembly
+         * uses no more than 2 lines.
+         */
+        info->cap_insn_split = 12;
+        if (m68k_feature(env, M68K_FEATURE_M68060)) {
+            cap_mode = CS_MODE_M68K_060;
+        } else if (m68k_feature(env, M68K_FEATURE_M68040)) {
+            cap_mode = CS_MODE_M68K_040;
+        } else if (m68k_feature(env, M68K_FEATURE_M68030)) {
+            cap_mode = CS_MODE_M68K_030;
+        } else if (m68k_feature(env, M68K_FEATURE_M68020)) {
+            cap_mode = CS_MODE_M68K_020;
+        } else if (m68k_feature(env, M68K_FEATURE_M68010)) {
+            cap_mode = CS_MODE_M68K_010;
+        } else {
+            cap_mode = CS_MODE_M68K_000;
+        }
+    } else {
+        /* ColdFire insns may have up to 3 words. */
+        info->cap_insn_split = 6;
+        if (m68k_feature(env, M68K_FEATURE_CF_ISA_A)) {
+            cap_mode |= CS_MODE_M68K_CF_ISA_A;
+            cap_mode |= CS_MODE_M68K_CF_DIV;
+        }
+        if (m68k_feature(env, M68K_FEATURE_CF_ISA_B)) {
+            cap_mode |= CS_MODE_M68K_CF_ISA_B;
+        }
+        if (m68k_feature(env, M68K_FEATURE_CF_ISA_APLUSC)) {
+            cap_mode |= CS_MODE_M68K_CF_ISA_A_PLUS;
+            cap_mode |= CS_MODE_M68K_CF_ISA_C;
+        }
+        if (m68k_feature(env, M68K_FEATURE_USP)) {
+            cap_mode |= CS_MODE_M68K_CF_USP;
+        }
+        if (m68k_feature(env, M68K_FEATURE_CF_FPU)) {
+            cap_mode |= CS_MODE_M68K_CF_FPU;
+        }
+        if (m68k_feature(env, M68K_FEATURE_CF_MAC)) {
+            cap_mode |= CS_MODE_M68K_CF_MAC;
+        }
+        if (m68k_feature(env, M68K_FEATURE_CF_EMAC)) {
+            cap_mode |= CS_MODE_M68K_CF_EMAC;
+        }
+        if (m68k_feature(env, M68K_FEATURE_CF_EMAC_B)) {
+            cap_mode |= CS_MODE_M68K_CF_EMAC_B;
+        }
+    }
+    info->cap_mode = cap_mode;
 }

 /* CPU models */