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 */