Message ID | 20241208224844.570491-16-richard.henderson@linaro.org |
---|---|
State | New |
Headers | show |
Series | softfloat, hexagon: Cleanup fmaf | expand |
On 12/8/2024 4:48 PM, Richard Henderson wrote: > This structure, with bitfields, is incorrect for big-endian. > Use extract64 and deposit64 instead. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/hexagon/fma_emu.c | 46 ++++++++++++++-------------------------- > 1 file changed, 16 insertions(+), 30 deletions(-) > > diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c > index c359eecffd..343c40a686 100644 > --- a/target/hexagon/fma_emu.c > +++ b/target/hexagon/fma_emu.c > @@ -43,39 +43,29 @@ > > #define WAY_BIG_EXP 4096 > > -typedef union { > - double f; > - uint64_t i; > - struct { > - uint64_t mant:52; > - uint64_t exp:11; > - uint64_t sign:1; > - }; > -} Double; > - > static uint64_t float64_getmant(float64 f64) > { > - Double a = { .i = f64 }; > + uint64_t mant = extract64(f64, 0, 52); > if (float64_is_normal(f64)) { > - return a.mant | 1ULL << 52; > + return mant | 1ULL << 52; > } > if (float64_is_zero(f64)) { > return 0; > } > if (float64_is_denormal(f64)) { > - return a.mant; > + return mant; > } > return ~0ULL; > } > > int32_t float64_getexp(float64 f64) > { > - Double a = { .i = f64 }; > + int exp = extract64(f64, 52, 11); > if (float64_is_normal(f64)) { > - return a.exp; > + return exp; > } > if (float64_is_denormal(f64)) { > - return a.exp + 1; > + return exp + 1; > } > return -1; > } > @@ -346,6 +336,8 @@ float32 infinite_float32(uint8_t sign) > /* Return a maximum finite value with the requested sign */ > static float64 accum_round_float64(Accum a, float_status * fp_status) > { > + uint64_t ret; > + > if ((int128_gethi(a.mant) == 0) && (int128_getlo(a.mant) == 0) > && ((a.guard | a.round | a.sticky) == 0)) { > /* result zero */ > @@ -453,22 +445,16 @@ static float64 accum_round_float64(Accum a, float_status * fp_status) > } > } > /* Underflow? */ > - if (int128_getlo(a.mant) & (1ULL << DF_MANTBITS)) { > + ret = int128_getlo(a.mant); > + if (ret & (1ULL << DF_MANTBITS)) { > /* Leading one means: No, we're normal. So, we should be done... */ > - Double ret; > - ret.i = 0; > - ret.sign = a.sign; > - ret.exp = a.exp; > - ret.mant = int128_getlo(a.mant); > - return ret.i; > + ret = deposit64(ret, 52, 11, a.exp); > + } else { > + assert(a.exp == 1); > + ret = deposit64(ret, 52, 11, 0); > } > - assert(a.exp == 1); > - Double ret; > - ret.i = 0; > - ret.sign = a.sign; > - ret.exp = 0; > - ret.mant = int128_getlo(a.mant); > - return ret.i; > + ret = deposit64(ret, 63, 1, a.sign); > + return ret; > } > > float64 internal_mpyhh(float64 a, float64 b, Reviewed-by: Brian Cain <brian.cain@oss.qualcomm.com>
diff --git a/target/hexagon/fma_emu.c b/target/hexagon/fma_emu.c index c359eecffd..343c40a686 100644 --- a/target/hexagon/fma_emu.c +++ b/target/hexagon/fma_emu.c @@ -43,39 +43,29 @@ #define WAY_BIG_EXP 4096 -typedef union { - double f; - uint64_t i; - struct { - uint64_t mant:52; - uint64_t exp:11; - uint64_t sign:1; - }; -} Double; - static uint64_t float64_getmant(float64 f64) { - Double a = { .i = f64 }; + uint64_t mant = extract64(f64, 0, 52); if (float64_is_normal(f64)) { - return a.mant | 1ULL << 52; + return mant | 1ULL << 52; } if (float64_is_zero(f64)) { return 0; } if (float64_is_denormal(f64)) { - return a.mant; + return mant; } return ~0ULL; } int32_t float64_getexp(float64 f64) { - Double a = { .i = f64 }; + int exp = extract64(f64, 52, 11); if (float64_is_normal(f64)) { - return a.exp; + return exp; } if (float64_is_denormal(f64)) { - return a.exp + 1; + return exp + 1; } return -1; } @@ -346,6 +336,8 @@ float32 infinite_float32(uint8_t sign) /* Return a maximum finite value with the requested sign */ static float64 accum_round_float64(Accum a, float_status * fp_status) { + uint64_t ret; + if ((int128_gethi(a.mant) == 0) && (int128_getlo(a.mant) == 0) && ((a.guard | a.round | a.sticky) == 0)) { /* result zero */ @@ -453,22 +445,16 @@ static float64 accum_round_float64(Accum a, float_status * fp_status) } } /* Underflow? */ - if (int128_getlo(a.mant) & (1ULL << DF_MANTBITS)) { + ret = int128_getlo(a.mant); + if (ret & (1ULL << DF_MANTBITS)) { /* Leading one means: No, we're normal. So, we should be done... */ - Double ret; - ret.i = 0; - ret.sign = a.sign; - ret.exp = a.exp; - ret.mant = int128_getlo(a.mant); - return ret.i; + ret = deposit64(ret, 52, 11, a.exp); + } else { + assert(a.exp == 1); + ret = deposit64(ret, 52, 11, 0); } - assert(a.exp == 1); - Double ret; - ret.i = 0; - ret.sign = a.sign; - ret.exp = 0; - ret.mant = int128_getlo(a.mant); - return ret.i; + ret = deposit64(ret, 63, 1, a.sign); + return ret; } float64 internal_mpyhh(float64 a, float64 b,
This structure, with bitfields, is incorrect for big-endian. Use extract64 and deposit64 instead. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/hexagon/fma_emu.c | 46 ++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 30 deletions(-)