target/arm: Handle FPCR.NEP for scalar FABS and FNEG

Handle FPCR.NEP merging for scalar FABS and FNEG; this requires
an extra parameter to do_fp1_scalar_int(), since FMOV scalar
does not have the merging behaviour.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Peter Maydell 2025-02-01 16:39:24 +00:00
parent 13ab4eb190
commit 64339259a9

View File

@ -8426,22 +8426,31 @@ typedef struct FPScalar1Int {
} FPScalar1Int;
static bool do_fp1_scalar_int(DisasContext *s, arg_rr_e *a,
const FPScalar1Int *f)
const FPScalar1Int *f,
bool merging)
{
switch (a->esz) {
case MO_64:
if (fp_access_check(s)) {
TCGv_i64 t = read_fp_dreg(s, a->rn);
f->gen_d(t, t);
if (merging) {
write_fp_dreg_merging(s, a->rd, a->rd, t);
} else {
write_fp_dreg(s, a->rd, t);
}
}
break;
case MO_32:
if (fp_access_check(s)) {
TCGv_i32 t = read_fp_sreg(s, a->rn);
f->gen_s(t, t);
if (merging) {
write_fp_sreg_merging(s, a->rd, a->rd, t);
} else {
write_fp_sreg(s, a->rd, t);
}
}
break;
case MO_16:
if (!dc_isar_feature(aa64_fp16, s)) {
@ -8450,8 +8459,12 @@ static bool do_fp1_scalar_int(DisasContext *s, arg_rr_e *a,
if (fp_access_check(s)) {
TCGv_i32 t = read_fp_hreg(s, a->rn);
f->gen_h(t, t);
if (merging) {
write_fp_hreg_merging(s, a->rd, a->rd, t);
} else {
write_fp_sreg(s, a->rd, t);
}
}
break;
default:
return false;
@ -8464,21 +8477,21 @@ static const FPScalar1Int f_scalar_fmov = {
tcg_gen_mov_i32,
tcg_gen_mov_i64,
};
TRANS(FMOV_s, do_fp1_scalar_int, a, &f_scalar_fmov)
TRANS(FMOV_s, do_fp1_scalar_int, a, &f_scalar_fmov, false)
static const FPScalar1Int f_scalar_fabs = {
gen_vfp_absh,
gen_vfp_abss,
gen_vfp_absd,
};
TRANS(FABS_s, do_fp1_scalar_int, a, &f_scalar_fabs)
TRANS(FABS_s, do_fp1_scalar_int, a, &f_scalar_fabs, true)
static const FPScalar1Int f_scalar_fneg = {
gen_vfp_negh,
gen_vfp_negs,
gen_vfp_negd,
};
TRANS(FNEG_s, do_fp1_scalar_int, a, &f_scalar_fneg)
TRANS(FNEG_s, do_fp1_scalar_int, a, &f_scalar_fneg, true)
typedef struct FPScalar1 {
void (*gen_h)(TCGv_i32, TCGv_i32, TCGv_ptr);