target/arm: Handle FPCR.NEP for FCVTXN (scalar)
Unlike the other users of do_2misc_narrow_scalar(), FCVTXN (scalar) is always double-to-single and must honour FPCR.NEP. Implement this directly in a trans function rather than using do_2misc_narrow_scalar(). We still need gen_fcvtxn_sd() and the f_scalar_fcvtxn[] array for the FCVTXN (vector) insn, so we move those down in the file to where they are used. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
64339259a9
commit
555639065d
@ -9247,24 +9247,21 @@ static ArithOneOp * const f_scalar_uqxtn[] = {
|
|||||||
};
|
};
|
||||||
TRANS(UQXTN_s, do_2misc_narrow_scalar, a, f_scalar_uqxtn)
|
TRANS(UQXTN_s, do_2misc_narrow_scalar, a, f_scalar_uqxtn)
|
||||||
|
|
||||||
static void gen_fcvtxn_sd(TCGv_i64 d, TCGv_i64 n)
|
static bool trans_FCVTXN_s(DisasContext *s, arg_rr_e *a)
|
||||||
{
|
{
|
||||||
|
if (fp_access_check(s)) {
|
||||||
/*
|
/*
|
||||||
* 64 bit to 32 bit float conversion
|
* 64 bit to 32 bit float conversion
|
||||||
* with von Neumann rounding (round to odd)
|
* with von Neumann rounding (round to odd)
|
||||||
*/
|
*/
|
||||||
TCGv_i32 tmp = tcg_temp_new_i32();
|
TCGv_i64 src = read_fp_dreg(s, a->rn);
|
||||||
gen_helper_fcvtx_f64_to_f32(tmp, n, fpstatus_ptr(FPST_A64));
|
TCGv_i32 dst = tcg_temp_new_i32();
|
||||||
tcg_gen_extu_i32_i64(d, tmp);
|
gen_helper_fcvtx_f64_to_f32(dst, src, fpstatus_ptr(FPST_A64));
|
||||||
|
write_fp_sreg_merging(s, a->rd, a->rd, dst);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ArithOneOp * const f_scalar_fcvtxn[] = {
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
gen_fcvtxn_sd,
|
|
||||||
};
|
|
||||||
TRANS(FCVTXN_s, do_2misc_narrow_scalar, a, f_scalar_fcvtxn)
|
|
||||||
|
|
||||||
#undef WRAP_ENV
|
#undef WRAP_ENV
|
||||||
|
|
||||||
static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn)
|
static bool do_gvec_fn2(DisasContext *s, arg_qrr_e *a, GVecGen2Fn *fn)
|
||||||
@ -9366,11 +9363,27 @@ static void gen_fcvtn_sd(TCGv_i64 d, TCGv_i64 n)
|
|||||||
tcg_gen_extu_i32_i64(d, tmp);
|
tcg_gen_extu_i32_i64(d, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gen_fcvtxn_sd(TCGv_i64 d, TCGv_i64 n)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 64 bit to 32 bit float conversion
|
||||||
|
* with von Neumann rounding (round to odd)
|
||||||
|
*/
|
||||||
|
TCGv_i32 tmp = tcg_temp_new_i32();
|
||||||
|
gen_helper_fcvtx_f64_to_f32(tmp, n, fpstatus_ptr(FPST_A64));
|
||||||
|
tcg_gen_extu_i32_i64(d, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
static ArithOneOp * const f_vector_fcvtn[] = {
|
static ArithOneOp * const f_vector_fcvtn[] = {
|
||||||
NULL,
|
NULL,
|
||||||
gen_fcvtn_hs,
|
gen_fcvtn_hs,
|
||||||
gen_fcvtn_sd,
|
gen_fcvtn_sd,
|
||||||
};
|
};
|
||||||
|
static ArithOneOp * const f_scalar_fcvtxn[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
gen_fcvtxn_sd,
|
||||||
|
};
|
||||||
TRANS(FCVTN_v, do_2misc_narrow_vector, a, f_vector_fcvtn)
|
TRANS(FCVTN_v, do_2misc_narrow_vector, a, f_vector_fcvtn)
|
||||||
TRANS(FCVTXN_v, do_2misc_narrow_vector, a, f_scalar_fcvtxn)
|
TRANS(FCVTXN_v, do_2misc_narrow_vector, a, f_scalar_fcvtxn)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user