@@ -8437,21 +8437,30 @@ 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);
- write_fp_dreg(s, a->rd, 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);
- write_fp_sreg(s, a->rd, 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:
@@ -8461,7 +8470,11 @@ 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);
- write_fp_sreg(s, a->rd, t);
+ if (merging) {
+ write_fp_hreg_merging(s, a->rd, a->rd, t);
+ } else {
+ write_fp_sreg(s, a->rd, t);
+ }
}
break;
default:
@@ -8475,21 +8488,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);
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> --- target/arm/tcg/translate-a64.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)