Only load or store 32 bits data for atomic instructions when UXL32. Signed-off-by: LIU Zhiwei <zhiwei_...@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