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~

Reply via email to