qemu-riscv
[Top][All Lists]
Advanced

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

[RFC PATCH 09/13] target/riscv: Support UXL32 for atomic instructions


From: LIU Zhiwei
Subject: [RFC PATCH 09/13] target/riscv: Support UXL32 for atomic instructions
Date: Thu, 5 Aug 2021 10:53:08 +0800

Only load or store 32 bits data for atomic instructions when UXL32.

Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
---
 target/riscv/insn_trans/trans_rva.c.inc | 36 ++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rva.c.inc 
b/target/riscv/insn_trans/trans_rva.c.inc
index 5bb5bbd09c..07c94416e5 100644
--- a/target/riscv/insn_trans/trans_rva.c.inc
+++ b/target/riscv/insn_trans/trans_rva.c.inc
@@ -20,12 +20,19 @@
 
 static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
 {
-    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src1 = gpr_src_u(ctx, a->rs1);
 
     /* Put addr in load_res, data in load_val.  */
     if (a->rl) {
         tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
     }
+    if (ctx->uxl32) {
+        TCGv_i32 val = tcg_temp_new_i32();
+        tcg_gen_qemu_ld_i32(val, src1, ctx->mem_idx, mop);
+        tcg_gen_extu_i32_tl(load_val, val);
+    } else {
+        tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
+    }
     tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
     if (a->aq) {
         tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
@@ -39,8 +46,8 @@ static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp 
mop)
 static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
 {
     TCGv dest = gpr_dst(ctx, a->rd);
-    TCGv src1 = gpr_src(ctx, a->rs1);
-    TCGv src2 = gpr_src(ctx, a->rs2);
+    TCGv src1 = gpr_src_u(ctx, a->rs1);
+    TCGv src2 = gpr_src_u(ctx, a->rs2);
     TCGLabel *l1 = gen_new_label();
     TCGLabel *l2 = gen_new_label();
 
@@ -50,8 +57,25 @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp 
mop)
      * Note that the TCG atomic primitives are SC,
      * so we can ignore AQ/RL along this path.
      */
-    tcg_gen_atomic_cmpxchg_tl(dest, load_res, load_val, src2,
-                              ctx->mem_idx, mop);
+    if (ctx->uxl32) {
+        TCGv_i32 retv, cmpv, newv;
+        retv = tcg_temp_new_i32();
+        cmpv = tcg_temp_new_i32();
+        newv = tcg_temp_new_i32();
+        tcg_gen_trunc_tl_i32(cmpv, load_val);
+        tcg_gen_trunc_tl_i32(newv, src2);
+
+        tcg_gen_atomic_cmpxchg_i32(retv, load_res, cmpv, newv,
+                                   ctx->mem_idx, mop);
+
+        tcg_gen_extu_i32_tl(dest, retv);
+        tcg_temp_free_i32(retv);
+        tcg_temp_free_i32(cmpv);
+        tcg_temp_free_i32(newv);
+    } else {
+        tcg_gen_atomic_cmpxchg_tl(dest, load_res, load_val, src2,
+                                  ctx->mem_idx, mop);
+    }
     tcg_gen_setcond_tl(TCG_COND_NE, dest, dest, load_val);
     tcg_gen_br(l2);
 
@@ -78,7 +102,7 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
                     MemOp mop)
 {
     TCGv dest = gpr_dst(ctx, a->rd);
-    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src1 = gpr_src_u(ctx, a->rs1);
     TCGv src2 = gpr_src(ctx, a->rs2);
 
     (*func)(dest, src1, src2, ctx->mem_idx, mop);
-- 
2.17.1




reply via email to

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