On 8/11/21 11:20 PM, Song Gao wrote:
This is easily implemented inline, followed by a single helper call to re-load
the rounding mode (if required by the mask).
Hi, Richard,
Sorry to bother you, When I was revising this patch, I found that I didn't seem
to
understand your opinion. Could you explain it in detail? thank you very much.
---%<
static const uint32_t fcsr_mask[4] = {
UINT32_MAX, FCSR0_M1, FCSR0_M2, FCSR0_M3
};
bool trans_movgr2fcsr(DisasContext *s, arg_movgr2fcsr *a)
{
uint32_t mask = fcsr_mask[a->fcsr];
if (mask == UINT32_MAX) {
tcg_gen_extrl_i64_i32(fpu_fscr0, get_gpr(a->rj));
} else {
TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_extrl_i64_i32(tmp, get_gpr(a->rj));
tcg_gen_andi_i32(tmp, tmp, mask);
tcg_gen_andi_i32(fpu_fcsr0, cpu_fcsr0, ~mask);
tcg_gen_or_i32(fpu_fcsr0, fpu_fcsr0, tmp);
tcg_temp_free_i32(tmp);
/*
* 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;
}
}
gen_helper_set_rounding_mode(cpu_env, fpu_fcsr0);
return true;
}
void trans_movfcsr2gr(DisasContext *s, arg_movfcsr2gr *a)
{
TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_andi_i32(tmp, fpu_fcsr0, fcsr_mask[a->fcsr]);
tcg_gen_ext_i32_i64(dest_gpr(a->rd), tmp);
tcg_temp_free_i32(tmp);
return true;
}
---%<
DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_RWG, void, env, i32)
---%<
void HELPER(set_rounding_mode)(CPULoongArchState *env, uint32_t fcsr)
{
set_float_rounding_mode(ieee_rm[(fcsr0 >> FCSR0_RM) & 0x3],
&env->fp_status);
}
r~