Hexagon (target/hexagon) Change subtract from zero to change sign
The F2_sffms instruction [r0 -= sfmpy(r1, r2)] doesn't properly handle -0. Previously we would negate the input operand by subtracting from zero. Instead, we negate by changing the sign bit. Test case added to tests/tcg/hexagon/fpstuff.c Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Reviewed-by: Anton Johansson <anjo@rev.ng> Message-Id: <20230307025828.1612809-12-tsimpson@quicinc.com>
This commit is contained in:
parent
1c629814f7
commit
1a442c0931
|
@ -1169,7 +1169,7 @@ float32 HELPER(sffms)(CPUHexagonState *env, float32 RxV,
|
|||
{
|
||||
float32 neg_RsV;
|
||||
arch_fpop_start(env);
|
||||
neg_RsV = float32_sub(float32_zero, RsV, &env->fp_status);
|
||||
neg_RsV = float32_set_sign(RsV, float32_is_neg(RsV) ? 0 : 1);
|
||||
RxV = internal_fmafx(neg_RsV, RtV, RxV, 0, &env->fp_status);
|
||||
arch_fpop_end(env);
|
||||
return RxV;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright(c) 2020-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||
* Copyright(c) 2020-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -40,6 +40,7 @@ const int SF_HEX_NAN = 0xffffffff;
|
|||
const int SF_small_neg = 0xab98fba8;
|
||||
const int SF_denorm = 0x00000001;
|
||||
const int SF_random = 0x346001d6;
|
||||
const int SF_neg_zero = 0x80000000;
|
||||
|
||||
const long long DF_QNaN = 0x7ff8000000000000ULL;
|
||||
const long long DF_SNaN = 0x7ff7000000000000ULL;
|
||||
|
@ -536,6 +537,33 @@ static void check_sffixupd(void)
|
|||
check32(result, 0x146001d6);
|
||||
}
|
||||
|
||||
static void check_sffms(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
/* Check that sffms properly deals with -0 */
|
||||
result = SF_neg_zero;
|
||||
asm ("%0 -= sfmpy(%1 , %2)\n\t"
|
||||
: "+r"(result)
|
||||
: "r"(SF_ZERO), "r"(SF_ZERO)
|
||||
: "r12", "r8");
|
||||
check32(result, SF_neg_zero);
|
||||
|
||||
result = SF_ZERO;
|
||||
asm ("%0 -= sfmpy(%1 , %2)\n\t"
|
||||
: "+r"(result)
|
||||
: "r"(SF_neg_zero), "r"(SF_ZERO)
|
||||
: "r12", "r8");
|
||||
check32(result, SF_ZERO);
|
||||
|
||||
result = SF_ZERO;
|
||||
asm ("%0 -= sfmpy(%1 , %2)\n\t"
|
||||
: "+r"(result)
|
||||
: "r"(SF_ZERO), "r"(SF_neg_zero)
|
||||
: "r12", "r8");
|
||||
check32(result, SF_ZERO);
|
||||
}
|
||||
|
||||
static void check_float2int_convs()
|
||||
{
|
||||
int res32;
|
||||
|
@ -688,6 +716,7 @@ int main()
|
|||
check_invsqrta();
|
||||
check_sffixupn();
|
||||
check_sffixupd();
|
||||
check_sffms();
|
||||
check_float2int_convs();
|
||||
|
||||
puts(err ? "FAIL" : "PASS");
|
||||
|
|
Loading…
Reference in New Issue