qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v11 03/16] target/riscv: clwz must ignore high bits (use shif


From: LIU Zhiwei
Subject: Re: [PATCH v11 03/16] target/riscv: clwz must ignore high bits (use shift-left & changed logic)
Date: Tue, 14 Sep 2021 17:15:42 +0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0


On 2021/9/11 下午10:00, Philipp Tomsich wrote:
Assume clzw being executed on a register that is not sign-extended, such
as for the following sequence that uses (1ULL << 63) | 392 as the operand
to clzw:
        bseti   a2, zero, 63
        addi    a2, a2, 392
        clzw    a3, a2
The correct result of clzw would be 23, but the current implementation
returns -32 (as it performs a 64bit clz, which results in 0 leading zero
bits, and then subtracts 32).

As the MSB word of  a3 has been cleaned,  the result of current implementation will be 23. So there is no
error here.

Thanks,
Zhiwei

Fix this by changing the implementation to:
  1. shift the original register up by 32
  2. performs a target-length (64bit) clz
  3. return 32 if no bits are set

Marking this instruction as 'w-form' (i.e., setting ctx->w) would not
correctly model the behaviour, as the instruction should not perform
a zero-extensions on the input (after all, it is not a .uw instruction)
and the result is always in the range 0..32 (so neither a sign-extension
nor a zero-extension on the result will ever be needed).  Consequently,
we do not set ctx->w and mark the instruction as EXT_NONE.

Signed-off-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
---

Changes in v11:
- Swaps out the EXT_ZERO to EXT_NONE, as no extension is to be performed.

Changes in v10:
- New patch, fixing correctnes for clzw called on a register with undefined
   (as in: not properly sign-extended) upper bits.

  target/riscv/insn_trans/trans_rvb.c.inc | 8 +++++---
  1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvb.c.inc 
b/target/riscv/insn_trans/trans_rvb.c.inc
index 6c85c89f6d..73d1e45026 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -349,15 +349,17 @@ GEN_TRANS_SHADD(3)
static void gen_clzw(TCGv ret, TCGv arg1)
  {
-    tcg_gen_clzi_tl(ret, arg1, 64);
-    tcg_gen_subi_tl(ret, ret, 32);
+    TCGv t = tcg_temp_new();
+    tcg_gen_shli_tl(t, arg1, 32);
+    tcg_gen_clzi_tl(ret, t, 32);
+    tcg_temp_free(t);
  }
static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
  {
      REQUIRE_64BIT(ctx);
      REQUIRE_EXT(ctx, RVB);
-    return gen_unary(ctx, a, EXT_ZERO, gen_clzw);
+    return gen_unary(ctx, a, EXT_NONE, gen_clzw);
  }
static void gen_ctzw(TCGv ret, TCGv arg1)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]