diff options
-rw-r--r-- | floatbuiltins.h | 12 | ||||
-rw-r--r-- | floattypes.h | 4 | ||||
-rw-r--r-- | mathfuncs_base.h | 1 | ||||
-rw-r--r-- | mathfuncs_convert.h | 8 | ||||
-rw-r--r-- | test.cc | 5 | ||||
-rw-r--r-- | vec_base.h | 8 | ||||
-rw-r--r-- | vec_builtin.h | 15 | ||||
-rw-r--r-- | vec_pseudo.h | 18 | ||||
-rw-r--r-- | vec_test.h | 7 |
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) @@ -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()); @@ -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) @@ -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) |