forked from iains/gcc-14-branch
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
libquadmath: Use soft-fp for sqrtq finite positive arguments [PR114623]
sqrt should be 0.5ulp precise, but the current implementation is less precise than that. The following patch uses the soft-fp code (like e.g. glibc for x86) for it if possible. I didn't want to replicate the libgcc infrastructure for choosing the right sfp-machine.h, so the patch just uses a single generic implementation. As the code is used solely for the finite positive arguments, it shouldn't generate NaNs (so the exact form of canonical QNaN/SNaN is irrelevant), and sqrt for these shouldn't produce underflows/overflows either, for < 1.0 arguments it always returns larger values than the argument and for > 1.0 smaller values than the argument. 2024-04-09 Jakub Jelinek <[email protected]> PR libquadmath/114623 * sfp-machine.h: New file. * math/sqrtq.c: Include from libgcc/soft-fp also soft-fp.h and quad.h if possible. (USE_SOFT_FP): Define in that case. (sqrtq): Use soft-fp based implementation for the finite positive arguments if possible.
1 parent
18e94e0
commit 481ba4f
Showing
2 changed files
with
78 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* libquadmath uses soft-fp only for sqrtq and only for | ||
the positive finite case, so it doesn't care about | ||
NaN representation, nor tininess after rounding vs. | ||
before rounding, all it cares about is current rounding | ||
mode and raising inexact exceptions. */ | ||
#if __SIZEOF_LONG__ == 8 | ||
#define _FP_W_TYPE_SIZE 64 | ||
#define _FP_I_TYPE long long | ||
#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0 | ||
#else | ||
#define _FP_W_TYPE_SIZE 32 | ||
#define _FP_I_TYPE int | ||
#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0 | ||
#endif | ||
#define _FP_W_TYPE unsigned _FP_I_TYPE | ||
#define _FP_WS_TYPE signed _FP_I_TYPE | ||
#define _FP_QNANNEGATEDP 0 | ||
#define _FP_NANSIGN_Q 1 | ||
#define _FP_KEEPNANFRACP 1 | ||
#define _FP_TININESS_AFTER_ROUNDING 0 | ||
#define _FP_DECL_EX \ | ||
unsigned int fp_roundmode __attribute__ ((unused)) = FP_RND_NEAREST; | ||
#define FP_ROUNDMODE fp_roundmode | ||
#define FP_INIT_ROUNDMODE \ | ||
do \ | ||
{ \ | ||
switch (fegetround ()) \ | ||
{ \ | ||
case FE_UPWARD: \ | ||
fp_roundmode = FP_RND_PINF; \ | ||
break; \ | ||
case FE_DOWNWARD: \ | ||
fp_roundmode = FP_RND_MINF; \ | ||
break; \ | ||
case FE_TOWARDZERO: \ | ||
fp_roundmode = FP_RND_ZERO; \ | ||
break; \ | ||
default: \ | ||
break; \ | ||
} \ | ||
} \ | ||
while (0) | ||
#define FP_HANDLE_EXCEPTIONS \ | ||
do \ | ||
{ \ | ||
if (_fex & FP_EX_INEXACT) \ | ||
{ \ | ||
volatile double eight = 8.0; \ | ||
volatile double eps \ | ||
= DBL_EPSILON; \ | ||
eight += eps; \ | ||
} \ | ||
} \ | ||
while (0) |