summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2005-01-11 23:12:55 +0000
committerdas <das@FreeBSD.org>2005-01-11 23:12:55 +0000
commit75bc489b6d03d2c16b15aaef653ed2c8c6a75694 (patch)
treef42f6e21c95b34f19074c7e2bd39938f6a3f9886 /lib
parent0a78d59d1fb4973a45e66d96381e83171e30f3df (diff)
downloadFreeBSD-src-75bc489b6d03d2c16b15aaef653ed2c8c6a75694.zip
FreeBSD-src-75bc489b6d03d2c16b15aaef653ed2c8c6a75694.tar.gz
Add MI implementations of [l]lrint[f]() and [l]lround[f]().
Discussed with: bde
Diffstat (limited to 'lib')
-rw-r--r--lib/msun/Makefile11
-rw-r--r--lib/msun/src/math.h8
-rw-r--r--lib/msun/src/s_llrint.c9
-rw-r--r--lib/msun/src/s_llrintf.c9
-rw-r--r--lib/msun/src/s_llround.c11
-rw-r--r--lib/msun/src/s_llroundf.c11
-rw-r--r--lib/msun/src/s_lrint.c58
-rw-r--r--lib/msun/src/s_lrintf.c9
-rw-r--r--lib/msun/src/s_lround.c67
-rw-r--r--lib/msun/src/s_lroundf.c11
10 files changed, 200 insertions, 4 deletions
diff --git a/lib/msun/Makefile b/lib/msun/Makefile
index 712f0c2..209ea4e 100644
--- a/lib/msun/Makefile
+++ b/lib/msun/Makefile
@@ -52,7 +52,7 @@ ARCH_SRCS = s_copysign.S s_copysignf.S
ARCH_SUBDIR= i387
ARCH_SRCS = e_acos.S e_asin.S e_atan2.S e_exp.S e_fmod.S e_log.S e_log10.S \
e_remainder.S e_scalb.S e_sqrt.S s_atan.S s_ceil.S s_copysign.S \
- s_cos.S s_finite.S s_floor.S s_logb.S \
+ s_cos.S s_finite.S s_floor.S s_llrint.S s_logb.S s_lrint.S \
s_rint.S s_scalbn.S s_significand.S s_sin.S s_tan.S
# Broken:
# ARCH_SRCS+= s_log1p.S
@@ -86,8 +86,9 @@ COMMON_SRCS= b_exp.c b_log.c b_tgamma.c \
s_floor.c s_floorf.c s_fmax.c s_fmaxf.c s_fmaxl.c s_fmin.c \
s_fminf.c s_fminl.c s_frexp.c s_frexpf.c s_ilogb.c s_ilogbf.c \
s_ilogbl.c s_isfinite.c s_isnan.c s_isnormal.c s_ldexpf.c \
- s_lib_version.c s_log1p.c \
- s_log1pf.c s_logb.c s_logbf.c s_matherr.c s_modff.c \
+ s_lib_version.c s_llrint.c s_llrintf.c s_llround.c s_llroundf.c \
+ s_log1p.c s_log1pf.c s_logb.c s_logbf.c s_lrint.c s_lrintf.c \
+ s_lround.c s_lroundf.c s_matherr.c s_modff.c \
s_nearbyint.c s_nextafter.c s_nextafterf.c \
s_rint.c s_rintf.c s_round.c s_roundf.c \
s_scalbln.c s_scalbn.c s_scalbnf.c s_signbit.c \
@@ -132,7 +133,7 @@ INCS= fenv.h math.h
MAN= acos.3 acosh.3 asin.3 asinh.3 atan.3 atan2.3 atanh.3 ceil.3 \
cimag.3 cos.3 cosh.3 erf.3 exp.3 fabs.3 fdim.3 feclearexcept.3 \
fegetenv.3 fegetround.3 fenv.3 floor.3 fmax.3 fmod.3 hypot.3 ieee.3 \
- ieee_test.3 j0.3 lgamma.3 math.3 rint.3 round.3 \
+ ieee_test.3 j0.3 lgamma.3 lrint.3 lround.3 math.3 rint.3 round.3 \
signbit.3 sin.3 sinh.3 sqrt.3 tan.3 tanh.3 trunc.3
MLINKS+=acos.3 acosf.3
@@ -177,6 +178,8 @@ MLINKS+=ieee_test.3 significand.3 ieee_test.3 significandf.3
MLINKS+=j0.3 j1.3 j0.3 jn.3 j0.3 y0.3 j0.3 y1.3 j0.3 y1f.3 j0.3 yn.3
MLINKS+=j0.3 j0f.3 j0.3 j1f.3 j0.3 jnf.3 j0.3 y0f.3 j0.3 ynf.3
MLINKS+=lgamma.3 gamma.3 lgamma.3 gammaf.3 lgamma.3 lgammaf.3 lgamma.3 tgamma.3
+MLINKS+=lrint.3 llrint.3 lrint.3 llrintf.3 lrint.3 lrintf.3
+MLINKS+=lround.3 llround.3 lround.3 llroundf.3 lround.3 lroundf.3
MLINKS+=rint.3 rintf.3 rint.3 nearbyint.3 rint.3 nearbyintf.3
MLINKS+=round.3 roundf.3
MLINKS+=sin.3 sinf.3
diff --git a/lib/msun/src/math.h b/lib/msun/src/math.h
index 7d85545..e5d6c2b 100644
--- a/lib/msun/src/math.h
+++ b/lib/msun/src/math.h
@@ -265,8 +265,12 @@ int ilogb(double);
int (isinf)(double) __pure2;
int (isnan)(double) __pure2;
double lgamma(double);
+long long llrint(double);
+long long llround(double);
double log1p(double) __pure2;
double logb(double) __pure2;
+long lrint(double);
+long lround(double);
double nextafter(double, double);
double remainder(double, double);
double rint(double) __pure2;
@@ -368,6 +372,10 @@ float atanhf(float);
float cbrtf(float) __pure2;
float logbf(float) __pure2;
float copysignf(float, float) __pure2;
+long long llrintf(float);
+long long llroundf(float);
+long lrintf(float);
+long lroundf(float);
float nearbyintf(float) __pure2;
float nextafterf(float, float);
float remainderf(float, float);
diff --git a/lib/msun/src/s_llrint.c b/lib/msun/src/s_llrint.c
new file mode 100644
index 0000000..7c959ec
--- /dev/null
+++ b/lib/msun/src/s_llrint.c
@@ -0,0 +1,9 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define type double
+#define roundit rint
+#define dtype long long
+#define fn llrint
+
+#include "s_lrint.c"
diff --git a/lib/msun/src/s_llrintf.c b/lib/msun/src/s_llrintf.c
new file mode 100644
index 0000000..7ec6015
--- /dev/null
+++ b/lib/msun/src/s_llrintf.c
@@ -0,0 +1,9 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define type float
+#define roundit rintf
+#define dtype long long
+#define fn llrintf
+
+#include "s_lrint.c"
diff --git a/lib/msun/src/s_llround.c b/lib/msun/src/s_llround.c
new file mode 100644
index 0000000..f907c05
--- /dev/null
+++ b/lib/msun/src/s_llround.c
@@ -0,0 +1,11 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define type double
+#define roundit round
+#define dtype long long
+#define DTYPE_MIN LLONG_MIN
+#define DTYPE_MAX LLONG_MAX
+#define fn llround
+
+#include "s_lrint.c"
diff --git a/lib/msun/src/s_llroundf.c b/lib/msun/src/s_llroundf.c
new file mode 100644
index 0000000..78a8feb
--- /dev/null
+++ b/lib/msun/src/s_llroundf.c
@@ -0,0 +1,11 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define type float
+#define roundit roundf
+#define dtype long long
+#define DTYPE_MIN LLONG_MIN
+#define DTYPE_MAX LLONG_MAX
+#define fn llroundf
+
+#include "s_lrint.c"
diff --git a/lib/msun/src/s_lrint.c b/lib/msun/src/s_lrint.c
new file mode 100644
index 0000000..27ff5ff
--- /dev/null
+++ b/lib/msun/src/s_lrint.c
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <fenv.h>
+#include <math.h>
+
+#ifndef type
+__FBSDID("$FreeBSD$");
+#define type double
+#define roundit rint
+#define dtype long
+#define fn lrint
+#endif
+
+/*
+ * C99 says we should not raise a spurious inexact exception when an
+ * invalid exception is raised. Unfortunately, the set of inputs
+ * that overflows depends on the rounding mode when 'dtype' has more
+ * significant bits than 'type'. Hence, we bend over backwards for the
+ * sake of correctness; an MD implementation could be more efficient.
+ */
+dtype
+fn(type x)
+{
+ fenv_t env;
+ dtype d;
+
+ feholdexcept(&env);
+ d = (dtype)roundit(x);
+ if (fetestexcept(FE_INVALID))
+ feclearexcept(FE_INEXACT);
+ feupdateenv(&env);
+ return (d);
+}
diff --git a/lib/msun/src/s_lrintf.c b/lib/msun/src/s_lrintf.c
new file mode 100644
index 0000000..a757ded
--- /dev/null
+++ b/lib/msun/src/s_lrintf.c
@@ -0,0 +1,9 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define type float
+#define roundit rintf
+#define dtype long
+#define fn lrintf
+
+#include "s_lrint.c"
diff --git a/lib/msun/src/s_lround.c b/lib/msun/src/s_lround.c
new file mode 100644
index 0000000..5101bbb
--- /dev/null
+++ b/lib/msun/src/s_lround.c
@@ -0,0 +1,67 @@
+/*-
+ * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/limits.h>
+#include <fenv.h>
+#include <math.h>
+
+#ifndef type
+__FBSDID("$FreeBSD$");
+#define type double
+#define roundit round
+#define dtype long
+#define DTYPE_MIN LONG_MIN
+#define DTYPE_MAX LONG_MAX
+#define fn lround
+#endif
+
+/*
+ * If type has more precision than dtype, the endpoints dtype_(min|max) are
+ * of the form xxx.5; they are "out of range" because lround() rounds away
+ * from 0. On the other hand, if type has less precision than dtype, then
+ * all values that are out of range are integral, so we might as well assume
+ * that everything is in range. (The correct condition in this case is
+ * harder to express.) At compile time, INRANGE(x) should reduce to two
+ * floating-point comparisons in the former case, or TRUE otherwise.
+ */
+static const double dtype_min = DTYPE_MIN - 0.5;
+static const double dtype_max = DTYPE_MAX + 0.5;
+#define INRANGE(x) (dtype_max - DTYPE_MAX != 0.5 || \
+ ((x) > dtype_min && (x) < dtype_max))
+
+dtype
+fn(type x)
+{
+
+ if (INRANGE(x)) {
+ x = roundit(x);
+ return ((dtype)x);
+ } else {
+ feraiseexcept(FE_INVALID);
+ return (DTYPE_MAX);
+ }
+}
diff --git a/lib/msun/src/s_lroundf.c b/lib/msun/src/s_lroundf.c
new file mode 100644
index 0000000..6d1d2b3
--- /dev/null
+++ b/lib/msun/src/s_lroundf.c
@@ -0,0 +1,11 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define type float
+#define roundit roundf
+#define dtype long
+#define DTYPE_MIN LONG_MIN
+#define DTYPE_MAX LONG_MAX
+#define fn lroundf
+
+#include "s_lrint.c"
OpenPOWER on IntegriCloud