diff options
Diffstat (limited to 'vec_sse_float1.h')
-rw-r--r-- | vec_sse_float1.h | 998 |
1 files changed, 452 insertions, 546 deletions
diff --git a/vec_sse_float1.h b/vec_sse_float1.h index 9cee891..a84a046 100644 --- a/vec_sse_float1.h +++ b/vec_sse_float1.h @@ -12,583 +12,489 @@ // SSE2 intrinsics #include <emmintrin.h> -#ifdef __SSE3__ // Intel's SSE 3 -# include <pmmintrin.h> +#ifdef __SSE3__ // Intel's SSE 3 +#include <pmmintrin.h> #endif -#ifdef __SSE4_1__ // Intel's SSE 4.1 -# include <smmintrin.h> +#ifdef __SSE4_1__ // Intel's SSE 4.1 +#include <smmintrin.h> #endif -#ifdef __SSE4A__ // AMD's SSE 4a -# include <ammintrin.h> +#ifdef __SSE4A__ // AMD's SSE 4a +#include <ammintrin.h> #endif -#if defined __AVX__ // Intel's AVX -# include <immintrin.h> +#if defined __AVX__ // Intel's AVX +#include <immintrin.h> #endif - - namespace vecmathlib { - + #define VECMATHLIB_HAVE_VEC_FLOAT_1 - template<> struct boolvec<float,1>; - template<> struct intvec<float,1>; - template<> struct realvec<float,1>; - - - - template<> - struct boolvec<float,1>: floatprops<float> - { - static int const size = 1; - typedef bool scalar_t; - typedef uint_t bvector_t; - static int const alignment = sizeof(bvector_t); - - static_assert(size * sizeof(real_t) == sizeof(bvector_t), - "vector size is wrong"); - - // true values are non-zero, false values are zero - - typedef boolvec boolvec_t; - typedef intvec<real_t, size> intvec_t; - typedef realvec<real_t, size> realvec_t; - - // Short names for type casts - typedef real_t R; - typedef int_t I; - typedef uint_t U; - typedef realvec_t RV; - typedef intvec_t IV; - typedef boolvec_t BV; - typedef floatprops<real_t> FP; - typedef mathfuncs<realvec_t> MF; - - - - bvector_t v; - - boolvec() {} - // Can't have a non-trivial copy constructor; if so, objects won't - // be passed in registers - // boolvec(boolvec const& x): v(x.v) {} - // boolvec& operator=(boolvec const& x) { return v=x.v, *this; } - boolvec(bvector_t x): v(x) {} - boolvec(bool a): v(a) {} - boolvec(bool const* as): v(as[0]) {} - - operator bvector_t() const { return v; } - bool operator[](int n) const { return v; } - boolvec_t& set_elt(int n, bool a) { return v=a, *this; } - - - - intvec_t as_int() const; // defined after intvec - intvec_t convert_int() const; // defined after intvec - - - - boolvec_t operator!() const { return !v; } - - boolvec_t operator&&(boolvec_t x) const { return v && x.v; } - boolvec_t operator||(boolvec_t x) const { return v || x.v; } - boolvec_t operator==(boolvec_t x) const { return bool(v) == bool(x.v); } - boolvec_t operator!=(boolvec_t x) const { return bool(v) != bool(x.v); } - - bool all() const { return *this; } - bool any() const { return *this; } - - - - // ifthen(condition, then-value, else-value) - boolvec_t ifthen(boolvec_t x, boolvec_t y) const; - intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec - realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec - }; - - - - template<> - struct intvec<float,1>: floatprops<float> - { - static int const size = 1; - typedef int_t scalar_t; - typedef int_t ivector_t; - static int const alignment = sizeof(ivector_t); - - static_assert(size * sizeof(real_t) == sizeof(ivector_t), - "vector size is wrong"); - - typedef boolvec<real_t, size> boolvec_t; - typedef intvec intvec_t; - typedef realvec<real_t, size> realvec_t; - - // Short names for type casts - typedef real_t R; - typedef int_t I; - typedef uint_t U; - typedef realvec_t RV; - typedef intvec_t IV; - typedef boolvec_t BV; - typedef floatprops<real_t> FP; - typedef mathfuncs<realvec_t> MF; - - - - ivector_t v; - - intvec() {} - // Can't have a non-trivial copy constructor; if so, objects won't - // be passed in registers - // intvec(intvec const& x): v(x.v) {} - // intvec& operator=(intvec const& x) { return v=x.v, *this; } - intvec(int_t a): v(a) {} - intvec(int_t const* as): v(as[0]) {} - static intvec_t iota() { return intvec(I(0)); } - - operator ivector_t() const { return v; } - int_t operator[](int n) const { return v; } - intvec_t& set_elt(int n, int_t a) { return v=a, *this; } - - - - boolvec_t as_bool() const { return U(v); } - boolvec_t convert_bool() const { return bool(v); } - realvec_t as_float() const; // defined after realvec - realvec_t convert_float() const; // defined after realvec - - - - intvec_t operator+() const { return +v; } - intvec_t operator-() const { return -v; } - - intvec_t operator+(intvec_t x) const { return v+x.v; } - intvec_t operator-(intvec_t x) const { return v-x.v; } - intvec_t operator*(intvec_t x) const { return v*x.v; } - intvec_t operator/(intvec_t x) const { return v/x.v; } - intvec_t operator%(intvec_t x) const { return v%x.v; } - - intvec_t& operator+=(intvec_t const& x) { return *this=*this+x; } - intvec_t& operator-=(intvec_t const& x) { return *this=*this-x; } - intvec_t& operator*=(intvec_t const& x) { return *this=*this*x; } - intvec_t& operator/=(intvec_t const& x) { return *this=*this/x; } - intvec_t& operator%=(intvec_t const& x) { return *this=*this%x; } - - - - intvec_t operator~() const { return ~v; } - - intvec_t operator&(intvec_t x) const { return v&x.v; } - intvec_t operator|(intvec_t x) const { return v|x.v; } - intvec_t operator^(intvec_t x) const { return v^x.v; } - - intvec_t& operator&=(intvec_t const& x) { return *this=*this&x; } - intvec_t& operator|=(intvec_t const& x) { return *this=*this|x; } - intvec_t& operator^=(intvec_t const& x) { return *this=*this^x; } - - intvec_t bitifthen(intvec_t x, intvec_t y) const; - - - - intvec_t lsr(int_t n) const { return U(v) >> U(n); } - intvec_t rotate(int_t n) const; - intvec_t operator>>(int_t n) const { return v>>n; } - intvec_t operator<<(int_t n) const { return v<<n; } - - intvec_t& operator>>=(int_t n) { return *this=*this>>n; } - intvec_t& operator<<=(int_t n) { return *this=*this<<n; } - - intvec_t lsr(intvec_t n) const { return U(v) >> U(n); } - intvec_t rotate(intvec_t n) const; - intvec_t operator>>(intvec_t n) const { return v>>n; } - intvec_t operator<<(intvec_t n) const { return v<<n; } - - intvec_t& operator>>=(intvec_t n) { return *this=*this>>n; } - intvec_t& operator<<=(intvec_t n) { return *this=*this<<n; } - - intvec_t clz() const { return __builtin_clz(v); } - intvec_t popcount() const { return __builtin_popcount(v); } - - - - boolvec_t operator==(intvec_t const& x) const { return v==x.v; } - boolvec_t operator!=(intvec_t const& x) const { return v!=x.v; } - boolvec_t operator<(intvec_t const& x) const { return v<x.v; } - boolvec_t operator<=(intvec_t const& x) const { return v<=x.v; } - boolvec_t operator>(intvec_t const& x) const { return v>x.v; } - boolvec_t operator>=(intvec_t const& x) const { return v>=x.v; } - - intvec_t abs() const { return std::abs(v); } - boolvec_t isignbit() const { return v<0; } - intvec_t max(intvec_t x) const { return std::max(v, x.v); } - intvec_t min(intvec_t x) const { return std::min(v, x.v); } - }; - - - - template<> - struct realvec<float,1>: floatprops<float> - { - static int const size = 1; - typedef real_t scalar_t; - typedef float vector_t; - static int const alignment = sizeof(vector_t); - - static char const* name() { return "<SSE2:1*float>"; } - void barrier() { __asm__("": "+x"(v)); } - - static_assert(size * sizeof(real_t) == sizeof(vector_t), - "vector size is wrong"); - - private: - static __m128 from_float(float a) { return _mm_set_ss(a); } - static float to_float(__m128 a) { return _mm_cvtss_f32(a); } - public: - - typedef boolvec<real_t, size> boolvec_t; - typedef intvec<real_t, size> intvec_t; - typedef realvec realvec_t; - - // Short names for type casts - typedef real_t R; - typedef int_t I; - typedef uint_t U; - typedef realvec_t RV; - typedef intvec_t IV; - typedef boolvec_t BV; - typedef floatprops<real_t> FP; - typedef mathfuncs<realvec_t> MF; - - - - vector_t v; - - realvec() {} - // Can't have a non-trivial copy constructor; if so, objects won't - // be passed in registers - // realvec(realvec const& x): v(x.v) {} - // realvec& operator=(realvec const& x) { return v=x.v, *this; } - realvec(real_t a): v(a) {} - realvec(real_t const* as): v(as[0]) {} - - operator vector_t() const { return v; } - real_t operator[](int n) const { return v; } - realvec_t& set_elt(int n, real_t a) { return v=a, *this; } - - - - typedef vecmathlib::mask_t<realvec_t> mask_t; - - static realvec_t loada(real_t const* p) - { - VML_ASSERT(intptr_t(p) % alignment == 0); - return *p; - } - static realvec_t loadu(real_t const* p) - { - return *p; - } - static realvec_t loadu(real_t const* p, std::ptrdiff_t ioff) - { - VML_ASSERT(intptr_t(p) % alignment == 0); - return loada(p+ioff); - } - realvec_t loada(real_t const* p, mask_t const& m) const - { - VML_ASSERT(intptr_t(p) % alignment == 0); - if (__builtin_expect(all(m.m), true)) { - return loada(p); - } else { - return *this; - } - } - realvec_t loadu(real_t const* p, mask_t const& m) const - { - if (__builtin_expect(m.all_m, true)) { - return loadu(p); - } else { - return *this; - } - } - realvec_t loadu(real_t const* p, std::ptrdiff_t ioff, mask_t const& m) const - { - VML_ASSERT(intptr_t(p) % alignment == 0); - return loada(p+ioff, m); - } - - void storea(real_t* p) const - { - VML_ASSERT(intptr_t(p) % alignment == 0); - *p = v; - } - void storeu(real_t* p) const - { - *p = v; - } - void storeu(real_t* p, std::ptrdiff_t ioff) const - { - VML_ASSERT(intptr_t(p) % alignment == 0); - storea(p+ioff); - } - void storea(real_t* p, mask_t const& m) const - { - VML_ASSERT(intptr_t(p) % alignment == 0); - if (__builtin_expect(m.all_m, true)) { - storea(p); - } +template <> struct boolvec<float, 1>; +template <> struct intvec<float, 1>; +template <> struct realvec<float, 1>; + +template <> struct boolvec<float, 1> : floatprops<float> { + static int const size = 1; + typedef bool scalar_t; + typedef uint_t bvector_t; + static int const alignment = sizeof(bvector_t); + + static_assert(size * sizeof(real_t) == sizeof(bvector_t), + "vector size is wrong"); + + // true values are non-zero, false values are zero + + typedef boolvec boolvec_t; + typedef intvec<real_t, size> intvec_t; + typedef realvec<real_t, size> realvec_t; + + // Short names for type casts + typedef real_t R; + typedef int_t I; + typedef uint_t U; + typedef realvec_t RV; + typedef intvec_t IV; + typedef boolvec_t BV; + typedef floatprops<real_t> FP; + typedef mathfuncs<realvec_t> MF; + + bvector_t v; + + boolvec() {} + // Can't have a non-trivial copy constructor; if so, objects won't + // be passed in registers + // boolvec(boolvec const& x): v(x.v) {} + // boolvec& operator=(boolvec const& x) { return v=x.v, *this; } + boolvec(bvector_t x) : v(x) {} + boolvec(bool a) : v(a) {} + boolvec(bool const *as) : v(as[0]) {} + + operator bvector_t() const { return v; } + bool operator[](int n) const { return v; } + boolvec_t &set_elt(int n, bool a) { return v = a, *this; } + + intvec_t as_int() const; // defined after intvec + intvec_t convert_int() const; // defined after intvec + + boolvec_t operator!() const { return !v; } + + boolvec_t operator&&(boolvec_t x) const { return v && x.v; } + boolvec_t operator||(boolvec_t x) const { return v || x.v; } + boolvec_t operator==(boolvec_t x) const { return bool(v) == bool(x.v); } + boolvec_t operator!=(boolvec_t x) const { return bool(v) != bool(x.v); } + + bool all() const { return *this; } + bool any() const { return *this; } + + // ifthen(condition, then-value, else-value) + boolvec_t ifthen(boolvec_t x, boolvec_t y) const; + intvec_t ifthen(intvec_t x, intvec_t y) const; // defined after intvec + realvec_t ifthen(realvec_t x, realvec_t y) const; // defined after realvec +}; + +template <> struct intvec<float, 1> : floatprops<float> { + static int const size = 1; + typedef int_t scalar_t; + typedef int_t ivector_t; + static int const alignment = sizeof(ivector_t); + + static_assert(size * sizeof(real_t) == sizeof(ivector_t), + "vector size is wrong"); + + typedef boolvec<real_t, size> boolvec_t; + typedef intvec intvec_t; + typedef realvec<real_t, size> realvec_t; + + // Short names for type casts + typedef real_t R; + typedef int_t I; + typedef uint_t U; + typedef realvec_t RV; + typedef intvec_t IV; + typedef boolvec_t BV; + typedef floatprops<real_t> FP; + typedef mathfuncs<realvec_t> MF; + + ivector_t v; + + intvec() {} + // Can't have a non-trivial copy constructor; if so, objects won't + // be passed in registers + // intvec(intvec const& x): v(x.v) {} + // intvec& operator=(intvec const& x) { return v=x.v, *this; } + intvec(int_t a) : v(a) {} + intvec(int_t const *as) : v(as[0]) {} + static intvec_t iota() { return intvec(I(0)); } + + operator ivector_t() const { return v; } + int_t operator[](int n) const { return v; } + intvec_t &set_elt(int n, int_t a) { return v = a, *this; } + + boolvec_t as_bool() const { return U(v); } + boolvec_t convert_bool() const { return bool(v); } + realvec_t as_float() const; // defined after realvec + realvec_t convert_float() const; // defined after realvec + + intvec_t operator+() const { return +v; } + intvec_t operator-() const { return -v; } + + intvec_t operator+(intvec_t x) const { return v + x.v; } + intvec_t operator-(intvec_t x) const { return v - x.v; } + intvec_t operator*(intvec_t x) const { return v * x.v; } + intvec_t operator/(intvec_t x) const { return v / x.v; } + intvec_t operator%(intvec_t x) const { return v % x.v; } + + intvec_t &operator+=(intvec_t const &x) { return *this = *this + x; } + intvec_t &operator-=(intvec_t const &x) { return *this = *this - x; } + intvec_t &operator*=(intvec_t const &x) { return *this = *this * x; } + intvec_t &operator/=(intvec_t const &x) { return *this = *this / x; } + intvec_t &operator%=(intvec_t const &x) { return *this = *this % x; } + + intvec_t operator~() const { return ~v; } + + intvec_t operator&(intvec_t x) const { return v & x.v; } + intvec_t operator|(intvec_t x) const { return v | x.v; } + intvec_t operator^(intvec_t x) const { return v ^ x.v; } + + intvec_t &operator&=(intvec_t const &x) { return *this = *this & x; } + intvec_t &operator|=(intvec_t const &x) { return *this = *this | x; } + intvec_t &operator^=(intvec_t const &x) { return *this = *this ^ x; } + + intvec_t bitifthen(intvec_t x, intvec_t y) const; + + intvec_t lsr(int_t n) const { return U(v) >> U(n); } + intvec_t rotate(int_t n) const; + intvec_t operator>>(int_t n) const { return v >> n; } + intvec_t operator<<(int_t n) const { return v << n; } + + intvec_t &operator>>=(int_t n) { return *this = *this >> n; } + intvec_t &operator<<=(int_t n) { return *this = *this << n; } + + intvec_t lsr(intvec_t n) const { return U(v) >> U(n); } + intvec_t rotate(intvec_t n) const; + intvec_t operator>>(intvec_t n) const { return v >> n; } + intvec_t operator<<(intvec_t n) const { return v << n; } + + intvec_t &operator>>=(intvec_t n) { return *this = *this >> n; } + intvec_t &operator<<=(intvec_t n) { return *this = *this << n; } + + intvec_t clz() const { return __builtin_clz(v); } + intvec_t popcount() const { return __builtin_popcount(v); } + + boolvec_t operator==(intvec_t const &x) const { return v == x.v; } + boolvec_t operator!=(intvec_t const &x) const { return v != x.v; } + boolvec_t operator<(intvec_t const &x) const { return v < x.v; } + boolvec_t operator<=(intvec_t const &x) const { return v <= x.v; } + boolvec_t operator>(intvec_t const &x) const { return v > x.v; } + boolvec_t operator>=(intvec_t const &x) const { return v >= x.v; } + + intvec_t abs() const { return std::abs(v); } + boolvec_t isignbit() const { return v < 0; } + intvec_t max(intvec_t x) const { return std::max(v, x.v); } + intvec_t min(intvec_t x) const { return std::min(v, x.v); } +}; + +template <> struct realvec<float, 1> : floatprops<float> { + static int const size = 1; + typedef real_t scalar_t; + typedef float vector_t; + static int const alignment = sizeof(vector_t); + + static char const *name() { return "<SSE2:1*float>"; } + void barrier() { __asm__("" : "+x"(v)); } + + static_assert(size * sizeof(real_t) == sizeof(vector_t), + "vector size is wrong"); + +private: + static __m128 from_float(float a) { return _mm_set_ss(a); } + static float to_float(__m128 a) { return _mm_cvtss_f32(a); } + +public: + typedef boolvec<real_t, size> boolvec_t; + typedef intvec<real_t, size> intvec_t; + typedef realvec realvec_t; + + // Short names for type casts + typedef real_t R; + typedef int_t I; + typedef uint_t U; + typedef realvec_t RV; + typedef intvec_t IV; + typedef boolvec_t BV; + typedef floatprops<real_t> FP; + typedef mathfuncs<realvec_t> MF; + + vector_t v; + + realvec() {} + // Can't have a non-trivial copy constructor; if so, objects won't + // be passed in registers + // realvec(realvec const& x): v(x.v) {} + // realvec& operator=(realvec const& x) { return v=x.v, *this; } + realvec(real_t a) : v(a) {} + realvec(real_t const *as) : v(as[0]) {} + + operator vector_t() const { return v; } + real_t operator[](int n) const { return v; } + realvec_t &set_elt(int n, real_t a) { return v = a, *this; } + + typedef vecmathlib::mask_t<realvec_t> mask_t; + + static realvec_t loada(real_t const *p) { + VML_ASSERT(intptr_t(p) % alignment == 0); + return *p; + } + static realvec_t loadu(real_t const *p) { return *p; } + static realvec_t loadu(real_t const *p, std::ptrdiff_t ioff) { + VML_ASSERT(intptr_t(p) % alignment == 0); + return loada(p + ioff); + } + realvec_t loada(real_t const *p, mask_t const &m) const { + VML_ASSERT(intptr_t(p) % alignment == 0); + if (__builtin_expect(all(m.m), true)) { + return loada(p); + } else { + return *this; } - void storeu(real_t* p, mask_t const& m) const - { - if (__builtin_expect(m.all_m, true)) { - storeu(p); - } + } + realvec_t loadu(real_t const *p, mask_t const &m) const { + if (__builtin_expect(m.all_m, true)) { + return loadu(p); + } else { + return *this; } - void storeu(real_t* p, std::ptrdiff_t ioff, mask_t const& m) const - { - VML_ASSERT(intptr_t(p) % alignment == 0); - storea(p+ioff, m); + } + realvec_t loadu(real_t const *p, std::ptrdiff_t ioff, mask_t const &m) const { + VML_ASSERT(intptr_t(p) % alignment == 0); + return loada(p + ioff, m); + } + + void storea(real_t *p) const { + VML_ASSERT(intptr_t(p) % alignment == 0); + *p = v; + } + void storeu(real_t *p) const { *p = v; } + void storeu(real_t *p, std::ptrdiff_t ioff) const { + VML_ASSERT(intptr_t(p) % alignment == 0); + storea(p + ioff); + } + void storea(real_t *p, mask_t const &m) const { + VML_ASSERT(intptr_t(p) % alignment == 0); + if (__builtin_expect(m.all_m, true)) { + storea(p); } - - - - intvec_t as_int() const { return floatprops::as_int(v); } - intvec_t convert_int() const { - // return floatprops::convert_int(v); - return _mm_cvttss_si32(_mm_set_ss(v)); + } + void storeu(real_t *p, mask_t const &m) const { + if (__builtin_expect(m.all_m, true)) { + storeu(p); } - - - - realvec_t operator+() const { return +v; } - realvec_t operator-() const { return -v; } - - realvec_t operator+(realvec_t x) const { return v+x.v; } - realvec_t operator-(realvec_t x) const { return v-x.v; } - realvec_t operator*(realvec_t x) const { return v*x.v; } - realvec_t operator/(realvec_t x) const { return v/x.v; } - - realvec_t& operator+=(realvec_t const& x) { return *this=*this+x; } - realvec_t& operator-=(realvec_t const& x) { return *this=*this-x; } - realvec_t& operator*=(realvec_t const& x) { return *this=*this*x; } - realvec_t& operator/=(realvec_t const& x) { return *this=*this/x; } - - real_t maxval() const { return *this; } - real_t minval() const { return *this; } - real_t prod() const { return *this; } - real_t sum() const { return *this; } - - - - boolvec_t operator==(realvec_t const& x) const { return v==x.v; } - boolvec_t operator!=(realvec_t const& x) const { return v!=x.v; } - boolvec_t operator<(realvec_t const& x) const { return v<x.v; } - boolvec_t operator<=(realvec_t const& x) const { return v<=x.v; } - boolvec_t operator>(realvec_t const& x) const { return v>x.v; } - boolvec_t operator>=(realvec_t const& x) const { return v>=x.v; } - - - - realvec_t acos() const { return MF::vml_acos(*this); } - realvec_t acosh() const { return MF::vml_acosh(*this); } - realvec_t asin() const { return MF::vml_asin(*this); } - realvec_t asinh() const { return MF::vml_asinh(*this); } - realvec_t atan() const { return MF::vml_atan(*this); } - realvec_t atan2(realvec_t y) const { return MF::vml_atan2(*this, y); } - realvec_t atanh() const { return MF::vml_atanh(*this); } - realvec_t cbrt() const { return MF::vml_cbrt(*this); } - realvec_t ceil() const - { + } + void storeu(real_t *p, std::ptrdiff_t ioff, mask_t const &m) const { + VML_ASSERT(intptr_t(p) % alignment == 0); + storea(p + ioff, m); + } + + intvec_t as_int() const { return floatprops::as_int(v); } + intvec_t convert_int() const { + // return floatprops::convert_int(v); + return _mm_cvttss_si32(_mm_set_ss(v)); + } + + realvec_t operator+() const { return +v; } + realvec_t operator-() const { return -v; } + + realvec_t operator+(realvec_t x) const { return v + x.v; } + realvec_t operator-(realvec_t x) const { return v - x.v; } + realvec_t operator*(realvec_t x) const { return v * x.v; } + realvec_t operator/(realvec_t x) const { return v / x.v; } + + realvec_t &operator+=(realvec_t const &x) { return *this = *this + x; } + realvec_t &operator-=(realvec_t const &x) { return *this = *this - x; } + realvec_t &operator*=(realvec_t const &x) { return *this = *this * x; } + realvec_t &operator/=(realvec_t const &x) { return *this = *this / x; } + + real_t maxval() const { return *this; } + real_t minval() const { return *this; } + real_t prod() const { return *this; } + real_t sum() const { return *this; } + + boolvec_t operator==(realvec_t const &x) const { return v == x.v; } + boolvec_t operator!=(realvec_t const &x) const { return v != x.v; } + boolvec_t operator<(realvec_t const &x) const { return v < x.v; } + boolvec_t operator<=(realvec_t const &x) const { return v <= x.v; } + boolvec_t operator>(realvec_t const &x) const { return v > x.v; } + boolvec_t operator>=(realvec_t const &x) const { return v >= x.v; } + + realvec_t acos() const { return MF::vml_acos(*this); } + realvec_t acosh() const { return MF::vml_acosh(*this); } + realvec_t asin() const { return MF::vml_asin(*this); } + realvec_t asinh() const { return MF::vml_asinh(*this); } + realvec_t atan() const { return MF::vml_atan(*this); } + realvec_t atan2(realvec_t y) const { return MF::vml_atan2(*this, y); } + realvec_t atanh() const { return MF::vml_atanh(*this); } + realvec_t cbrt() const { return MF::vml_cbrt(*this); } + realvec_t ceil() const { #ifdef __SSE4_1__ - return to_float(_mm_ceil_ss(from_float(v), from_float(v))); + return to_float(_mm_ceil_ss(from_float(v), from_float(v))); #else - return vml_std::ceil(v); + return vml_std::ceil(v); #endif - } - realvec_t copysign(realvec_t y) const { return vml_std::copysign(v, y.v); } - realvec_t cos() const { return MF::vml_cos(*this); } - realvec_t cosh() const { return MF::vml_cosh(*this); } - realvec_t exp() const { return MF::vml_exp(*this); } - realvec_t exp10() const { return MF::vml_exp10(*this); } - realvec_t exp2() const { return MF::vml_exp2(*this); } - realvec_t expm1() const { return MF::vml_expm1(*this); } - realvec_t fabs() const { return vml_std::fabs(v); } - realvec_t fdim(realvec_t y) const { return MF::vml_fdim(*this, y); } - realvec_t floor() const - { + } + realvec_t copysign(realvec_t y) const { return vml_std::copysign(v, y.v); } + realvec_t cos() const { return MF::vml_cos(*this); } + realvec_t cosh() const { return MF::vml_cosh(*this); } + realvec_t exp() const { return MF::vml_exp(*this); } + realvec_t exp10() const { return MF::vml_exp10(*this); } + realvec_t exp2() const { return MF::vml_exp2(*this); } + realvec_t expm1() const { return MF::vml_expm1(*this); } + realvec_t fabs() const { return vml_std::fabs(v); } + realvec_t fdim(realvec_t y) const { return MF::vml_fdim(*this, y); } + realvec_t floor() const { #ifdef __SSE4_1__ - return to_float(_mm_floor_ss(from_float(v), from_float(v))); + return to_float(_mm_floor_ss(from_float(v), from_float(v))); #else - return vml_std::floor(v); + return vml_std::floor(v); #endif - } - realvec_t fma(realvec_t y, realvec_t z) const - { - return MF::vml_fma(*this, y, z); - } - realvec_t fmax(realvec_t y) const - { - return to_float(_mm_max_ss(from_float(v), from_float(y.v))); - } - realvec_t fmin(realvec_t y) const - { - return to_float(_mm_min_ss(from_float(v), from_float(y.v))); - } - realvec_t fmod(realvec_t y) const { return vml_std::fmod(v, y.v); } - realvec_t frexp(intvec_t* irp) const - { - int iri; - realvec_t r = vml_std::frexp(v, &iri); - int_t ir = iri; - if (isinf()) ir = std::numeric_limits<int_t>::max(); - if (isnan()) ir = std::numeric_limits<int_t>::min(); - irp->v = ir; - return r; - } - realvec_t hypot(realvec_t y) const { return MF::vml_hypot(*this, y); } - intvec_t ilogb() const - { - int_t r = vml_std::ilogb(v); - typedef std::numeric_limits<int_t> NL; - if (FP_ILOGB0 != NL::min() and *this == RV(R(0.0))) { - r = NL::min(); + } + realvec_t fma(realvec_t y, realvec_t z) const { + return MF::vml_fma(*this, y, z); + } + realvec_t fmax(realvec_t y) const { + return to_float(_mm_max_ss(from_float(v), from_float(y.v))); + } + realvec_t fmin(realvec_t y) const { + return to_float(_mm_min_ss(from_float(v), from_float(y.v))); + } + realvec_t fmod(realvec_t y) const { return vml_std::fmod(v, y.v); } + realvec_t frexp(intvec_t *irp) const { + int iri; + realvec_t r = vml_std::frexp(v, &iri); + int_t ir = iri; + if (isinf()) + ir = std::numeric_limits<int_t>::max(); + if (isnan()) + ir = std::numeric_limits<int_t>::min(); + irp->v = ir; + return r; + } + realvec_t hypot(realvec_t y) const { return MF::vml_hypot(*this, y); } + intvec_t ilogb() const { + int_t r = vml_std::ilogb(v); + typedef std::numeric_limits<int_t> NL; + if (FP_ILOGB0 != NL::min() and *this == RV(R(0.0))) { + r = NL::min(); #if defined VML_HAVE_INF - } else if (INT_MAX != NL::max() and vml_std::isinf(v)) { - r = NL::max(); + } else if (INT_MAX != NL::max() and vml_std::isinf(v)) { + r = NL::max(); #endif #if defined VML_HAVE_NAN - } else if (FP_ILOGBNAN != NL::min() and isnan()) { - r = NL::min(); + } else if (FP_ILOGBNAN != NL::min() and isnan()) { + r = NL::min(); #endif - } - return r; } - boolvec_t isfinite() const { return vml_std::isfinite(v); } - boolvec_t isinf() const { return vml_std::isinf(v); } - boolvec_t isnan() const - { + return r; + } + boolvec_t isfinite() const { return vml_std::isfinite(v); } + boolvec_t isinf() const { return vml_std::isinf(v); } + boolvec_t isnan() const { #if defined VML_HAVE_NAN - // This is wrong: - // return _mm_ucomineq_ss(from_float(v), from_float(v)); - // This works: - // char r; - // __asm__("ucomiss %[v],%[v]; setp %[r]": [r]"=q"(r): [v]"x"(v)); - // return boolvec_t::scalar_t(r); - // This works as well: - return vml_std::isnan(v); + // This is wrong: + // return _mm_ucomineq_ss(from_float(v), from_float(v)); + // This works: + // char r; + // __asm__("ucomiss %[v],%[v]; setp %[r]": [r]"=q"(r): [v]"x"(v)); + // return boolvec_t::scalar_t(r); + // This works as well: + return vml_std::isnan(v); #else - return BV(false); + return BV(false); #endif - } - boolvec_t isnormal() const { return vml_std::isnormal(v); } - realvec_t ldexp(int_t n) const { return vml_std::ldexp(v, n); } - realvec_t ldexp(intvec_t n) const { return vml_std::ldexp(v, n); } - realvec_t log() const { return MF::vml_log(*this); } - 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); } - realvec_t mad(realvec_t y, realvec_t z) const - { - return MF::vml_mad(*this, y, z); - } - realvec_t nextafter(realvec_t y) const - { - return MF::vml_nextafter(*this, y); - } - realvec_t pow(realvec_t y) const { return MF::vml_pow(*this, y); } - realvec_t rcp() const { return R(1.0)/v; } - realvec_t remainder(realvec_t y) const - { - return vml_std::remainder(v, y.v); - } - realvec_t rint() const - { + } + boolvec_t isnormal() const { return vml_std::isnormal(v); } + realvec_t ldexp(int_t n) const { return vml_std::ldexp(v, n); } + realvec_t ldexp(intvec_t n) const { return vml_std::ldexp(v, n); } + realvec_t log() const { return MF::vml_log(*this); } + 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); } + realvec_t mad(realvec_t y, realvec_t z) const { + return MF::vml_mad(*this, y, z); + } + realvec_t nextafter(realvec_t y) const { return MF::vml_nextafter(*this, y); } + realvec_t pow(realvec_t y) const { return MF::vml_pow(*this, y); } + realvec_t rcp() const { return R(1.0) / v; } + realvec_t remainder(realvec_t y) const { return vml_std::remainder(v, y.v); } + realvec_t rint() const { #ifdef __SSE4_1__ - return to_float(_mm_round_ss(from_float(v), from_float(v), - _MM_FROUND_TO_NEAREST_INT)); + return to_float( + _mm_round_ss(from_float(v), from_float(v), _MM_FROUND_TO_NEAREST_INT)); #else - return MF::vml_rint(*this); + return MF::vml_rint(*this); #endif - } - realvec_t round() const { return MF::vml_round(*this); } - realvec_t rsqrt() const { return MF::vml_rsqrt(*this); } - boolvec_t signbit() const { return vml_std::signbit(v); } - realvec_t sin() const { return MF::vml_sin(*this); } - realvec_t sinh() const { return MF::vml_sinh(*this); } - realvec_t sqrt() const { return to_float(_mm_sqrt_ss(from_float(v))); } - realvec_t tan() const { return MF::vml_tan(*this); } - realvec_t tanh() const { return MF::vml_tanh(*this); } - realvec_t trunc() const - { + } + realvec_t round() const { return MF::vml_round(*this); } + realvec_t rsqrt() const { return MF::vml_rsqrt(*this); } + boolvec_t signbit() const { return vml_std::signbit(v); } + realvec_t sin() const { return MF::vml_sin(*this); } + realvec_t sinh() const { return MF::vml_sinh(*this); } + realvec_t sqrt() const { return to_float(_mm_sqrt_ss(from_float(v))); } + realvec_t tan() const { return MF::vml_tan(*this); } + realvec_t tanh() const { return MF::vml_tanh(*this); } + realvec_t trunc() const { #ifdef __SSE4_1__ - return to_float(_mm_round_ss(from_float(v), from_float(v), - _MM_FROUND_TO_ZERO)); + return to_float( + _mm_round_ss(from_float(v), from_float(v), _MM_FROUND_TO_ZERO)); #else - return MF::vml_trunc(*this); + return MF::vml_trunc(*this); #endif - } - }; - - - - // boolvec definitions - - inline intvec<float,1> boolvec<float,1>::as_int() const - { - return I(v); - } - - inline intvec<float,1> boolvec<float,1>::convert_int() const - { - return v; - } - - inline - boolvec<float,1> boolvec<float,1>::ifthen(boolvec_t x, boolvec_t y) const - { - return v ? x : y; - } - - inline intvec<float,1> boolvec<float,1>::ifthen(intvec_t x, intvec_t y) const - { - return v ? x : y; - } - - inline - realvec<float,1> boolvec<float,1>::ifthen(realvec_t x, realvec_t y) const - { - return v ? x : y; - } - - - - // intvec definitions - - inline realvec<float,1> intvec<float,1>::as_float() const - { - return FP::as_float(v); - } - - inline intvec<float,1> intvec<float,1>::bitifthen(intvec_t x, - intvec_t y) const - { - return MF::vml_bitifthen(*this, x, y); - } - - inline realvec<float,1> intvec<float,1>::convert_float() const - { - // return FP::convert_float(v); - return _mm_cvtss_f32(_mm_cvtsi32_ss(_mm_setzero_ps(), v)); } - - inline intvec<float,1> intvec<float,1>::rotate(int_t n) const - { - return MF::vml_rotate(*this, n); - } - - inline intvec<float,1> intvec<float,1>::rotate(intvec_t n) const - { - return MF::vml_rotate(*this, n); - } - +}; + +// boolvec definitions + +inline intvec<float, 1> boolvec<float, 1>::as_int() const { return I(v); } + +inline intvec<float, 1> boolvec<float, 1>::convert_int() const { return v; } + +inline boolvec<float, 1> boolvec<float, 1>::ifthen(boolvec_t x, + boolvec_t y) const { + return v ? x : y; +} + +inline intvec<float, 1> boolvec<float, 1>::ifthen(intvec_t x, + intvec_t y) const { + return v ? x : y; +} + +inline realvec<float, 1> boolvec<float, 1>::ifthen(realvec_t x, + realvec_t y) const { + return v ? x : y; +} + +// intvec definitions + +inline realvec<float, 1> intvec<float, 1>::as_float() const { + return FP::as_float(v); +} + +inline intvec<float, 1> intvec<float, 1>::bitifthen(intvec_t x, + intvec_t y) const { + return MF::vml_bitifthen(*this, x, y); +} + +inline realvec<float, 1> intvec<float, 1>::convert_float() const { + // return FP::convert_float(v); + return _mm_cvtss_f32(_mm_cvtsi32_ss(_mm_setzero_ps(), v)); +} + +inline intvec<float, 1> intvec<float, 1>::rotate(int_t n) const { + return MF::vml_rotate(*this, n); +} + +inline intvec<float, 1> intvec<float, 1>::rotate(intvec_t n) const { + return MF::vml_rotate(*this, n); +} + } // namespace vecmathlib -#endif // #ifndef VEC_SSE_FLOAT1_H +#endif // #ifndef VEC_SSE_FLOAT1_H |