Restore buildworld from clang (adjust libm)
authorJohn Marino <draco@marino.st>
Sat, 14 Nov 2015 17:12:05 +0000 (18:12 +0100)
committerJohn Marino <draco@marino.st>
Sat, 14 Nov 2015 20:03:46 +0000 (21:03 +0100)
Functions like "isinff" come from GCC only, causes a missed reference when
the world is built with clang.  To solve, bring back FreeBSD versions of
round(|f|l).  An additional benefit is that these functions appear to be
improved over the OpenBSD versions (avoids unnecessary conversions).  The
FreeBSD roundl uses ENTERI/RETURNI macros so I left these off meaning DF
will still not able to raise exceptions on roundl.

Since isinff and friends are no longer used, clang can continue further with
building the world.

contrib/openbsd_libm/src/s_round.c
contrib/openbsd_libm/src/s_roundf.c
contrib/openbsd_libm/src/s_roundl.c

index ce7eb92..bd1d73c 100644 (file)
@@ -35,19 +35,21 @@ double
 round(double x)
 {
        double t;
+       uint32_t hx;
 
-       if (isinf(x) || isnan(x))
-               return (x);
+       GET_HIGH_WORD(hx, x);
+       if ((hx & 0x7fffffff) == 0x7ff00000)
+               return (x + x);
 
-       if (x >= 0.0) {
+       if (!(hx & 0x80000000)) {
                t = floor(x);
                if (t - x <= -0.5)
-                       t += 1.0;
+                       t += 1;
                return (t);
        } else {
                t = floor(-x);
                if (t + x <= -0.5)
-                       t += 1.0;
+                       t += 1;
                return (-t);
        }
 }
index f56d218..d6527ec 100644 (file)
@@ -33,19 +33,21 @@ float
 roundf(float x)
 {
        float t;
+       uint32_t hx;
 
-       if (isinff(x) || isnanf(x))
-               return (x);
+       GET_FLOAT_WORD(hx, x);
+       if ((hx & 0x7fffffff) == 0x7f800000)
+               return (x + x);
 
-       if (x >= 0.0) {
+       if (!(hx & 0x80000000)) {
                t = floorf(x);
-               if (t - x <= -0.5)
-                       t += 1.0;
+               if (t - x <= -0.5F)
+                       t += 1;
                return (t);
        } else {
                t = floorf(-x);
-               if (t + x <= -0.5)
-                       t += 1.0;
+               if (t + x <= -0.5F)
+                       t += 1;
                return (-t);
        }
 }
index b893f31..481a14b 100644 (file)
  */
 
 #include <math.h>
+#include "math_private.h"
 
 long double
 roundl(long double x)
 {
        long double t;
+       uint16_t hx;
 
-       if (!isfinite(x))
-               return (x);
+       GET_LDOUBLE_EXP(hx, x);
+       if ((hx & 0x7fff) == 0x7fff)
+               return (x + x);
 
-       if (x >= 0.0) {
+
+       if (!(hx & 0x8000)) {
                t = floorl(x);
-               if (t - x <= -0.5)
-                       t += 1.0;
+               if (t - x <= -0.5L)
+                       t += 1;
                return (t);
        } else {
                t = floorl(-x);
-               if (t + x <= -0.5)
-                       t += 1.0;
+               if (t + x <= -0.5L)
+                       t += 1;
                return (-t);
        }
 }