@samitouri / QOSamiQemu / commits / 84dd090703

target/mips: 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 17:28 UTC 84dd090703e4164e209e0729333cfd30d8f9c9f8
2 files changed +77 -7
include/disas/capstone.h
+21 -3
@@ -29,6 +29,7 @@
29 #define CS_MODE_THUMB 0
30 #define CS_MODE_MCLASS 0
31 #define CS_MODE_V8 0
32 +#define CS_MODE_V9 0
33 #define CS_MODE_M68K_000 0
34 #define CS_MODE_M68K_010 0
35 #define CS_MODE_M68K_020 0
@@ -36,11 +37,10 @@
37 #define CS_MODE_M68K_040 0
38 #define CS_MODE_M68K_060 0
39 #define CS_MODE_MICRO 0
40 +#define CS_MODE_MIPS2 0
41 #define CS_MODE_MIPS3 0
40 -#define CS_MODE_MIPS32R6 0
41 -#define CS_MODE_MIPSGP64 0
42 -#define CS_MODE_V9 0
42 #define CS_MODE_MIPS32 0
43 +#define CS_MODE_MIPS32R6 0
44 #define CS_MODE_MIPS64 0
45
46 #endif /* CONFIG_CAPSTONE */
@@ -64,6 +64,24 @@
64 #define CS_MODE_M68K_CF_FPU 0
65 #endif
66
67 +#if CS_API_MAJOR < 6
68 +#define CS_MODE_MIPS16 0
69 +#define CS_MODE_MIPS1 0
70 +#define CS_MODE_MIPS32R2 0
71 +#define CS_MODE_MIPS32R3 0
72 +#define CS_MODE_MIPS32R5 0
73 +#define CS_MODE_MIPS4 0
74 +#define CS_MODE_MIPS5 0
75 +#define CS_MODE_MIPS64R2 0
76 +#define CS_MODE_MIPS64R3 0
77 +#define CS_MODE_MIPS64R5 0
78 +#define CS_MODE_MIPS64R6 0
79 +#define CS_MODE_OCTEON 0
80 +#define CS_MODE_OCTEONP 0
81 +#define CS_MODE_NANOMIPS 0
82 +#define CS_MODE_MIPS_PTR64 0
83 +#endif
84 +
85 #if CS_API_MAJOR < 5
86 #define CS_ARCH_RISCV -1
87 #define CS_MODE_RISCV32 0
target/mips/cpu.c
+56 -4
@@ -30,6 +30,7 @@
30 #include "system/qtest.h"
31 #include "hw/core/qdev-properties.h"
32 #include "hw/core/qdev-clock.h"
33 +#include "disas/capstone.h"
34 #include "fpu_helper.h"
35 #ifndef CONFIG_USER_ONLY
36 #include "semihosting/semihost.h"
@@ -488,15 +489,66 @@ static void mips_cpu_disas_set_info(const CPUState *cs, disassemble_info *info)
489 {
490 const MIPSCPU *cpu = MIPS_CPU(cs);
491 const CPUMIPSState *env = &cpu->env;
492 + bool is64 = env->hflags & MIPS_HFLAG_64;
493 + int cap_mode = 0;
494
492 - if (!(env->insn_flags & ISA_NANOMIPS32)) {
495 + if (env->insn_flags & ISA_NANOMIPS32) {
496 + info->print_insn = print_insn_nanomips;
497 + info->endian = BFD_ENDIAN_LITTLE;
498 + /* nanomips has 16, 32 and 48-bit insns */
499 + info->cap_insn_unit = 2;
500 + info->cap_insn_split = 6;
501 + cap_mode = CS_MODE_NANOMIPS;
502 + } else {
503 info->endian = TARGET_BIG_ENDIAN ? BFD_ENDIAN_BIG
504 : BFD_ENDIAN_LITTLE;
505 info->print_insn = TARGET_BIG_ENDIAN ? print_insn_big_mips
506 : print_insn_little_mips;
497 - } else {
498 - info->print_insn = print_insn_nanomips;
499 - info->endian = BFD_ENDIAN_LITTLE;
507 +
508 + if (env->hflags & MIPS_HFLAG_M16) {
509 + cap_mode = (env->insn_flags & ASE_MICROMIPS
510 + ? CS_MODE_MICRO : CS_MODE_MIPS16);
511 + /* Beware unsupported capstone mode */
512 + if (cap_mode == 0) {
513 + return;
514 + }
515 + info->cap_insn_unit = 2;
516 + } else {
517 + info->cap_insn_unit = 4;
518 + }
519 + info->cap_insn_split = 4;
520 +
521 + cap_mode |= is64 ? CS_MODE_MIPS64 : CS_MODE_MIPS32;
522 + if (env->insn_flags & ISA_MIPS_R6) {
523 + cap_mode |= is64 ? CS_MODE_MIPS64R6 : CS_MODE_MIPS32R6;
524 + } else if (env->insn_flags & ISA_MIPS_R5) {
525 + cap_mode |= is64 ? CS_MODE_MIPS64R5 : CS_MODE_MIPS32R5;
526 + } else if (env->insn_flags & ISA_MIPS_R3) {
527 + cap_mode |= is64 ? CS_MODE_MIPS64R3 : CS_MODE_MIPS32R3;
528 + } else if (env->insn_flags & ISA_MIPS_R2) {
529 + cap_mode |= is64 ? CS_MODE_MIPS64R2 : CS_MODE_MIPS32R2;
530 + } else if (env->insn_flags & ISA_MIPS5) {
531 + cap_mode |= CS_MODE_MIPS5;
532 + } else if (env->insn_flags & ISA_MIPS4) {
533 + cap_mode |= CS_MODE_MIPS4;
534 + } else if (env->insn_flags & ISA_MIPS3) {
535 + cap_mode |= CS_MODE_MIPS3;
536 + } else if (env->insn_flags & ISA_MIPS2) {
537 + cap_mode |= CS_MODE_MIPS2;
538 + } else if (env->insn_flags & ISA_MIPS1) {
539 + cap_mode |= CS_MODE_MIPS1;
540 + }
541 + if (env->insn_flags & INSN_OCTEON) {
542 + cap_mode |= CS_MODE_OCTEON | CS_MODE_OCTEONP;
543 + }
544 + if (is64 && !(env->hflags & MIPS_HFLAG_AWRAP)) {
545 + cap_mode |= CS_MODE_MIPS_PTR64;
546 + }
547 + }
548 + /* Beware unsupported capstone mode */
549 + if (cap_mode) {
550 + info->cap_arch = CS_ARCH_MIPS;
551 + info->cap_mode = cap_mode;
552 }
553 }
554