[PATCH 9/9] target/mips: 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 | 24 ++++++++++++++-- target/mips/cpu.c | 60 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 77 insertions(+), 7 deletions(-) diff --git a/include/disas/capstone.h b/include/disas/capstone.h index 3d6f90d816..e72faf8179 100644 --- a/include/disas/capstone.h +++ b/include/disas/capstone.h @@ -29,6 +29,7 @@ #define CS_MODE_THUMB 0 #define CS_MODE_MCLASS 0 #define CS_MODE_V8 0 +#define CS_MODE_V9 0 #define CS_MODE_M68K_000 0 #define CS_MODE_M68K_010 0 #define CS_MODE_M68K_020 0 @@ -36,11 +37,10 @@ #define CS_MODE_M68K_040 0 #define CS_MODE_M68K_060 0 #define CS_MODE_MICRO 0 +#define CS_MODE_MIPS2 0 #define CS_MODE_MIPS3 0 -#define CS_MODE_MIPS32R6 0 -#define CS_MODE_MIPSGP64 0 -#define CS_MODE_V9 0 #define CS_MODE_MIPS32 0 +#define CS_MODE_MIPS32R6 0 #define CS_MODE_MIPS64 0 #endif /* CONFIG_CAPSTONE */ @@ -64,6 +64,24 @@ #define CS_MODE_M68K_CF_FPU 0 #endif +#if CS_API_MAJOR < 6 +#define CS_MODE_MIPS16 0 +#define CS_MODE_MIPS1 0 +#define CS_MODE_MIPS32R2 0 +#define CS_MODE_MIPS32R3 0 +#define CS_MODE_MIPS32R5 0 +#define CS_MODE_MIPS4 0 +#define CS_MODE_MIPS5 0 +#define CS_MODE_MIPS64R2 0 +#define CS_MODE_MIPS64R3 0 +#define CS_MODE_MIPS64R5 0 +#define CS_MODE_MIPS64R6 0 +#define CS_MODE_OCTEON 0 +#define CS_MODE_OCTEONP 0 +#define CS_MODE_NANOMIPS 0 +#define CS_MODE_MIPS_PTR64 0 +#endif + #if CS_API_MAJOR < 5 #define CS_ARCH_RISCV -1 #define CS_MODE_RISCV32 0 diff --git a/target/mips/cpu.c b/target/mips/cpu.c index d72044aef6..7c1e4827b9 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c @@ -30,6 +30,7 @@ #include "system/qtest.h" #include "hw/core/qdev-properties.h" #include "hw/core/qdev-clock.h" +#include "disas/capstone.h" #include "fpu_helper.h" #ifndef CONFIG_USER_ONLY #include "semihosting/semihost.h" @@ -488,15 +489,66 @@ static void mips_cpu_disas_set_info(const CPUState *cs, disassemble_info *info) { const MIPSCPU *cpu = MIPS_CPU(cs); const CPUMIPSState *env = &cpu->env; + bool is64 = env->hflags & MIPS_HFLAG_64; + int cap_mode = 0; - if (!(env->insn_flags & ISA_NANOMIPS32)) { + if (env->insn_flags & ISA_NANOMIPS32) { + info->print_insn = print_insn_nanomips; + info->endian = BFD_ENDIAN_LITTLE; + /* nanomips has 16, 32 and 48-bit insns */ + info->cap_insn_unit = 2; + info->cap_insn_split = 6; + cap_mode = CS_MODE_NANOMIPS; + } else { info->endian = TARGET_BIG_ENDIAN ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE; info->print_insn = TARGET_BIG_ENDIAN ? print_insn_big_mips : print_insn_little_mips; - } else { - info->print_insn = print_insn_nanomips; - info->endian = BFD_ENDIAN_LITTLE; + + if (env->hflags & MIPS_HFLAG_M16) { + cap_mode = (env->insn_flags & ASE_MICROMIPS + ? CS_MODE_MICRO : CS_MODE_MIPS16); + /* Beware unsupported capstone mode */ + if (cap_mode == 0) { + return; + } + info->cap_insn_unit = 2; + } else { + info->cap_insn_unit = 4; + } + info->cap_insn_split = 4; + + cap_mode |= is64 ? CS_MODE_MIPS64 : CS_MODE_MIPS32; + if (env->insn_flags & ISA_MIPS_R6) { + cap_mode |= is64 ? CS_MODE_MIPS64R6 : CS_MODE_MIPS32R6; + } else if (env->insn_flags & ISA_MIPS_R5) { + cap_mode |= is64 ? CS_MODE_MIPS64R5 : CS_MODE_MIPS32R5; + } else if (env->insn_flags & ISA_MIPS_R3) { + cap_mode |= is64 ? CS_MODE_MIPS64R3 : CS_MODE_MIPS32R3; + } else if (env->insn_flags & ISA_MIPS_R2) { + cap_mode |= is64 ? CS_MODE_MIPS64R2 : CS_MODE_MIPS32R2; + } else if (env->insn_flags & ISA_MIPS5) { + cap_mode |= CS_MODE_MIPS5; + } else if (env->insn_flags & ISA_MIPS4) { + cap_mode |= CS_MODE_MIPS4; + } else if (env->insn_flags & ISA_MIPS3) { + cap_mode |= CS_MODE_MIPS3; + } else if (env->insn_flags & ISA_MIPS2) { + cap_mode |= CS_MODE_MIPS2; + } else if (env->insn_flags & ISA_MIPS1) { + cap_mode |= CS_MODE_MIPS1; + } + if (env->insn_flags & INSN_OCTEON) { + cap_mode |= CS_MODE_OCTEON | CS_MODE_OCTEONP; + } + if (is64 && !(env->hflags & MIPS_HFLAG_AWRAP)) { + cap_mode |= CS_MODE_MIPS_PTR64; + } + } + /* Beware unsupported capstone mode */ + if (cap_mode) { + info->cap_arch = CS_ARCH_MIPS; + info->cap_mode = cap_mode; } } -- 2.43.0