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:
parent
13ab4eb190
commit
64339259a9
@ -8426,21 +8426,30 @@ typedef struct FPScalar1Int {
|
|||||||
} FPScalar1Int;
|
} FPScalar1Int;
|
||||||
|
|
||||||
static bool do_fp1_scalar_int(DisasContext *s, arg_rr_e *a,
|
static bool do_fp1_scalar_int(DisasContext *s, arg_rr_e *a,
|
||||||
const FPScalar1Int *f)
|
const FPScalar1Int *f,
|
||||||
|
bool merging)
|
||||||
{
|
{
|
||||||
switch (a->esz) {
|
switch (a->esz) {
|
||||||
case MO_64:
|
case MO_64:
|
||||||
if (fp_access_check(s)) {
|
if (fp_access_check(s)) {
|
||||||
TCGv_i64 t = read_fp_dreg(s, a->rn);
|
TCGv_i64 t = read_fp_dreg(s, a->rn);
|
||||||
f->gen_d(t, t);
|
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;
|
break;
|
||||||
case MO_32:
|
case MO_32:
|
||||||
if (fp_access_check(s)) {
|
if (fp_access_check(s)) {
|
||||||
TCGv_i32 t = read_fp_sreg(s, a->rn);
|
TCGv_i32 t = read_fp_sreg(s, a->rn);
|
||||||
f->gen_s(t, t);
|
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;
|
break;
|
||||||
case MO_16:
|
case MO_16:
|
||||||
@ -8450,7 +8459,11 @@ static bool do_fp1_scalar_int(DisasContext *s, arg_rr_e *a,
|
|||||||
if (fp_access_check(s)) {
|
if (fp_access_check(s)) {
|
||||||
TCGv_i32 t = read_fp_hreg(s, a->rn);
|
TCGv_i32 t = read_fp_hreg(s, a->rn);
|
||||||
f->gen_h(t, t);
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -8464,21 +8477,21 @@ static const FPScalar1Int f_scalar_fmov = {
|
|||||||
tcg_gen_mov_i32,
|
tcg_gen_mov_i32,
|
||||||
tcg_gen_mov_i64,
|
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 = {
|
static const FPScalar1Int f_scalar_fabs = {
|
||||||
gen_vfp_absh,
|
gen_vfp_absh,
|
||||||
gen_vfp_abss,
|
gen_vfp_abss,
|
||||||
gen_vfp_absd,
|
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 = {
|
static const FPScalar1Int f_scalar_fneg = {
|
||||||
gen_vfp_negh,
|
gen_vfp_negh,
|
||||||
gen_vfp_negs,
|
gen_vfp_negs,
|
||||||
gen_vfp_negd,
|
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 {
|
typedef struct FPScalar1 {
|
||||||
void (*gen_h)(TCGv_i32, TCGv_i32, TCGv_ptr);
|
void (*gen_h)(TCGv_i32, TCGv_i32, TCGv_ptr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user