[PATCH 8/9] target/m68k: Enable disassembly via capstone
Richard Henderson <[email protected]>
| Newsgroups | org.nongnu.qemu-devel,org.nongnu.qemu-riscv |
|---|---|
| Message-ID | <[email protected]> |
Signed-off-by: Richard Henderson <[email protected]> --- include/disas/capstone.h | 20 +++++++++++++ target/m68k/cpu.c | 65 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 1 deletion(-) 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 9ad3057d91..6acf23b29b 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 */ -- 2.43.0