From ec33e3b30b4324cad3f5c26186cc2d2620708a0f Mon Sep 17 00:00:00 2001 From: Erik Schnetter Date: Mon, 25 Nov 2013 14:52:26 -0500 Subject: Provide lrint --- floatbuiltins.h | 12 ++++++++++++ floattypes.h | 4 ++++ mathfuncs_base.h | 1 + mathfuncs_convert.h | 8 ++++++++ test.cc | 5 +++++ vec_base.h | 8 +++++++- vec_builtin.h | 15 +++++++++++++++ vec_pseudo.h | 18 ++++++++++++++++++ vec_test.h | 7 +++++++ 9 files changed, 77 insertions(+), 1 deletion(-) 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 + typename realvec_t::intvec_t mathfuncs::vml_lrint(realvec_t x) + { + return convert_int(rint(x)); + } + // Round to nearest integer, breaking ties away from zero template realvec_t mathfuncs::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("floor", vml_std::floor, vecmathlib::floor, fn2, accuracy()); check_real("floor", vml_std::floor, vecmathlib::floor, fn1h, accuracy()); check_real("floor", vml_std::floor, vecmathlib::floor, fn2h, accuracy()); + // check_int("lrint", vml_std::lrint, vecmathlib::rint, x, accuracy()); + // check_int("lrint", vml_std::lrint, vecmathlib::rint, fn1, accuracy()); + // check_int("lrint", vml_std::lrint, vecmathlib::rint, fn2, accuracy()); + // check_int("lrint", vml_std::lrint, vecmathlib::rint, fn1h, accuracy()); + // check_int("lrint", vml_std::lrint, vecmathlib::rint, fn2h, accuracy()); check_real("rint", vml_std::rint, vecmathlib::rint, x, accuracy()); check_real("rint", vml_std::rint, vecmathlib::rint, fn1, accuracy()); check_real("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 + inline intvec lrint(realvec x) + { + return x.lrint(); + } + template inline realvec mad(realvec x, realvec 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 + inline intbuiltinvec lrint(realbuiltinvec x) + { + return x.lrint(); + } + + template inline realbuiltinvec mad(realbuiltinvec x, realbuiltinvec y, realbuiltinvec 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 + inline intpseudovec lrint(realpseudovec x) + { + return x.lrint(); + } + + template inline realpseudovec mad(realpseudovec x, realpseudovec y, realpseudovec 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 + inline inttestvec lrint(realtestvec x) + { + return x.lrint(); + } + + template inline realtestvec mad(realtestvec x, realtestvec y, realtestvec z) -- cgit v1.1