mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-22 17:42:10 -06:00
target/arm: Handle FPCR.AH in negation in FMLS (vector)
Handle the FPCR.AH "don't negate the sign of a NaN" semantics in FMLS (vector), by implementing a new set of helpers for the AH=1 case. The float_muladd_negate_product flag produces the same result as negating either of the multiplication operands, assuming neither of the operands are NaNs. But since FEAT_AFP does not negate NaNs, this behaviour is exactly what we need. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
b85d8684c5
commit
1fae4f5e9f
3 changed files with 32 additions and 1 deletions
|
@ -782,6 +782,10 @@ DEF_HELPER_FLAGS_5(gvec_vfms_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
|
||||||
DEF_HELPER_FLAGS_5(gvec_vfms_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
|
DEF_HELPER_FLAGS_5(gvec_vfms_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
|
||||||
DEF_HELPER_FLAGS_5(gvec_vfms_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
|
DEF_HELPER_FLAGS_5(gvec_vfms_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
|
||||||
|
|
||||||
|
DEF_HELPER_FLAGS_5(gvec_ah_vfms_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
|
||||||
|
DEF_HELPER_FLAGS_5(gvec_ah_vfms_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
|
||||||
|
DEF_HELPER_FLAGS_5(gvec_ah_vfms_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, fpst, i32)
|
||||||
|
|
||||||
DEF_HELPER_FLAGS_5(gvec_ftsmul_h, TCG_CALL_NO_RWG,
|
DEF_HELPER_FLAGS_5(gvec_ftsmul_h, TCG_CALL_NO_RWG,
|
||||||
void, ptr, ptr, ptr, fpst, i32)
|
void, ptr, ptr, ptr, fpst, i32)
|
||||||
DEF_HELPER_FLAGS_5(gvec_ftsmul_s, TCG_CALL_NO_RWG,
|
DEF_HELPER_FLAGS_5(gvec_ftsmul_s, TCG_CALL_NO_RWG,
|
||||||
|
|
|
@ -5860,7 +5860,12 @@ static gen_helper_gvec_3_ptr * const f_vector_fmls[3] = {
|
||||||
gen_helper_gvec_vfms_s,
|
gen_helper_gvec_vfms_s,
|
||||||
gen_helper_gvec_vfms_d,
|
gen_helper_gvec_vfms_d,
|
||||||
};
|
};
|
||||||
TRANS(FMLS_v, do_fp3_vector, a, 0, f_vector_fmls)
|
static gen_helper_gvec_3_ptr * const f_vector_fmls_ah[3] = {
|
||||||
|
gen_helper_gvec_ah_vfms_h,
|
||||||
|
gen_helper_gvec_ah_vfms_s,
|
||||||
|
gen_helper_gvec_ah_vfms_d,
|
||||||
|
};
|
||||||
|
TRANS(FMLS_v, do_fp3_vector_2fn, a, 0, f_vector_fmls, f_vector_fmls_ah)
|
||||||
|
|
||||||
static gen_helper_gvec_3_ptr * const f_vector_fcmeq[3] = {
|
static gen_helper_gvec_3_ptr * const f_vector_fcmeq[3] = {
|
||||||
gen_helper_gvec_fceq_h,
|
gen_helper_gvec_fceq_h,
|
||||||
|
|
|
@ -1558,6 +1558,24 @@ static float64 float64_mulsub_f(float64 dest, float64 op1, float64 op2,
|
||||||
return float64_muladd(float64_chs(op1), op2, dest, 0, stat);
|
return float64_muladd(float64_chs(op1), op2, dest, 0, stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float16 float16_ah_mulsub_f(float16 dest, float16 op1, float16 op2,
|
||||||
|
float_status *stat)
|
||||||
|
{
|
||||||
|
return float16_muladd(op1, op2, dest, float_muladd_negate_product, stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float32 float32_ah_mulsub_f(float32 dest, float32 op1, float32 op2,
|
||||||
|
float_status *stat)
|
||||||
|
{
|
||||||
|
return float32_muladd(op1, op2, dest, float_muladd_negate_product, stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float64 float64_ah_mulsub_f(float64 dest, float64 op1, float64 op2,
|
||||||
|
float_status *stat)
|
||||||
|
{
|
||||||
|
return float64_muladd(op1, op2, dest, float_muladd_negate_product, stat);
|
||||||
|
}
|
||||||
|
|
||||||
#define DO_MULADD(NAME, FUNC, TYPE) \
|
#define DO_MULADD(NAME, FUNC, TYPE) \
|
||||||
void HELPER(NAME)(void *vd, void *vn, void *vm, \
|
void HELPER(NAME)(void *vd, void *vn, void *vm, \
|
||||||
float_status *stat, uint32_t desc) \
|
float_status *stat, uint32_t desc) \
|
||||||
|
@ -1584,6 +1602,10 @@ DO_MULADD(gvec_vfms_h, float16_mulsub_f, float16)
|
||||||
DO_MULADD(gvec_vfms_s, float32_mulsub_f, float32)
|
DO_MULADD(gvec_vfms_s, float32_mulsub_f, float32)
|
||||||
DO_MULADD(gvec_vfms_d, float64_mulsub_f, float64)
|
DO_MULADD(gvec_vfms_d, float64_mulsub_f, float64)
|
||||||
|
|
||||||
|
DO_MULADD(gvec_ah_vfms_h, float16_ah_mulsub_f, float16)
|
||||||
|
DO_MULADD(gvec_ah_vfms_s, float32_ah_mulsub_f, float32)
|
||||||
|
DO_MULADD(gvec_ah_vfms_d, float64_ah_mulsub_f, float64)
|
||||||
|
|
||||||
/* For the indexed ops, SVE applies the index per 128-bit vector segment.
|
/* For the indexed ops, SVE applies the index per 128-bit vector segment.
|
||||||
* For AdvSIMD, there is of course only one such vector segment.
|
* For AdvSIMD, there is of course only one such vector segment.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue