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)
|
||||
|
||||
static void gen_fcvtxn_sd(TCGv_i64 d, TCGv_i64 n)
|
||||
static bool trans_FCVTXN_s(DisasContext *s, arg_rr_e *a)
|
||||
{
|
||||
/*
|
||||
* 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);
|
||||
if (fp_access_check(s)) {
|
||||
/*
|
||||
* 64 bit to 32 bit float conversion
|
||||
* with von Neumann rounding (round to odd)
|
||||
*/
|
||||
TCGv_i64 src = read_fp_dreg(s, a->rn);
|
||||
TCGv_i32 dst = tcg_temp_new_i32();
|
||||
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
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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[] = {
|
||||
NULL,
|
||||
gen_fcvtn_hs,
|
||||
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(FCVTXN_v, do_2misc_narrow_vector, a, f_scalar_fcvtxn)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user