summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2005-03-07 04:55:58 +0000
committerdas <das@FreeBSD.org>2005-03-07 04:55:58 +0000
commite1ac3a8c058a65b02d6664528411d6469e711412 (patch)
treef8c4ac60ad06be68b4ec26babec5d15e6075c461 /lib
parent4d2ad621bf42c8dfb26c6371162292b6d9077822 (diff)
downloadFreeBSD-src-e1ac3a8c058a65b02d6664528411d6469e711412.zip
FreeBSD-src-e1ac3a8c058a65b02d6664528411d6469e711412.tar.gz
- Try harder to trick gcc into not optimizing away statements
that are intended to raise underflow and inexact exceptions. - On systems where long double is the same as double, nextafter should be aliased as nexttoward, nexttowardl, and nextafterl.
Diffstat (limited to 'lib')
-rw-r--r--lib/msun/src/s_nextafter.c18
-rw-r--r--lib/msun/src/s_nextafterf.c9
2 files changed, 19 insertions, 8 deletions
diff --git a/lib/msun/src/s_nextafter.c b/lib/msun/src/s_nextafter.c
index 4fc5b77..a235099 100644
--- a/lib/msun/src/s_nextafter.c
+++ b/lib/msun/src/s_nextafter.c
@@ -21,12 +21,16 @@ static char rcsid[] = "$FreeBSD$";
* Special cases:
*/
+#include <sys/cdefs.h>
+#include <float.h>
+
#include "math.h"
#include "math_private.h"
double
nextafter(double x, double y)
{
+ volatile double t;
int32_t hx,hy,ix,iy;
u_int32_t lx,ly;
@@ -41,8 +45,8 @@ nextafter(double x, double y)
if(x==y) return y; /* x=y, return y */
if((ix|lx)==0) { /* x == 0 */
INSERT_WORDS(x,hy&0x80000000,1); /* return +-minsubnormal */
- y = x*x;
- if(y==x) return y; else return x; /* raise underflow flag */
+ t = x*x;
+ if(t==x) return t; else return x; /* raise underflow flag */
}
if(hx>=0) { /* x > 0 */
if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */
@@ -64,8 +68,8 @@ nextafter(double x, double y)
hy = hx&0x7ff00000;
if(hy>=0x7ff00000) return x+x; /* overflow */
if(hy<0x00100000) { /* underflow */
- y = x*x;
- if(y!=x) { /* raise underflow flag */
+ t = x*x;
+ if(t!=x) { /* raise underflow flag */
INSERT_WORDS(y,hx,lx);
return y;
}
@@ -73,3 +77,9 @@ nextafter(double x, double y)
INSERT_WORDS(x,hx,lx);
return x;
}
+
+#if (LDBL_MANT_DIG == 53)
+__strong_reference(nextafter, nexttoward);
+__strong_reference(nextafter, nexttowardl);
+__strong_reference(nextafter, nextafterl);
+#endif
diff --git a/lib/msun/src/s_nextafterf.c b/lib/msun/src/s_nextafterf.c
index c4032e9..b8a1125 100644
--- a/lib/msun/src/s_nextafterf.c
+++ b/lib/msun/src/s_nextafterf.c
@@ -23,6 +23,7 @@ static char rcsid[] = "$FreeBSD$";
float
nextafterf(float x, float y)
{
+ volatile float t;
int32_t hx,hy,ix,iy;
GET_FLOAT_WORD(hx,x);
@@ -36,8 +37,8 @@ nextafterf(float x, float y)
if(x==y) return y; /* x=y, return y */
if(ix==0) { /* x == 0 */
SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */
- y = x*x;
- if(y==x) return y; else return x; /* raise underflow flag */
+ t = x*x;
+ if(t==x) return t; else return x; /* raise underflow flag */
}
if(hx>=0) { /* x > 0 */
if(hx>hy) { /* x > y, x -= ulp */
@@ -55,8 +56,8 @@ nextafterf(float x, float y)
hy = hx&0x7f800000;
if(hy>=0x7f800000) return x+x; /* overflow */
if(hy<0x00800000) { /* underflow */
- y = x*x;
- if(y!=x) { /* raise underflow flag */
+ t = x*x;
+ if(t!=x) { /* raise underflow flag */
SET_FLOAT_WORD(y,hx);
return y;
}
OpenPOWER on IntegriCloud