summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>2026-05-27 17:03:55 -0300
committerMichael Tokarev <mjt@tls.msk.ru>2026-06-17 08:32:09 +0300
commit58276e92dde2899a05c0efc1a07393f436ba31b9 (patch)
treeb4c3d61801ee85b344a7c131af21b98b5ca2ba97
parent38f9b1ab7e6e0bd40770503df6a7926dba9d41ec (diff)
downloadqemu-58276e92dde2899a05c0efc1a07393f436ba31b9.tar.gz
qemu-58276e92dde2899a05c0efc1a07393f436ba31b9.zip
disas/riscv.c: fix inst_length()
inst_length() can return 0 if 'inst' happens to not match any known encoding (like [1]). Returning 0 is not desirable, even for unknown encodings, given that it will cause a loop in target_disas() later on. The most recent version of the RISC-V unpriv spec ditched the sophisticated instruction-length encoding. We're now supporting only 16-bit and 32-bit length instructions, where: "All the 32-bit instructions in the base ISA have their lowest two bits set to 11. The optional compressed 16-bit instruction-set extensions have their lowest two bits equal to 00, 01, or 10." So the code is now simpler, never returning 0, and in fact it's the same thing we're already doing in insn_len() from target/riscv/internals.h. Due to include shenarigans we can't use that function in disas/riscv.c, but I believe we can cut ourselves some slack this time and not lose sleep over a 1 line of duplicated logic. We're documenting it though! [1] https://gitlab.com/qemu-project/qemu/-/work_items/3479 Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3479 Signed-off-by: Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260527200355.2068879-2-daniel.barboza@oss.qualcomm.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com> (cherry picked from commit 758dce9c98af4f3ef26eada48a484a7d60258636) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
-rw-r--r--disas/riscv.c20
1 files changed, 2 insertions, 18 deletions
diff --git a/disas/riscv.c b/disas/riscv.c
index 980da7f7e1..2d8add3212 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -5083,26 +5083,10 @@ static bool check_constraints(rv_decode *dec, const rvc_constraint *c)
return true;
}
-/* instruction length */
-
+/* Same as insn_len() from target/riscv/internals.h */
static size_t inst_length(rv_inst inst)
{
- /* NOTE: supports maximum instruction size of 64-bits */
-
- /*
- * instruction length coding
- *
- * aa - 16 bit aa != 11
- * bbb11 - 32 bit bbb != 111
- * 011111 - 48 bit
- * 0111111 - 64 bit
- */
-
- return (inst & 0b11) != 0b11 ? 2
- : (inst & 0b11100) != 0b11100 ? 4
- : (inst & 0b111111) == 0b011111 ? 6
- : (inst & 0b1111111) == 0b0111111 ? 8
- : 0;
+ return (inst & 3) == 3 ? 4 : 2;
}
/* format instruction */