From 10dcb08b03863221faa41f4f1aa835cdca441b96 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 6 Aug 2022 10:04:44 -0700 Subject: target/loongarch: Remove cpu_fcsr0 All of the fpu operations are defined with TCG_CALL_NO_WG, but they all modify FCSR0. The most efficient way to fix this is to remove cpu_fcsr0, and instead use explicit load and store operations for the two instructions that manipulate that value. Acked-by: Qi Hu Reviewed-by: Song Gao Reported-by: Feiyang Chen Signed-off-by: Richard Henderson --- target/loongarch/insn_trans/trans_fmov.c.inc | 33 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'target/loongarch/insn_trans') diff --git a/target/loongarch/insn_trans/trans_fmov.c.inc b/target/loongarch/insn_trans/trans_fmov.c.inc index 24753d4568..5537e3dd35 100644 --- a/target/loongarch/insn_trans/trans_fmov.c.inc +++ b/target/loongarch/insn_trans/trans_fmov.c.inc @@ -60,38 +60,39 @@ static bool trans_movgr2fcsr(DisasContext *ctx, arg_movgr2fcsr *a) TCGv Rj = gpr_src(ctx, a->rj, EXT_NONE); if (mask == UINT32_MAX) { - tcg_gen_extrl_i64_i32(cpu_fcsr0, Rj); + tcg_gen_st32_i64(Rj, cpu_env, offsetof(CPULoongArchState, fcsr0)); } else { + TCGv_i32 fcsr0 = tcg_temp_new_i32(); TCGv_i32 temp = tcg_temp_new_i32(); + tcg_gen_ld_i32(fcsr0, cpu_env, offsetof(CPULoongArchState, fcsr0)); tcg_gen_extrl_i64_i32(temp, Rj); tcg_gen_andi_i32(temp, temp, mask); - tcg_gen_andi_i32(cpu_fcsr0, cpu_fcsr0, ~mask); - tcg_gen_or_i32(cpu_fcsr0, cpu_fcsr0, temp); - tcg_temp_free_i32(temp); + tcg_gen_andi_i32(fcsr0, fcsr0, ~mask); + tcg_gen_or_i32(fcsr0, fcsr0, temp); + tcg_gen_st_i32(fcsr0, cpu_env, offsetof(CPULoongArchState, fcsr0)); - /* - * Install the new rounding mode to fpu_status, if changed. - * Note that FCSR3 is exactly the rounding mode field. - */ - if (mask != FCSR0_M3) { - return true; - } + tcg_temp_free_i32(temp); + tcg_temp_free_i32(fcsr0); } - gen_helper_set_rounding_mode(cpu_env, cpu_fcsr0); + /* + * Install the new rounding mode to fpu_status, if changed. + * Note that FCSR3 is exactly the rounding mode field. + */ + if (mask & FCSR0_M3) { + gen_helper_set_rounding_mode(cpu_env); + } return true; } static bool trans_movfcsr2gr(DisasContext *ctx, arg_movfcsr2gr *a) { - TCGv_i32 temp = tcg_temp_new_i32(); TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE); - tcg_gen_andi_i32(temp, cpu_fcsr0, fcsr_mask[a->fcsrs]); - tcg_gen_ext_i32_i64(dest, temp); + tcg_gen_ld32u_i64(dest, cpu_env, offsetof(CPULoongArchState, fcsr0)); + tcg_gen_andi_i64(dest, dest, fcsr_mask[a->fcsrs]); gen_set_gpr(a->rd, dest, EXT_NONE); - tcg_temp_free_i32(temp); return true; } -- cgit v1.2.3