diff options
Diffstat (limited to 'mathfuncs_fabs.h')
-rw-r--r-- | mathfuncs_fabs.h | 305 |
1 files changed, 140 insertions, 165 deletions
diff --git a/mathfuncs_fabs.h b/mathfuncs_fabs.h index 4f31dec..c3f7356 100644 --- a/mathfuncs_fabs.h +++ b/mathfuncs_fabs.h @@ -7,201 +7,176 @@ #include <cmath> +namespace vecmathlib { +template <typename realvec_t> +realvec_t mathfuncs<realvec_t>::vml_copysign(realvec_t x, realvec_t y) { + intvec_t value = as_int(x) & IV(U(~FP::signbit_mask)); + intvec_t sign = as_int(y) & IV(FP::signbit_mask); + return as_float(sign | value); +} -namespace vecmathlib { - - template<typename realvec_t> - realvec_t mathfuncs<realvec_t>::vml_copysign(realvec_t x, realvec_t y) - { - intvec_t value = as_int(x) & IV(U(~FP::signbit_mask)); - intvec_t sign = as_int(y) & IV(FP::signbit_mask); - return as_float(sign | value); - } - - template<typename realvec_t> - realvec_t mathfuncs<realvec_t>::vml_fabs(realvec_t x) - { - return as_float(as_int(x) & IV(U(~FP::signbit_mask))); - } - - template<typename realvec_t> - realvec_t mathfuncs<realvec_t>::vml_fdim(realvec_t x, realvec_t y) - { - // return ifthen(x > y, x - y, RV(0.0)); - return fmax(x - y, RV(0.0)); - } - - template<typename realvec_t> - realvec_t mathfuncs<realvec_t>::vml_fma(realvec_t x, realvec_t y, realvec_t z) - { - return x * y + z; - } - - template<typename realvec_t> - realvec_t mathfuncs<realvec_t>::vml_fmax(realvec_t x, realvec_t y) - { - return ifthen(x < y, y, x); - } - - template<typename realvec_t> - realvec_t mathfuncs<realvec_t>::vml_fmin(realvec_t x, realvec_t y) - { - return ifthen(y < x, y, x); - } - - template<typename realvec_t> - realvec_t mathfuncs<realvec_t>::vml_frexp(realvec_t x, - typename realvec_t::intvec_t* irp) - { - intvec_t e = lsr(as_int(x) & IV(FP::exponent_mask), FP::mantissa_bits); - intvec_t ir = e - IV(FP::exponent_offset - 1); - ir = ifthen(convert_bool(e), ir, IV(std::numeric_limits<int_t>::min())); +template <typename realvec_t> +realvec_t mathfuncs<realvec_t>::vml_fabs(realvec_t x) { + return as_float(as_int(x) & IV(U(~FP::signbit_mask))); +} + +template <typename realvec_t> +realvec_t mathfuncs<realvec_t>::vml_fdim(realvec_t x, realvec_t y) { + // return ifthen(x > y, x - y, RV(0.0)); + return fmax(x - y, RV(0.0)); +} + +template <typename realvec_t> +realvec_t mathfuncs<realvec_t>::vml_fma(realvec_t x, realvec_t y, realvec_t z) { + return x * y + z; +} + +template <typename realvec_t> +realvec_t mathfuncs<realvec_t>::vml_fmax(realvec_t x, realvec_t y) { + return ifthen(x < y, y, x); +} + +template <typename realvec_t> +realvec_t mathfuncs<realvec_t>::vml_fmin(realvec_t x, realvec_t y) { + return ifthen(y < x, y, x); +} + +template <typename realvec_t> +realvec_t mathfuncs<realvec_t>::vml_frexp(realvec_t x, + typename realvec_t::intvec_t *irp) { + intvec_t e = lsr(as_int(x) & IV(FP::exponent_mask), FP::mantissa_bits); + intvec_t ir = e - IV(FP::exponent_offset - 1); + ir = ifthen(convert_bool(e), ir, IV(std::numeric_limits<int_t>::min())); #if defined VML_HAVE_INF - ir = ifthen(isinf(x), IV(std::numeric_limits<int_t>::max()), ir); + ir = ifthen(isinf(x), IV(std::numeric_limits<int_t>::max()), ir); #endif #if defined VML_HAVE_NAN - ir = ifthen(isnan(x), IV(std::numeric_limits<int_t>::min()), ir); + ir = ifthen(isnan(x), IV(std::numeric_limits<int_t>::min()), ir); #endif - realvec_t r = + realvec_t r = as_float((as_int(x) & IV(FP::signbit_mask | FP::mantissa_mask)) | IV(FP::as_int(R(0.5)) & FP::exponent_mask)); - boolvec_t iszero = x == RV(0.0); - ir = ifthen(iszero, IV(I(0)), ir); - r = ifthen(iszero, copysign(RV(R(0.0)), r), r); - *irp = ir; - return r; - } - - template<typename realvec_t> - typename realvec_t::intvec_t mathfuncs<realvec_t>::vml_ilogb(realvec_t x) - { - // TODO: Check SLEEF 2.80 algorithm - intvec_t e = lsr(as_int(x) & IV(FP::exponent_mask), FP::mantissa_bits); - intvec_t r = e - IV(FP::exponent_offset); - r = ifthen(convert_bool(e), r, IV(std::numeric_limits<int_t>::min())); + boolvec_t iszero = x == RV(0.0); + ir = ifthen(iszero, IV(I(0)), ir); + r = ifthen(iszero, copysign(RV(R(0.0)), r), r); + *irp = ir; + return r; +} + +template <typename realvec_t> +typename realvec_t::intvec_t mathfuncs<realvec_t>::vml_ilogb(realvec_t x) { + // TODO: Check SLEEF 2.80 algorithm + intvec_t e = lsr(as_int(x) & IV(FP::exponent_mask), FP::mantissa_bits); + intvec_t r = e - IV(FP::exponent_offset); + r = ifthen(convert_bool(e), r, IV(std::numeric_limits<int_t>::min())); #if defined VML_HAVE_INF - r = ifthen(isinf(x), IV(std::numeric_limits<int_t>::max()), r); + r = ifthen(isinf(x), IV(std::numeric_limits<int_t>::max()), r); #endif #if defined VML_HAVE_NAN - r = ifthen(isnan(x), IV(std::numeric_limits<int_t>::min()), r); + r = ifthen(isnan(x), IV(std::numeric_limits<int_t>::min()), r); #endif - return r; - } - - template<typename realvec_t> - typename realvec_t::boolvec_t - mathfuncs<realvec_t>::vml_ieee_isfinite(realvec_t x) - { - return (as_int(x) & IV(FP::exponent_mask)) != IV(FP::exponent_mask); - } - - template<typename realvec_t> - typename realvec_t::boolvec_t - mathfuncs<realvec_t>::vml_ieee_isinf(realvec_t x) - { - return (as_int(x) & IV(I(~FP::signbit_mask))) == IV(FP::exponent_mask); - } - - template<typename realvec_t> - typename realvec_t::boolvec_t - mathfuncs<realvec_t>::vml_ieee_isnan(realvec_t x) - { - return - (as_int(x) & IV(FP::exponent_mask)) == IV(FP::exponent_mask) && - (as_int(x) & IV(FP::mantissa_mask)) != IV(I(0)); - } - - template<typename realvec_t> - typename realvec_t::boolvec_t - mathfuncs<realvec_t>::vml_ieee_isnormal(realvec_t x) - { - return - (as_int(x) & IV(FP::exponent_mask)) != IV(FP::exponent_mask) && - (as_int(x) & IV(FP::exponent_mask)) != IV(I(0)); - } - - template<typename realvec_t> - typename realvec_t::boolvec_t - mathfuncs<realvec_t>::vml_isfinite(realvec_t x) - { + return r; +} + +template <typename realvec_t> +typename realvec_t::boolvec_t +mathfuncs<realvec_t>::vml_ieee_isfinite(realvec_t x) { + return (as_int(x) & IV(FP::exponent_mask)) != IV(FP::exponent_mask); +} + +template <typename realvec_t> +typename realvec_t::boolvec_t +mathfuncs<realvec_t>::vml_ieee_isinf(realvec_t x) { + return (as_int(x) & IV(I(~FP::signbit_mask))) == IV(FP::exponent_mask); +} + +template <typename realvec_t> +typename realvec_t::boolvec_t +mathfuncs<realvec_t>::vml_ieee_isnan(realvec_t x) { + return (as_int(x) & IV(FP::exponent_mask)) == IV(FP::exponent_mask) && + (as_int(x) & IV(FP::mantissa_mask)) != IV(I(0)); +} + +template <typename realvec_t> +typename realvec_t::boolvec_t +mathfuncs<realvec_t>::vml_ieee_isnormal(realvec_t x) { + return (as_int(x) & IV(FP::exponent_mask)) != IV(FP::exponent_mask) && + (as_int(x) & IV(FP::exponent_mask)) != IV(I(0)); +} + +template <typename realvec_t> +typename realvec_t::boolvec_t mathfuncs<realvec_t>::vml_isfinite(realvec_t x) { #if defined VML_HAVE_INF || defined VML_HAVE_NAN - return vml_ieee_isfinite(x); + return vml_ieee_isfinite(x); #else - return BV(true); + return BV(true); #endif - } - - template<typename realvec_t> - typename realvec_t::boolvec_t mathfuncs<realvec_t>::vml_isinf(realvec_t x) - { +} + +template <typename realvec_t> +typename realvec_t::boolvec_t mathfuncs<realvec_t>::vml_isinf(realvec_t x) { #if defined VML_HAVE_INF - return vml_ieee_isinf(x); + return vml_ieee_isinf(x); #else - return BV(false); + return BV(false); #endif - } - - template<typename realvec_t> - typename realvec_t::boolvec_t mathfuncs<realvec_t>::vml_isnan(realvec_t x) - { +} + +template <typename realvec_t> +typename realvec_t::boolvec_t mathfuncs<realvec_t>::vml_isnan(realvec_t x) { #if defined VML_HAVE_NAN - return vml_ieee_isnan(x); + return vml_ieee_isnan(x); #else - return BV(false); + return BV(false); #endif - } - - template<typename realvec_t> - typename realvec_t::boolvec_t mathfuncs<realvec_t>::vml_isnormal(realvec_t x) - { +} + +template <typename realvec_t> +typename realvec_t::boolvec_t mathfuncs<realvec_t>::vml_isnormal(realvec_t x) { #if defined VML_HAVE_DENORMALS || defined VML_HAVE_INF || defined VML_HAVE_NAN - return vml_ieee_isnormal(x); + return vml_ieee_isnormal(x); #else - return BV(true); + return BV(true); #endif - } - - template<typename realvec_t> - realvec_t mathfuncs<realvec_t>::vml_ldexp(realvec_t x, intvec_t n) - { - // TODO: Check SLEEF 2.80 algorithm +} + +template <typename realvec_t> +realvec_t mathfuncs<realvec_t>::vml_ldexp(realvec_t x, intvec_t n) { +// TODO: Check SLEEF 2.80 algorithm #if 0 realvec_t r = as_float(as_int(x) + (n << I(FP::mantissa_bits))); r = ifthen((as_int(x) & IV(FP::exponent_mask)) == IV(I(0)), x, r); return r; #endif - realvec_t r = as_float(as_int(x) + (n << U(FP::mantissa_bits))); - int max_n = FP::max_exponent - FP::min_exponent; - boolvec_t underflow = n < IV(I(-max_n)); - boolvec_t overflow = n > IV(I(max_n)); - intvec_t old_exp = - lsr(as_int(x) & IV(FP::exponent_mask), FP::mantissa_bits); - intvec_t new_exp = old_exp + n; - // TODO: check bit patterns instead - underflow = + realvec_t r = as_float(as_int(x) + (n << U(FP::mantissa_bits))); + int max_n = FP::max_exponent - FP::min_exponent; + boolvec_t underflow = n < IV(I(-max_n)); + boolvec_t overflow = n > IV(I(max_n)); + intvec_t old_exp = lsr(as_int(x) & IV(FP::exponent_mask), FP::mantissa_bits); + intvec_t new_exp = old_exp + n; + // TODO: check bit patterns instead + underflow = underflow || new_exp < IV(I(FP::min_exponent + FP::exponent_offset)); - overflow = + overflow = overflow || new_exp > IV(I(FP::max_exponent + FP::exponent_offset)); - r = ifthen(underflow, copysign(RV(R(0.0)), x), r); - r = ifthen(overflow, copysign(RV(FP::infinity()), x), r); - boolvec_t dont_change = x == RV(R(0.0)) || isinf(x) || isnan(x); - r = ifthen(dont_change, x, r); - return r; - } - - template<typename realvec_t> - realvec_t mathfuncs<realvec_t>::vml_mad(realvec_t x, realvec_t y, realvec_t z) - { - return x * y + z; - } - - template<typename realvec_t> - typename realvec_t::boolvec_t mathfuncs<realvec_t>::vml_signbit(realvec_t x) - { - return convert_bool(as_int(x) & IV(FP::signbit_mask)); - } - + r = ifthen(underflow, copysign(RV(R(0.0)), x), r); + r = ifthen(overflow, copysign(RV(FP::infinity()), x), r); + boolvec_t dont_change = x == RV(R(0.0)) || isinf(x) || isnan(x); + r = ifthen(dont_change, x, r); + return r; +} + +template <typename realvec_t> +realvec_t mathfuncs<realvec_t>::vml_mad(realvec_t x, realvec_t y, realvec_t z) { + return x * y + z; +} + +template <typename realvec_t> +typename realvec_t::boolvec_t mathfuncs<realvec_t>::vml_signbit(realvec_t x) { + return convert_bool(as_int(x) & IV(FP::signbit_mask)); +} + }; // namespace vecmathlib -#endif // #ifndef MATHFUNCS_FABS_H +#endif // #ifndef MATHFUNCS_FABS_H |