summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>2026-05-19 17:47:14 -0300
committerMichael Tokarev <mjt@tls.msk.ru>2026-06-17 08:29:24 +0300
commitd293278f68e904ea6cc7d4b0540d1118ad7129e0 (patch)
treee5ce27cce878dd448ca3fb7db801efc71cb273bf
parent4686ecc71af1019132f9de869daeed39dcdf8f53 (diff)
downloadqemu-d293278f68e904ea6cc7d4b0540d1118ad7129e0.tar.gz
qemu-d293278f68e904ea6cc7d4b0540d1118ad7129e0.zip
disas/riscv.c: add 'cbo' insns to disassembler
We forgot to add 'cbo' insns to disas/riscv.c. The result is that the disassembler recognizes all of them as 'lq', an insn that happens to share the same opcode space. While we're at it reorder cbo_* entries in insn32.decode using opcode order instead of insn name. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3480 Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-ID: <20260519204714.1376551-1-daniel.barboza@oss.qualcomm.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com> (cherry picked from commit 9273cda72293ed2f414a0f239c4ac78fb7838c0e) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
-rw-r--r--disas/riscv.c29
-rw-r--r--target/riscv/insn32.decode2
2 files changed, 29 insertions, 2 deletions
diff --git a/disas/riscv.c b/disas/riscv.c
index 85cd2a9c2a..980da7f7e1 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -984,6 +984,10 @@ typedef enum {
rv_op_ssamoswap_d = 953,
rv_op_c_sspush = 954,
rv_op_c_sspopchk = 955,
+ rv_op_cbo_inval = 956,
+ rv_op_cbo_clean = 957,
+ rv_op_cbo_flush = 958,
+ rv_op_cbo_zero = 959,
} rv_op;
/* register names */
@@ -2254,6 +2258,10 @@ const rv_opcode_data rvi_opcode_data[] = {
rv_op_sspush, 0 },
{ "c.sspopchk", rv_codec_cmop_ss, rv_fmt_rs1, NULL, rv_op_sspopchk,
rv_op_sspopchk, 0 },
+ { "cbo.inval", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+ { "cbo.clean", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+ { "cbo.flush", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
+ { "cbo.zero", rv_codec_r, rv_fmt_rs1, NULL, 0, 0, 0 },
};
/* CSR names */
@@ -2875,7 +2883,26 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fence; break;
case 1: op = rv_op_fence_i; break;
- case 2: op = rv_op_lq; break;
+ case 2:
+ /*
+ * 'lq' shares the "(...) 010 ..... 0001111" opcode space
+ * with 'cbo' insns. Check the next 5 bits to select
+ * what we want:
+ *
+ * cbo_inval 0000000 00000 ..... 010 00000 0001111
+ * cbo_clean 0000000 00001 ..... 010 00000 0001111
+ * cbo_flush 0000000 00010 ..... 010 00000 0001111
+ * cbo_zero 0000000 00100 ..... 010 00000 0001111
+ *
+ * Anything that doesn't match these will default to 'lq'.
+ */
+ switch ((inst >> 17) & 0b11111) {
+ case 0: op = rv_op_cbo_inval; break;
+ case 1: op = rv_op_cbo_clean; break;
+ case 2: op = rv_op_cbo_flush; break;
+ case 4: op = rv_op_cbo_zero; break;
+ default: op = rv_op_lq; break;
+ }
}
break;
case 4:
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index cd23b1f3a9..564b745c48 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -199,9 +199,9 @@ ldu ............ ..... 111 ..... 0000011 @i
{
[
# *** RV32 Zicbom Standard Extension ***
+ cbo_inval 0000000 00000 ..... 010 00000 0001111 @sfence_vm
cbo_clean 0000000 00001 ..... 010 00000 0001111 @sfence_vm
cbo_flush 0000000 00010 ..... 010 00000 0001111 @sfence_vm
- cbo_inval 0000000 00000 ..... 010 00000 0001111 @sfence_vm
# *** RV32 Zicboz Standard Extension ***
cbo_zero 0000000 00100 ..... 010 00000 0001111 @sfence_vm