alpha: Fixes for v7.4

Make the FP emulation determine tininess after rounding, as the hardware
 does.  soft-fp always determined it before rounding, so an operation that
 trapped for software completion could report an underflow the same
 operation would not report when it did not trap.  glibc's math testsuite
 catches the disagreement.
 
 This adds _FP_TININESS_AFTER_ROUNDING to the shared soft-fp code in
 include/math-emu/, as glibc's copy already has, and sets it only for
 alpha.  It defaults to zero, so powerpc, sh and sparc are unchanged.
 
 This is the last patch of a three-patch series; the first two were
 merged for v7.3.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iPEEABYKAJkWIQReryEEmoa4pUzLG/qs6yl0DJpOlwUCatgX0RsUgAAAAAAEAA5t
 YW51MiwyLjUrMS4xMiwyLDJfFIAAAAAALgAoaXNzdWVyLWZwckBub3RhdGlvbnMu
 b3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldDVFQUYyMTA0OUE4NkI4QTU0Q0NCMUJG
 QUFDRUIyOTc0MEM5QTRFOTcACgkQrOspdAyaTpcd4gEA0gQ6thmKEAmN/TyGgbUT
 Bvu9gkJXONuHo/ZoVa5ntp4A/jnLYnzV9DInWCvU/83mbpLFWvwqMmQYK9+/Juxj
 d3kD
 =5e8M
 -----END PGP SIGNATURE-----

Merge tag 'alpha-fixes-v7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mattst88/alpha

Pull alpha floating point emulation fix from Matt Turner:
 "Make the FP emulation determine tininess after rounding, as the
  hardware does.

  soft-fp always determined it before rounding, so an operation that
  trapped for software completion could report an underflow the same
  operation would not report when it did not trap. glibc's math
  testsuite catches the disagreement.

  This adds _FP_TININESS_AFTER_ROUNDING to the shared soft-fp code in
  include/math-emu/, as glibc's copy already has, and sets it only for
  alpha. It defaults to zero, so powerpc, sh and sparc are unchanged.

  This is the last patch of a three-patch series; the first two were
  merged for v7.3"

* tag 'alpha-fixes-v7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/mattst88/alpha:
  alpha: determine tininess after rounding in the FP emulation
This commit is contained in:
Linus Torvalds 2026-10-22 08:02:35 -10:00
commit 979fac3eaa
3 changed files with 33 additions and 2 deletions

View File

@ -59,6 +59,10 @@
R##_c = FP_CLS_NAN; \
} while (0)
/* Alpha determines tininess after rounding, so the emulation must do the
same as the hardware does for the results it produces itself. */
#define _FP_TININESS_AFTER_ROUNDING 1
/* Obtain the current rounding mode. */
#define FP_ROUNDMODE mode
#define FP_RND_NEAREST (FPCR_DYN_NORMAL >> FPCR_DYN_SHIFT)

View File

@ -135,6 +135,24 @@ do { \
else \
{ \
/* we've got a denormalized number */ \
int _FP_PACK_CANONICAL_is_tiny = 1; \
if (_FP_TININESS_AFTER_ROUNDING && X##_e == 0) \
{ \
/* Architectures that detect tininess after rounding \
only signal underflow if the result is still \
subnormal once rounded as if the exponent range \
were unbounded. Round a copy to find out. */ \
FP_DECL_##fs(_FP_PACK_CANONICAL_T); \
/* The class field is not used by the rounding below, \
and is unused entirely where this block is dead. */ \
(void)_FP_PACK_CANONICAL_T##_c; \
_FP_FRAC_COPY_##wc(_FP_PACK_CANONICAL_T, X); \
_FP_PACK_CANONICAL_T##_s = X##_s; \
_FP_PACK_CANONICAL_T##_e = X##_e; \
_FP_ROUND(wc, _FP_PACK_CANONICAL_T); \
if (_FP_FRAC_OVERP_##wc(fs, _FP_PACK_CANONICAL_T)) \
_FP_PACK_CANONICAL_is_tiny = 0; \
} \
X##_e = -X##_e + 1; \
if (X##_e <= _FP_WFRACBITS_##fs) \
{ \
@ -161,8 +179,9 @@ do { \
_FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
} \
} \
if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) || \
(FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \
if (_FP_PACK_CANONICAL_is_tiny \
&& ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) || \
(FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))) \
FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \
} \
else \

View File

@ -31,6 +31,14 @@
#include <endian.h>
#endif
/* Whether the architecture determines tininess of a floating-point
result after rounding rather than before it. IEEE 754 permits either
but requires the same choice for every operation, so this has to agree
with what the hardware does for the results it produces itself. */
#ifndef _FP_TININESS_AFTER_ROUNDING
#define _FP_TININESS_AFTER_ROUNDING 0
#endif
#define _FP_WORKBITS 3
#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3)
#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2)