Hexagon (target/hexagon) properly handle denorm in arch_sf_recip_common
The arch_sf_recip_common function was calling float32_getexp which adjusts for denorm, but the we actually need the raw exponent bits. This function is called from 3 instructions sfrecipa sffixupn sffixupd Test cases added to tests/tcg/hexagon/fpstuff.c Signed-off-by: Taylor Simpson <tsimpson@quicinc.com> Message-Id: <20220210021556.9217-6-tsimpson@quicinc.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
9a65990326
commit
77ccf44453
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
* Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -298,8 +298,8 @@ int arch_sf_recip_common(float32 *Rs, float32 *Rt, float32 *Rd, int *adjust,
|
||||||
} else {
|
} else {
|
||||||
PeV = 0x00;
|
PeV = 0x00;
|
||||||
/* Basic checks passed */
|
/* Basic checks passed */
|
||||||
n_exp = float32_getexp(RsV);
|
n_exp = float32_getexp_raw(RsV);
|
||||||
d_exp = float32_getexp(RtV);
|
d_exp = float32_getexp_raw(RtV);
|
||||||
if ((n_exp - d_exp + SF_BIAS) <= SF_MANTBITS) {
|
if ((n_exp - d_exp + SF_BIAS) <= SF_MANTBITS) {
|
||||||
/* Near quotient underflow / inexact Q */
|
/* Near quotient underflow / inexact Q */
|
||||||
PeV = 0x80;
|
PeV = 0x80;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
* Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -24,6 +24,10 @@ static inline bool is_finite(float64 x)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t float64_getexp(float64 f64);
|
int32_t float64_getexp(float64 f64);
|
||||||
|
static inline uint32_t float32_getexp_raw(float32 f32)
|
||||||
|
{
|
||||||
|
return extract32(f32, 23, 8);
|
||||||
|
}
|
||||||
int32_t float32_getexp(float32 f32);
|
int32_t float32_getexp(float32 f32);
|
||||||
float32 infinite_float32(uint8_t sign);
|
float32 infinite_float32(uint8_t sign);
|
||||||
float32 internal_fmafx(float32 a, float32 b, float32 c,
|
float32 internal_fmafx(float32 a, float32 b, float32 c,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright(c) 2020-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
* Copyright(c) 2020-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -38,6 +38,8 @@ const int SF_NaN_special = 0x7f800001;
|
||||||
const int SF_ANY = 0x3f800000;
|
const int SF_ANY = 0x3f800000;
|
||||||
const int SF_HEX_NAN = 0xffffffff;
|
const int SF_HEX_NAN = 0xffffffff;
|
||||||
const int SF_small_neg = 0xab98fba8;
|
const int SF_small_neg = 0xab98fba8;
|
||||||
|
const int SF_denorm = 0x00000001;
|
||||||
|
const int SF_random = 0x346001d6;
|
||||||
|
|
||||||
const long long DF_NaN = 0x7ff8000000000000ULL;
|
const long long DF_NaN = 0x7ff8000000000000ULL;
|
||||||
const long long DF_ANY = 0x3f80000000000000ULL;
|
const long long DF_ANY = 0x3f80000000000000ULL;
|
||||||
|
@ -250,10 +252,11 @@ static void check_dfminmax(void)
|
||||||
check_fpstatus(usr, FPINVF);
|
check_fpstatus(usr, FPINVF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_recip_exception(void)
|
static void check_sfrecipa(void)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
int usr;
|
int usr;
|
||||||
|
int pred;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that sfrecipa doesn't set status bits when
|
* Check that sfrecipa doesn't set status bits when
|
||||||
|
@ -329,6 +332,17 @@ static void check_recip_exception(void)
|
||||||
: "r2", "p0", "usr");
|
: "r2", "p0", "usr");
|
||||||
check32(result, 0x3f800000);
|
check32(result, 0x3f800000);
|
||||||
check_fpstatus(usr, 0);
|
check_fpstatus(usr, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that sfrecipa properly handles denorm
|
||||||
|
*/
|
||||||
|
asm (CLEAR_FPSTATUS
|
||||||
|
"%0,p0 = sfrecipa(%2, %3)\n\t"
|
||||||
|
"%1 = p0\n\t"
|
||||||
|
: "=r"(result), "=r"(pred) : "r"(SF_denorm), "r"(SF_random)
|
||||||
|
: "p0", "usr");
|
||||||
|
check32(result, 0x6a920001);
|
||||||
|
check32(pred, 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_canonical_NaN(void)
|
static void check_canonical_NaN(void)
|
||||||
|
@ -455,6 +469,28 @@ static void check_invsqrta(void)
|
||||||
check32(predval, 0x0);
|
check32(predval, 0x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_sffixupn(void)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
/* Check that sffixupn properly deals with denorm */
|
||||||
|
asm volatile("%0 = sffixupn(%1, %2)\n\t"
|
||||||
|
: "=r"(result)
|
||||||
|
: "r"(SF_random), "r"(SF_denorm));
|
||||||
|
check32(result, 0x246001d6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_sffixupd(void)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
|
||||||
|
/* Check that sffixupd properly deals with denorm */
|
||||||
|
asm volatile("%0 = sffixupd(%1, %2)\n\t"
|
||||||
|
: "=r"(result)
|
||||||
|
: "r"(SF_denorm), "r"(SF_random));
|
||||||
|
check32(result, 0x146001d6);
|
||||||
|
}
|
||||||
|
|
||||||
static void check_float2int_convs()
|
static void check_float2int_convs()
|
||||||
{
|
{
|
||||||
int res32;
|
int res32;
|
||||||
|
@ -602,9 +638,11 @@ int main()
|
||||||
check_compare_exception();
|
check_compare_exception();
|
||||||
check_sfminmax();
|
check_sfminmax();
|
||||||
check_dfminmax();
|
check_dfminmax();
|
||||||
check_recip_exception();
|
check_sfrecipa();
|
||||||
check_canonical_NaN();
|
check_canonical_NaN();
|
||||||
check_invsqrta();
|
check_invsqrta();
|
||||||
|
check_sffixupn();
|
||||||
|
check_sffixupd();
|
||||||
check_float2int_convs();
|
check_float2int_convs();
|
||||||
|
|
||||||
puts(err ? "FAIL" : "PASS");
|
puts(err ? "FAIL" : "PASS");
|
||||||
|
|
Loading…
Reference in New Issue