@samitouri / QOSamiQemu / commits / dddee8e1ba

fpu/softfloat: Refactor floatx80 format NaN classification to share code

The floatx80_is_[quiet|signaling]_nan functions contain duplicated logic that should be shared. This commit introduces floatx80_nan_is_snan helper function that determine if a NaN is signaling and change the return type of floatx80_is_[signaling|quiet]_nan to bool. Suggested-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Max Chou <max.chou@sifive.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Chao Liu <chao.liu.zevorn@gmail.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-ID: <20260204051756.667397-4-max.chou@sifive.com>

Max Chou committed Feb 4, 2026 at 13:17 UTC dddee8e1ba3e53e8a8e0718943e5e585c731804e
2 files changed +22 -37
fpu/softfloat-specialize.c.inc
+20 -35
@@ -357,53 +357,38 @@ bool float64_is_signaling_nan(float64 a_, float_status *status)
357 }
358
359 /*----------------------------------------------------------------------------
360 -| Returns 1 if the extended double-precision floating-point value `a' is a
361 -| quiet NaN; otherwise returns 0. This slightly differs from the same
362 -| function for other types as floatx80 has an explicit bit.
360 +| Determine if a floatx80 NaN is signaling NaN.
361 +| The MSB of frac differs from the same function for other types as floatx80
362 +| has an explicit bit.
363 *----------------------------------------------------------------------------*/
364
365 -int floatx80_is_quiet_nan(floatx80 a, float_status *status)
365 +static bool floatx80_nan_is_snan(floatx80 a, float_status *status)
366 {
367 if (no_signaling_nans(status)) {
368 - return floatx80_is_any_nan(a);
369 - } else {
370 - if (snan_bit_is_one(status)) {
371 - uint64_t aLow;
372 -
373 - aLow = a.low & ~0x4000000000000000ULL;
374 - return ((a.high & 0x7FFF) == 0x7FFF)
375 - && (aLow << 1)
376 - && (a.low == aLow);
377 - } else {
378 - return ((a.high & 0x7FFF) == 0x7FFF)
379 - && (UINT64_C(0x8000000000000000) <= ((uint64_t)(a.low << 1)));
380 - }
368 + return false;
369 }
370 + bool frac_msb_is_one = (a.low >> 62) & 1;
371 + return frac_msb_is_one == snan_bit_is_one(status);
372 }
373
374 /*----------------------------------------------------------------------------
375 | Returns 1 if the extended double-precision floating-point value `a' is a
386 -| signaling NaN; otherwise returns 0. This slightly differs from the same
387 -| function for other types as floatx80 has an explicit bit.
376 +| quiet NaN; otherwise returns 0.
377 *----------------------------------------------------------------------------*/
378
390 -int floatx80_is_signaling_nan(floatx80 a, float_status *status)
379 +bool floatx80_is_quiet_nan(floatx80 a, float_status *status)
380 {
392 - if (no_signaling_nans(status)) {
393 - return 0;
394 - } else {
395 - if (snan_bit_is_one(status)) {
396 - return ((a.high & 0x7FFF) == 0x7FFF)
397 - && ((a.low << 1) >= 0x8000000000000000ULL);
398 - } else {
399 - uint64_t aLow;
400 -
401 - aLow = a.low & ~UINT64_C(0x4000000000000000);
402 - return ((a.high & 0x7FFF) == 0x7FFF)
403 - && (uint64_t)(aLow << 1)
404 - && (a.low == aLow);
405 - }
406 - }
381 + return floatx80_is_any_nan(a) && !floatx80_nan_is_snan(a, status);
382 +}
383 +
384 +/*----------------------------------------------------------------------------
385 +| Returns 1 if the extended double-precision floating-point value `a' is a
386 +| signaling NaN; otherwise returns 0.
387 +*----------------------------------------------------------------------------*/
388 +
389 +bool floatx80_is_signaling_nan(floatx80 a, float_status *status)
390 +{
391 + return floatx80_is_any_nan(a) && floatx80_nan_is_snan(a, status);
392 }
393
394 /*----------------------------------------------------------------------------
include/fpu/softfloat.h
+2 -2
@@ -978,8 +978,8 @@ floatx80 floatx80_rem(floatx80, floatx80, float_status *status);
978 floatx80 floatx80_sqrt(floatx80, float_status *status);
979 FloatRelation floatx80_compare(floatx80, floatx80, float_status *status);
980 FloatRelation floatx80_compare_quiet(floatx80, floatx80, float_status *status);
981 -int floatx80_is_quiet_nan(floatx80, float_status *status);
982 -int floatx80_is_signaling_nan(floatx80, float_status *status);
981 +bool floatx80_is_quiet_nan(floatx80, float_status *status);
982 +bool floatx80_is_signaling_nan(floatx80, float_status *status);
983 floatx80 floatx80_silence_nan(floatx80, float_status *status);
984 floatx80 floatx80_scalbn(floatx80, int, float_status *status);
985