diff mbox series

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

Message ID 20210805025312.15720-10-zhiwei_liu@c-sky.com
State New
Headers show
Series Support UXL field in mstatus | expand

Commit Message

LIU Zhiwei Aug. 5, 2021, 2:53 a.m. UTC
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 mbox series

Patch

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);