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