From: Frédéric Pétrot <[email protected]>

Lq shares the cmo opcode space, but the cbos must have rd = 0.
Now ensure that they are matched only in that case.
This implies that lq can be recognized as such only when rd != 0.
Update the decoder file accordingly.

Fixes: 9273cda722 ("disas/riscv.c: add 'cbo' insns to disassembler")
Reported-by: Julien Thillard <[email protected]>
Signed-off-by: Frédéric Pétrot <[email protected]>
Reviewed-by: Daniel Henrique Barboza <[email protected]>
---
 disas/riscv.c              | 20 +++++++++++---------
 target/riscv/insn32.decode |  2 ++
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index b8099cbdf8..e85dbac035 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -1281,22 +1281,24 @@ static const rv_opcode_data 
*decode_inst_opcode(rv_decode *dec, rv_isa isa)
             case 2:
                /*
                 * 'lq' shares the "(...) 010 ..... 0001111" opcode space
-                * with 'cbo' insns.  Check the next 5 bits to select
-                * what we want:
+                * with 'cbo' insns.
                 *
                 * 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'.
+                * lq matches when rd != 0
                 */
-               switch ((inst >> 17) & 0b11111) {
-               case 0: return &op_cbo_inval;
-               case 1: return &op_cbo_clean;
-               case 2: return &op_cbo_flush;
-               case 4: return &op_cbo_zero;
-               default: return &op_lq;
+               if ((inst >> 7) & 0b11111) {
+                   return &op_lq;
+               } else {
+                   switch (inst >> 20) {
+                   case 0: return &op_cbo_inval;
+                   case 1: return &op_cbo_clean;
+                   case 2: return &op_cbo_flush;
+                   case 4: return &op_cbo_zero;
+                   }
                }
             }
             break;
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 21272fdb50..aa02dae3c9 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -216,6 +216,8 @@ ldu      ............   ..... 111 ..... 0000011 @i
   ]
 
   # *** RVI128 lq ***
+  # *** Catches an lq with rd = 0, which we disallow
+  illegal  ------------   ----- 010 00000 0001111
   lq       ............   ..... 010 ..... 0001111 @i
 }
 sq       ............   ..... 100 ..... 0100011 @s
-- 
2.43.0


Reply via email to