summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--floatbuiltins.h12
-rw-r--r--floattypes.h4
-rw-r--r--mathfuncs_base.h1
-rw-r--r--mathfuncs_convert.h8
-rw-r--r--test.cc5
-rw-r--r--vec_base.h8
-rw-r--r--vec_builtin.h15
-rw-r--r--vec_pseudo.h18
-rw-r--r--vec_test.h7
9 files changed, 77 insertions, 1 deletions
diff --git a/floatbuiltins.h b/floatbuiltins.h
index 68d391a..ee076a2 100644
--- a/floatbuiltins.h
+++ b/floatbuiltins.h
@@ -212,6 +212,12 @@ namespace vecmathlib {
#if __SIZEOF_LONG_DOUBLE__
inline long double builtin_ldexp(long double x, int y) { return __builtin_ldexpl(x, y); }
#endif
+
+ inline long long builtin_llrint(float x) { return __builtin_llrintf(x); }
+ inline long long builtin_llrint(double x) { return __builtin_llrint(x); }
+#if __SIZEOF_LONG_DOUBLE__
+ inline long long builtin_llrint(long double x) { return __builtin_llrintl(x); }
+#endif
inline float builtin_log(float x) { return __builtin_logf(x); }
inline double builtin_log(double x) { return __builtin_log(x); }
@@ -237,6 +243,12 @@ namespace vecmathlib {
inline long double builtin_log2(long double x) { return __builtin_log2l(x); }
#endif
+ inline long builtin_lrint(float x) { return __builtin_lrintf(x); }
+ inline long builtin_lrint(double x) { return __builtin_lrint(x); }
+#if __SIZEOF_LONG_DOUBLE__
+ inline long builtin_lrint(long double x) { return __builtin_lrintl(x); }
+#endif
+
inline float builtin_nextafter(float x, float y) { return __builtin_nextafterf(x, y); }
inline double builtin_nextafter(double x, double y) { return __builtin_nextafter(x, y); }
#if __SIZEOF_LONG_DOUBLE__
diff --git a/floattypes.h b/floattypes.h
index 1964fcf..cfa9136 100644
--- a/floattypes.h
+++ b/floattypes.h
@@ -129,10 +129,12 @@ namespace vml_std {
inline bool isnan(float x) { return libc_isnan(x); }
inline bool isnormal(float x) { return libc_isnormal(x); }
inline float ldexp(float x, int n) { return ::ldexpf(x, n); }
+ inline long long llrint(float x) { return ::llrintf(x); }
inline float log(float x) { return ::logf(x); }
inline float log10(float x) { return ::log10f(x); }
inline float log1p(float x) { return ::log1pf(x); }
inline float log2(float x) { return ::log2f(x); }
+ inline long lrint(float x) { return ::lrintf(x); }
inline float nextafter(float x, float y) { return ::nextafterf(x, y); }
inline float pow(float x, float y) { return ::powf(x, y); }
inline float remainder(float x, float y) { return ::remainderf(x, y); }
@@ -176,10 +178,12 @@ namespace vml_std {
inline bool isnan(double x) { return libc_isnan(x); }
inline bool isnormal(double x) { return libc_isnormal(x); }
inline double ldexp(double x, int n) { return ::ldexp(x, n); }
+ inline long long llrint(double x) { return ::llrint(x); }
inline double log(double x) { return ::log(x); }
inline double log10(double x) { return ::log10(x); }
inline double log1p(double x) { return ::log1p(x); }
inline double log2(double x) { return ::log2(x); }
+ inline long lrint(double x) { return ::lrint(x); }
inline double nextafter(double x, double y) { return ::nextafter(x, y); }
inline double pow(double x, double y) { return ::pow(x, y); }
inline double remainder(double x, double y) { return ::remainder(x, y); }
diff --git a/mathfuncs_base.h b/mathfuncs_base.h
index 9cb6eb2..c685542 100644
--- a/mathfuncs_base.h
+++ b/mathfuncs_base.h
@@ -65,6 +65,7 @@ namespace vecmathlib {
static realvec_t vml_convert_float(intvec_t x);
static intvec_t vml_convert_int(realvec_t x);
static realvec_t vml_floor(realvec_t x);
+ static intvec_t vml_lrint(realvec_t x);
static realvec_t vml_rint(realvec_t x);
static realvec_t vml_round(realvec_t x);
static realvec_t vml_nextafter(realvec_t x, realvec_t y);
diff --git a/mathfuncs_convert.h b/mathfuncs_convert.h
index 70aedc2..79befbc 100644
--- a/mathfuncs_convert.h
+++ b/mathfuncs_convert.h
@@ -121,6 +121,14 @@ namespace vecmathlib {
return ifthen(x<RV(0.0), vml_antitrunc(x), trunc(x));
}
+ // Round to nearest integer, breaking ties using prevailing rounding
+ // mode (default: round to even), returning an integer
+ template<typename realvec_t>
+ typename realvec_t::intvec_t mathfuncs<realvec_t>::vml_lrint(realvec_t x)
+ {
+ return convert_int(rint(x));
+ }
+
// Round to nearest integer, breaking ties away from zero
template<typename realvec_t>
realvec_t mathfuncs<realvec_t>::vml_round(realvec_t x)
diff --git a/test.cc b/test.cc
index f07b572..6d84877 100644
--- a/test.cc
+++ b/test.cc
@@ -1391,6 +1391,11 @@ struct vecmathlib_test {
check_real<RV>("floor", vml_std::floor, vecmathlib::floor, fn2, accuracy());
check_real<RV>("floor", vml_std::floor, vecmathlib::floor, fn1h, accuracy());
check_real<RV>("floor", vml_std::floor, vecmathlib::floor, fn2h, accuracy());
+ // check_int<RV>("lrint", vml_std::lrint, vecmathlib::rint, x, accuracy());
+ // check_int<RV>("lrint", vml_std::lrint, vecmathlib::rint, fn1, accuracy());
+ // check_int<RV>("lrint", vml_std::lrint, vecmathlib::rint, fn2, accuracy());
+ // check_int<RV>("lrint", vml_std::lrint, vecmathlib::rint, fn1h, accuracy());
+ // check_int<RV>("lrint", vml_std::lrint, vecmathlib::rint, fn2h, accuracy());
check_real<RV>("rint", vml_std::rint, vecmathlib::rint, x, accuracy());
check_real<RV>("rint", vml_std::rint, vecmathlib::rint, fn1, accuracy());
check_real<RV>("rint", vml_std::rint, vecmathlib::rint, fn2, accuracy());
diff --git a/vec_base.h b/vec_base.h
index 702a405..643359c 100644
--- a/vec_base.h
+++ b/vec_base.h
@@ -517,7 +517,13 @@ namespace vecmathlib {
{
return x.log2();
}
-
+
+ template<typename real_t, int size>
+ inline intvec<real_t, size> lrint(realvec<real_t, size> x)
+ {
+ return x.lrint();
+ }
+
template<typename real_t, int size>
inline realvec<real_t, size> mad(realvec<real_t, size> x,
realvec<real_t, size> y,
diff --git a/vec_builtin.h b/vec_builtin.h
index a9a87cb..d8a8a45 100644
--- a/vec_builtin.h
+++ b/vec_builtin.h
@@ -686,6 +686,15 @@ namespace vecmathlib {
realvec_t log10() const { return map(builtin_log10); }
realvec_t log1p() const { return map(builtin_log1p); }
realvec_t log2() const { return map(builtin_log2); }
+ intvec_t lrint() const
+ {
+ if (sizeof(int_t) <= sizeof(long)) {
+ return map(builtin_lrint);
+ } else if (sizeof(int_t) <= sizeof(long long)) {
+ return map(builtin_llrint);
+ }
+ __builtin_unreachable();
+ }
realvec_t mad(realvec_t y, realvec_t z) const
{
return MF::vml_mad(*this, y, z);
@@ -1298,6 +1307,12 @@ namespace vecmathlib {
}
template<typename real_t, int size>
+ inline intbuiltinvec<real_t, size> lrint(realbuiltinvec<real_t, size> x)
+ {
+ return x.lrint();
+ }
+
+ template<typename real_t, int size>
inline realbuiltinvec<real_t, size> mad(realbuiltinvec<real_t, size> x,
realbuiltinvec<real_t, size> y,
realbuiltinvec<real_t, size> z)
diff --git a/vec_pseudo.h b/vec_pseudo.h
index 5f84d3c..8fa80dc 100644
--- a/vec_pseudo.h
+++ b/vec_pseudo.h
@@ -887,6 +887,18 @@ namespace vecmathlib {
realvec_t log10() const { return map(vml_std::log10); }
realvec_t log1p() const { return map(vml_std::log1p); }
realvec_t log2() const { return map(vml_std::log2); }
+ intvec_t lrint() const
+ {
+ realvec_t res;
+ if (sizeof(int_t) <= sizeof(long)) {
+ for (int d=0; d<size; ++d) res.v[d] = vml_std::lrint(v[d]);
+ } else if (sizeof(int_t) <= sizeof(long long)) {
+ for (int d=0; d<size; ++d) res.v[d] = vml_std::llrint(v[d]);
+ } else {
+ __builtin_unreachable();
+ }
+ return res;
+ }
realvec_t mad(realvec_t y, realvec_t z) const
{
return MF::vml_mad(*this, y, z);
@@ -1507,6 +1519,12 @@ namespace vecmathlib {
}
template<typename real_t, int size>
+ inline intpseudovec<real_t, size> lrint(realpseudovec<real_t, size> x)
+ {
+ return x.lrint();
+ }
+
+ template<typename real_t, int size>
inline realpseudovec<real_t, size> mad(realpseudovec<real_t, size> x,
realpseudovec<real_t, size> y,
realpseudovec<real_t, size> z)
diff --git a/vec_test.h b/vec_test.h
index 93ae551..7906801 100644
--- a/vec_test.h
+++ b/vec_test.h
@@ -722,6 +722,7 @@ namespace vecmathlib {
realvec_t log10() const { return MF::vml_log10(*this); }
realvec_t log1p() const { return MF::vml_log1p(*this); }
realvec_t log2() const { return MF::vml_log2(*this); }
+ intvec_t lrint() const { return MF::vml_lrint(*this); }
realvec_t mad(realvec_t y, realvec_t z) const
{
return MF::vml_mad(*this, y, z);
@@ -1328,6 +1329,12 @@ namespace vecmathlib {
}
template<typename real_t, int size>
+ inline inttestvec<real_t, size> lrint(realtestvec<real_t, size> x)
+ {
+ return x.lrint();
+ }
+
+ template<typename real_t, int size>
inline realtestvec<real_t, size> mad(realtestvec<real_t, size> x,
realtestvec<real_t, size> y,
realtestvec<real_t, size> z)
OpenPOWER on IntegriCloud