diff options
author | Erik Schnetter <schnetter@gmail.com> | 2015-10-16 13:45:31 -0400 |
---|---|---|
committer | Erik Schnetter <schnetter@gmail.com> | 2015-10-16 13:45:31 -0400 |
commit | 06ddf9a62fd6e991dfcf0bd2abe0941b960cb2bb (patch) | |
tree | 793b48ebee5b9c779c8afd34cc20245c93b9ad9d /vec_neon_float2.h | |
parent | 71a4a6821276690eed15df8d2c246be499da1e29 (diff) | |
download | vecmathlib-06ddf9a62fd6e991dfcf0bd2abe0941b960cb2bb.zip vecmathlib-06ddf9a62fd6e991dfcf0bd2abe0941b960cb2bb.tar.gz |
Reformat source code with clang-format
Note: If you have an existing checkout with modifications, then you should:
(1) save your current state on a branch
(2) run clang-format on this branch
(3) compare this branch to a fresh checkout of the clang-formatted master
Since both your branch and master have been formatted with clang-format, this will lead to a very small diff, avoiding spurious changes due to formatting differences.
Diffstat (limited to 'vec_neon_float2.h')
-rw-r--r-- | vec_neon_float2.h | 1085 |
1 files changed, 494 insertions, 591 deletions
diff --git a/vec_neon_float2.h b/vec_neon_float2.h index 3a21a05..6df9969 100644 --- a/vec_neon_float2.h +++ b/vec_neon_float2.h @@ -14,608 +14,511 @@ // Neon intrinsics #include <arm_neon.h> - - namespace vecmathlib { - + #define VECMATHLIB_HAVE_VEC_FLOAT_2 - template<> struct boolvec<float,2>; - template<> struct intvec<float,2>; - template<> struct realvec<float,2>; - - - - template<> - struct boolvec<float,2>: floatprops<float> - { - static int const size = 2; - typedef bool scalar_t; - typedef uint32x2_t bvector_t; - static int const alignment = sizeof(bvector_t); - - static_assert(size * sizeof(real_t) == sizeof(bvector_t), - "vector size is wrong"); - - private: - // true values are -1, false values are 0 - static uint_t from_bool(bool a) { return -int_t(a); } - static bool to_bool(uint_t a) { return a; } - public: - - 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(vdup_n_u32(from_bool(a))) {} - boolvec(bool const* as) - { - for (int d=0; d<size; ++d) set_elt(d, as[d]); - } - - operator bvector_t() const { return v; } - bool operator[](int n) const - { - return to_bool(vecmathlib::get_elt<BV,bvector_t,uint_t>(v, n)); - } - boolvec& set_elt(int n, bool a) - { - return - vecmathlib::set_elt<BV,bvector_t,uint_t>(v, n, from_bool(a)), *this; - } - - - - intvec_t as_int() const; // defined after intvec - intvec_t convert_int() const; // defined after intvec - - - - boolvec operator!() const { return vmvn_u32(v); } - - boolvec operator&&(boolvec x) const { return vand_u32(v, x.v); } - boolvec operator||(boolvec x) const { return vorr_u32(v, x.v); } - boolvec operator==(boolvec x) const { return vceq_u32(v, x.v); } - boolvec operator!=(boolvec x) const { return veor_u32(v, x.v); } - - bool all() const - { - boolvec r = vpmin_u32(v, v); - return r[0]; - } - bool any() const - { - boolvec r = vpmax_u32(v, v); - return r[0]; - } - - - - // 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,2>: floatprops<float> - { - static int const size = 2; - typedef int_t scalar_t; - typedef int32x2_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(ivector_t x): v(x) {} - intvec(int_t a): v(vdup_n_s32(a)) {} - intvec(int_t const* as) - { - for (int d=0; d<size; ++d) set_elt(d, as[d]); - } - static intvec iota() - { - return vcreate_s32((uint64_t(1) << uint64_t(32)) | uint64_t(0)); - } - - operator ivector_t() const { return v; } - int_t operator[](int n) const - { - return vecmathlib::get_elt<IV,ivector_t,int_t>(v, n); - } - intvec_t& set_elt(int n, int_t a) - { - return vecmathlib::set_elt<IV,ivector_t,int_t>(v, n, a), *this; - } - - - - // Vector casts do not change the bit battern - boolvec_t as_bool() const { return vreinterpret_u32_s32(v); } - boolvec_t convert_bool() const { return *this != IV(0); } - realvec_t as_float() const; // defined after realvec - realvec_t convert_float() const; // defined after realvec - - - - intvec operator+() const { return *this; } - intvec operator-() const { return vneg_s32(v); } - - intvec operator+(intvec x) const { return vadd_s32(v, x.v); } - intvec operator-(intvec x) const { return vsub_s32(v, x.v); } - intvec operator*(intvec x) const { return vmul_s32(v, x.v); } - - intvec& operator+=(intvec const& x) { return *this=*this+x; } - intvec& operator-=(intvec const& x) { return *this=*this-x; } - intvec& operator*=(intvec const& x) { return *this=*this*x; } - - - - intvec operator~() const { return vmvn_s32(v); } - - intvec operator&(intvec x) const { return vand_s32(v, x.v); } - intvec operator|(intvec x) const { return vorr_s32(v, x.v); } - intvec operator^(intvec x) const { return veor_s32(v, x.v); } - - intvec& operator&=(intvec const& x) { return *this=*this&x; } - intvec& operator|=(intvec const& x) { return *this=*this|x; } - intvec& operator^=(intvec const& x) { return *this=*this^x; } - - intvec_t bitifthen(intvec_t x, intvec_t y) const - { - return vbsl_s32(vreinterpret_u32_s32(v), x.v, y.v); - } - - - - intvec_t lsr(int_t n) const { return lsr(IV(n)); } - intvec_t rotate(int_t n) const; - intvec operator>>(int_t n) const { return *this >> IV(n); } - intvec operator<<(int_t n) const { return *this << IV(n); } - intvec& operator>>=(int_t n) { return *this=*this>>n; } - intvec& operator<<=(int_t n) { return *this=*this<<n; } - - intvec lsr(intvec n) const - { - return vreinterpret_s32_u32(vshl_u32(vreinterpret_u32_s32(v), (-n).v)); - } - intvec_t rotate(intvec_t n) const; - intvec operator>>(intvec n) const - { - return vshl_s32(v, (-n).v); - } - intvec operator<<(intvec n) const - { - return vshl_s32(v, n.v); - } - intvec& operator>>=(intvec n) { return *this=*this>>n; } - intvec& operator<<=(intvec n) { return *this=*this<<n; } - - intvec_t clz() const { return vclz_s32(v); } - intvec_t popcount() const - { - return vpaddl_s16(vpaddl_s8(vcnt_s8(vreinterpret_s8_s32(v)))); - } - - - - boolvec_t operator==(intvec const& x) const { return vceq_s32(v, x.v); } - boolvec_t operator!=(intvec const& x) const { return !(*this == x); } - boolvec_t operator<(intvec const& x) const { return vclt_s32(v, x.v); } - boolvec_t operator<=(intvec const& x) const { return vcle_s32(v, x.v); } - boolvec_t operator>(intvec const& x) const { return vcgt_s32(v, x.v); } - boolvec_t operator>=(intvec const& x) const { return vcge_s32(v, x.v); } - - intvec_t abs() const { return vabs_s32(v); } - boolvec_t isignbit() const - { - //return *this < IV(I(0)); - return intvec(vshr_n_s32(v, FP::bits-1)).as_bool(); - } - intvec_t max(intvec_t x) const { return vmax_s32(v, x.v); } - intvec_t min(intvec_t x) const { return vmin_s32(v, x.v); } - }; - - - - template<> - struct realvec<float,2>: floatprops<float> - { - static int const size = 2; - typedef real_t scalar_t; - typedef float32x2_t vector_t; - static int const alignment = sizeof(vector_t); - - static char const* name() { return "<NEON:2*float>"; } - void barrier() { __asm__("": "+w"(v)); } - - static_assert(size * sizeof(real_t) == sizeof(vector_t), - "vector size is wrong"); - - 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(vector_t x): v(x) {} - realvec(real_t a): v(vdup_n_f32(a)) {} - realvec(real_t const* as) - { - for (int d=0; d<size; ++d) set_elt(d, as[d]); - } - - operator vector_t() const { return v; } - real_t operator[](int n) const - { - return vecmathlib::get_elt<RV,vector_t,real_t>(v, n); - } - realvec_t& set_elt(int n, real_t a) - { - return vecmathlib::set_elt<RV,vector_t,real_t>(v, n, 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 vld1_f32(p); - } - static realvec_t loadu(real_t const* p) - { +template <> struct boolvec<float, 2>; +template <> struct intvec<float, 2>; +template <> struct realvec<float, 2>; + +template <> struct boolvec<float, 2> : floatprops<float> { + static int const size = 2; + typedef bool scalar_t; + typedef uint32x2_t bvector_t; + static int const alignment = sizeof(bvector_t); + + static_assert(size * sizeof(real_t) == sizeof(bvector_t), + "vector size is wrong"); + +private: + // true values are -1, false values are 0 + static uint_t from_bool(bool a) { return -int_t(a); } + static bool to_bool(uint_t a) { return a; } + +public: + 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(vdup_n_u32(from_bool(a))) {} + boolvec(bool const *as) { + for (int d = 0; d < size; ++d) + set_elt(d, as[d]); + } + + operator bvector_t() const { return v; } + bool operator[](int n) const { + return to_bool(vecmathlib::get_elt<BV, bvector_t, uint_t>(v, n)); + } + boolvec &set_elt(int n, bool a) { + return vecmathlib::set_elt<BV, bvector_t, uint_t>(v, n, from_bool(a)), + *this; + } + + intvec_t as_int() const; // defined after intvec + intvec_t convert_int() const; // defined after intvec + + boolvec operator!() const { return vmvn_u32(v); } + + boolvec operator&&(boolvec x) const { return vand_u32(v, x.v); } + boolvec operator||(boolvec x) const { return vorr_u32(v, x.v); } + boolvec operator==(boolvec x) const { return vceq_u32(v, x.v); } + boolvec operator!=(boolvec x) const { return veor_u32(v, x.v); } + + bool all() const { + boolvec r = vpmin_u32(v, v); + return r[0]; + } + bool any() const { + boolvec r = vpmax_u32(v, v); + return r[0]; + } + + // 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, 2> : floatprops<float> { + static int const size = 2; + typedef int_t scalar_t; + typedef int32x2_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(ivector_t x) : v(x) {} + intvec(int_t a) : v(vdup_n_s32(a)) {} + intvec(int_t const *as) { + for (int d = 0; d < size; ++d) + set_elt(d, as[d]); + } + static intvec iota() { + return vcreate_s32((uint64_t(1) << uint64_t(32)) | uint64_t(0)); + } + + operator ivector_t() const { return v; } + int_t operator[](int n) const { + return vecmathlib::get_elt<IV, ivector_t, int_t>(v, n); + } + intvec_t &set_elt(int n, int_t a) { + return vecmathlib::set_elt<IV, ivector_t, int_t>(v, n, a), *this; + } + + // Vector casts do not change the bit battern + boolvec_t as_bool() const { return vreinterpret_u32_s32(v); } + boolvec_t convert_bool() const { return *this != IV(0); } + realvec_t as_float() const; // defined after realvec + realvec_t convert_float() const; // defined after realvec + + intvec operator+() const { return *this; } + intvec operator-() const { return vneg_s32(v); } + + intvec operator+(intvec x) const { return vadd_s32(v, x.v); } + intvec operator-(intvec x) const { return vsub_s32(v, x.v); } + intvec operator*(intvec x) const { return vmul_s32(v, x.v); } + + intvec &operator+=(intvec const &x) { return *this = *this + x; } + intvec &operator-=(intvec const &x) { return *this = *this - x; } + intvec &operator*=(intvec const &x) { return *this = *this * x; } + + intvec operator~() const { return vmvn_s32(v); } + + intvec operator&(intvec x) const { return vand_s32(v, x.v); } + intvec operator|(intvec x) const { return vorr_s32(v, x.v); } + intvec operator^(intvec x) const { return veor_s32(v, x.v); } + + intvec &operator&=(intvec const &x) { return *this = *this & x; } + intvec &operator|=(intvec const &x) { return *this = *this | x; } + intvec &operator^=(intvec const &x) { return *this = *this ^ x; } + + intvec_t bitifthen(intvec_t x, intvec_t y) const { + return vbsl_s32(vreinterpret_u32_s32(v), x.v, y.v); + } + + intvec_t lsr(int_t n) const { return lsr(IV(n)); } + intvec_t rotate(int_t n) const; + intvec operator>>(int_t n) const { return *this >> IV(n); } + intvec operator<<(int_t n) const { return *this << IV(n); } + intvec &operator>>=(int_t n) { return *this = *this >> n; } + intvec &operator<<=(int_t n) { return *this = *this << n; } + + intvec lsr(intvec n) const { + return vreinterpret_s32_u32(vshl_u32(vreinterpret_u32_s32(v), (-n).v)); + } + intvec_t rotate(intvec_t n) const; + intvec operator>>(intvec n) const { return vshl_s32(v, (-n).v); } + intvec operator<<(intvec n) const { return vshl_s32(v, n.v); } + intvec &operator>>=(intvec n) { return *this = *this >> n; } + intvec &operator<<=(intvec n) { return *this = *this << n; } + + intvec_t clz() const { return vclz_s32(v); } + intvec_t popcount() const { + return vpaddl_s16(vpaddl_s8(vcnt_s8(vreinterpret_s8_s32(v)))); + } + + boolvec_t operator==(intvec const &x) const { return vceq_s32(v, x.v); } + boolvec_t operator!=(intvec const &x) const { return !(*this == x); } + boolvec_t operator<(intvec const &x) const { return vclt_s32(v, x.v); } + boolvec_t operator<=(intvec const &x) const { return vcle_s32(v, x.v); } + boolvec_t operator>(intvec const &x) const { return vcgt_s32(v, x.v); } + boolvec_t operator>=(intvec const &x) const { return vcge_s32(v, x.v); } + + intvec_t abs() const { return vabs_s32(v); } + boolvec_t isignbit() const { + // return *this < IV(I(0)); + return intvec(vshr_n_s32(v, FP::bits - 1)).as_bool(); + } + intvec_t max(intvec_t x) const { return vmax_s32(v, x.v); } + intvec_t min(intvec_t x) const { return vmin_s32(v, x.v); } +}; + +template <> struct realvec<float, 2> : floatprops<float> { + static int const size = 2; + typedef real_t scalar_t; + typedef float32x2_t vector_t; + static int const alignment = sizeof(vector_t); + + static char const *name() { return "<NEON:2*float>"; } + void barrier() { __asm__("" : "+w"(v)); } + + static_assert(size * sizeof(real_t) == sizeof(vector_t), + "vector size is wrong"); + + 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(vector_t x) : v(x) {} + realvec(real_t a) : v(vdup_n_f32(a)) {} + realvec(real_t const *as) { + for (int d = 0; d < size; ++d) + set_elt(d, as[d]); + } + + operator vector_t() const { return v; } + real_t operator[](int n) const { + return vecmathlib::get_elt<RV, vector_t, real_t>(v, n); + } + realvec_t &set_elt(int n, real_t a) { + return vecmathlib::set_elt<RV, vector_t, real_t>(v, n, 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 vld1_f32(p); + } + static realvec_t loadu(real_t const *p) { #if defined __ARM_FEATURE_UNALIGNED - return vld1_f32(p); + return vld1_f32(p); #else - realvec_t r; - r.set_elt(0, p[0]); - r.set_elt(1, p[1]); - return r; + realvec_t r; + r.set_elt(0, p[0]); + r.set_elt(1, p[1]); + return r; #endif + } + static realvec_t loadu(real_t const *p, std::ptrdiff_t ioff) { + VML_ASSERT(intptr_t(p) % alignment == 0); + if (ioff % realvec::size == 0) + return loada(p + ioff); + return loadu(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 m.m.ifthen(loada(p), *this); } - static realvec_t loadu(real_t const* p, std::ptrdiff_t ioff) - { - VML_ASSERT(intptr_t(p) % alignment == 0); - if (ioff % realvec::size == 0) return loada(p+ioff); - return loadu(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 m.m.ifthen(loada(p), *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 m.m.ifthen(loadu(p), *this); - } - } - realvec_t loadu(real_t const* p, std::ptrdiff_t ioff, mask_t const& m) const - { - VML_ASSERT(intptr_t(p) % alignment == 0); - if (ioff % realvec::size == 0) return loada(p+ioff, m); - return loadu(p+ioff, m); - } - - void storea(real_t* p) const - { - VML_ASSERT(intptr_t(p) % alignment == 0); - vst1_f32(p, v); + } + realvec_t loadu(real_t const *p, mask_t const &m) const { + if (__builtin_expect(m.all_m, true)) { + return loadu(p); + } else { + return m.m.ifthen(loadu(p), *this); } - void storeu(real_t* p) const - { - // Vector stores would require vector loads, which would need to - // be atomic + } + realvec_t loadu(real_t const *p, std::ptrdiff_t ioff, mask_t const &m) const { + VML_ASSERT(intptr_t(p) % alignment == 0); + if (ioff % realvec::size == 0) + return loada(p + ioff, m); + return loadu(p + ioff, m); + } + + void storea(real_t *p) const { + VML_ASSERT(intptr_t(p) % alignment == 0); + vst1_f32(p, v); + } + void storeu(real_t *p) const { +// Vector stores would require vector loads, which would need to +// be atomic #if defined __ARM_FEATURE_UNALIGNED - vst1_f32(p, v); + vst1_f32(p, v); #else - p[0] = (*this)[0]; - p[1] = (*this)[1]; + p[0] = (*this)[0]; + p[1] = (*this)[1]; #endif + } + void storeu(real_t *p, std::ptrdiff_t ioff) const { + VML_ASSERT(intptr_t(p) % alignment == 0); + if (ioff % realvec::size == 0) + return storea(p + ioff); + storeu(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); + } else { + if (m.m[0]) + p[0] = (*this)[0]; + if (m.m[1]) + p[1] = (*this)[1]; } - void storeu(real_t* p, std::ptrdiff_t ioff) const - { - VML_ASSERT(intptr_t(p) % alignment == 0); - if (ioff % realvec::size == 0) return storea(p+ioff); - storeu(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); - } else { - if (m.m[0]) p[0] = (*this)[0]; - if (m.m[1]) p[1] = (*this)[1]; - } - } - void storeu(real_t* p, mask_t const& m) const - { - if (__builtin_expect(m.all_m, true)) { - storeu(p); - } else { - if (m.m[0]) p[0] = (*this)[0]; - if (m.m[1]) p[1] = (*this)[1]; - } - } - void storeu(real_t* p, std::ptrdiff_t ioff, mask_t const& m) const - { - VML_ASSERT(intptr_t(p) % alignment == 0); - if (ioff % realvec::size == 0) return storea(p+ioff, m); - storeu(p+ioff, m); - } - - - - intvec_t as_int() const { return vreinterpret_s32_f32(v); } - intvec_t convert_int() const { return vcvt_s32_f32(v); } - - - - realvec operator+() const { return *this; } - realvec operator-() const { return vneg_f32(v); } - - realvec operator+(realvec x) const { return vadd_f32(v, x.v); } - realvec operator-(realvec x) const { return vsub_f32(v, x.v); } - realvec operator*(realvec x) const { return vmul_f32(v, x.v); } - realvec operator/(realvec x) const { return *this * x.rcp(); } - - realvec& operator+=(realvec const& x) { return *this=*this+x; } - realvec& operator-=(realvec const& x) { return *this=*this-x; } - realvec& operator*=(realvec const& x) { return *this=*this*x; } - realvec& operator/=(realvec const& x) { return *this=*this/x; } - - real_t maxval() const - { - realvec r = vpmax_f32(v, v); - return r[0]; - } - real_t minval() const - { - realvec r = vpmin_f32(v, v); - return r[0]; - } - real_t prod() const - { - return (*this)[0] * (*this)[1]; - } - real_t sum() const - { - realvec r = vpadd_f32(v, v); - return r[0]; - } - - - - boolvec_t operator==(realvec const& x) const { return vceq_f32(v, x.v); } - boolvec_t operator!=(realvec const& x) const { return !(*this == x); } - boolvec_t operator<(realvec const& x) const { return vclt_f32(v, x.v); } - boolvec_t operator<=(realvec const& x) const { return vcle_f32(v, x.v); } - boolvec_t operator>(realvec const& x) const { return vcgt_f32(v, x.v); } - boolvec_t operator>=(realvec const& x) const { return vcge_f32(v, x.v); } - - - - realvec acos() const { return MF::vml_acos(*this); } - realvec acosh() const { return MF::vml_acosh(*this); } - realvec asin() const { return MF::vml_asin(*this); } - realvec asinh() const { return MF::vml_asinh(*this); } - realvec atan() const { return MF::vml_atan(*this); } - realvec atan2(realvec y) const { return MF::vml_atan2(*this, y); } - realvec atanh() const { return MF::vml_atanh(*this); } - realvec cbrt() const { return MF::vml_cbrt(*this); } - realvec ceil() const - { - // return vrndp_f32(v); - return MF::vml_ceil(*this); - } - realvec copysign(realvec y) const - { - return vbsl_f32(vdup_n_u32(FP::signbit_mask), y.v, v); - } - realvec cos() const { return MF::vml_cos(*this); } - realvec cosh() const { return MF::vml_cosh(*this); } - realvec exp() const { return MF::vml_exp(*this); } - realvec exp10() const { return MF::vml_exp10(*this); } - realvec exp2() const { return MF::vml_exp2(*this); } - realvec expm1() const { return MF::vml_expm1(*this); } - realvec fabs() const { return vabs_f32(v); } - realvec fdim(realvec y) const { return MF::vml_fdim(*this, y); } - realvec floor() const - { - // return vrndm_f32(v); - return MF::vml_floor(*this); - } - realvec_t fma(realvec_t y, realvec_t z) const - { - return vfma_f32(z.v, v, y.v); - } - realvec fmax(realvec y) const { return vmax_f32(v, y.v); } - realvec fmin(realvec y) const { return vmin_f32(v, y.v); } - realvec fmod(realvec y) const { return MF::vml_fmod(*this, y); } - realvec frexp(intvec_t* r) const { return MF::vml_frexp(*this, r); } - realvec hypot(realvec y) const { return MF::vml_hypot(*this, y); } - intvec_t ilogb() const { return MF::vml_ilogb(*this); } - boolvec_t isfinite() const { return MF::vml_isfinite(*this); } - boolvec_t isinf() const { return MF::vml_isinf(*this); } - boolvec_t isnan() const { return MF::vml_isnan(*this); } - boolvec_t isnormal() const { return MF::vml_isnormal(*this); } - realvec ldexp(int_t n) const { return MF::vml_ldexp(*this, n); } - realvec ldexp(intvec_t n) const { return MF::vml_ldexp(*this, n); } - realvec log() const { return MF::vml_log(*this); } - realvec log10() const { return MF::vml_log10(*this); } - realvec log1p() const { return MF::vml_log1p(*this); } - realvec log2() const { return MF::vml_log2(*this); } - realvec_t mad(realvec_t y, realvec_t z) const - { - // TODO: vfma_f32 - return vmla_f32(z.v, v, y.v); - } - realvec nextafter(realvec y) const { return MF::vml_nextafter(*this, y); } - realvec pow(realvec y) const { return MF::vml_pow(*this, y); } - realvec rcp() const - { - realvec r = vrecpe_f32(v); - r *= vrecps_f32(v, r); - r *= vrecps_f32(v, r); - return r; - } - realvec remainder(realvec y) const { return MF::vml_remainder(*this, y); } - realvec rint() const - { - // return vrndn_f32(v); - return MF::vml_rint(*this); - } - realvec round() const - { - // return vrnda_f32(v); - return MF::vml_round(*this); - } - realvec rsqrt() const - { - realvec r = vrsqrte_f32(v); - r *= vrsqrts_f32(v, r*r); - r *= vrsqrts_f32(v, r*r); - return r; - } - boolvec_t signbit() const { return MF::vml_signbit(*this); } - realvec sin() const { return MF::vml_sin(*this); } - realvec sinh() const { return MF::vml_sinh(*this); } - realvec sqrt() const { return *this * rsqrt(); } - realvec tan() const { return MF::vml_tan(*this); } - realvec tanh() const { return MF::vml_tanh(*this); } - realvec trunc() const - { - // return vrnd_f32(v); - return MF::vml_trunc(*this); + } + void storeu(real_t *p, mask_t const &m) const { + if (__builtin_expect(m.all_m, true)) { + storeu(p); + } else { + if (m.m[0]) + p[0] = (*this)[0]; + if (m.m[1]) + p[1] = (*this)[1]; } - }; - - - - // boolvec definitions - - inline intvec<float,2> boolvec<float,2>::as_int() const - { - return vreinterpret_s32_u32(v); - } - - inline intvec<float,2> boolvec<float,2>::convert_int() const - { - return - as_int(); - } - - inline - boolvec<float,2> boolvec<float,2>::ifthen(boolvec_t x, boolvec_t y) const - { - return vbsl_u32(v, x.v, y.v); - } - - inline intvec<float,2> boolvec<float,2>::ifthen(intvec_t x, intvec_t y) const - { - return vbsl_s32(v, x.v, y.v); - } - - inline - realvec<float,2> boolvec<float,2>::ifthen(realvec_t x, realvec_t y) const - { - return vbsl_f32(v, x.v, y.v); - } - - - - // intvec definitions - - inline realvec<float,2> intvec<float,2>::as_float() const - { - return vreinterpret_f32_s32(v); - } - - inline realvec<float,2> intvec<float,2>::convert_float() const - { - return vcvt_f32_s32(v); - } - - inline intvec<float,2> intvec<float,2>::rotate(int_t n) const - { - return MF::vml_rotate(*this, n); - } - - inline intvec<float,2> intvec<float,2>::rotate(intvec_t n) const - { - return MF::vml_rotate(*this, n); - } - + } + void storeu(real_t *p, std::ptrdiff_t ioff, mask_t const &m) const { + VML_ASSERT(intptr_t(p) % alignment == 0); + if (ioff % realvec::size == 0) + return storea(p + ioff, m); + storeu(p + ioff, m); + } + + intvec_t as_int() const { return vreinterpret_s32_f32(v); } + intvec_t convert_int() const { return vcvt_s32_f32(v); } + + realvec operator+() const { return *this; } + realvec operator-() const { return vneg_f32(v); } + + realvec operator+(realvec x) const { return vadd_f32(v, x.v); } + realvec operator-(realvec x) const { return vsub_f32(v, x.v); } + realvec operator*(realvec x) const { return vmul_f32(v, x.v); } + realvec operator/(realvec x) const { return *this * x.rcp(); } + + realvec &operator+=(realvec const &x) { return *this = *this + x; } + realvec &operator-=(realvec const &x) { return *this = *this - x; } + realvec &operator*=(realvec const &x) { return *this = *this * x; } + realvec &operator/=(realvec const &x) { return *this = *this / x; } + + real_t maxval() const { + realvec r = vpmax_f32(v, v); + return r[0]; + } + real_t minval() const { + realvec r = vpmin_f32(v, v); + return r[0]; + } + real_t prod() const { return (*this)[0] * (*this)[1]; } + real_t sum() const { + realvec r = vpadd_f32(v, v); + return r[0]; + } + + boolvec_t operator==(realvec const &x) const { return vceq_f32(v, x.v); } + boolvec_t operator!=(realvec const &x) const { return !(*this == x); } + boolvec_t operator<(realvec const &x) const { return vclt_f32(v, x.v); } + boolvec_t operator<=(realvec const &x) const { return vcle_f32(v, x.v); } + boolvec_t operator>(realvec const &x) const { return vcgt_f32(v, x.v); } + boolvec_t operator>=(realvec const &x) const { return vcge_f32(v, x.v); } + + realvec acos() const { return MF::vml_acos(*this); } + realvec acosh() const { return MF::vml_acosh(*this); } + realvec asin() const { return MF::vml_asin(*this); } + realvec asinh() const { return MF::vml_asinh(*this); } + realvec atan() const { return MF::vml_atan(*this); } + realvec atan2(realvec y) const { return MF::vml_atan2(*this, y); } + realvec atanh() const { return MF::vml_atanh(*this); } + realvec cbrt() const { return MF::vml_cbrt(*this); } + realvec ceil() const { + // return vrndp_f32(v); + return MF::vml_ceil(*this); + } + realvec copysign(realvec y) const { + return vbsl_f32(vdup_n_u32(FP::signbit_mask), y.v, v); + } + realvec cos() const { return MF::vml_cos(*this); } + realvec cosh() const { return MF::vml_cosh(*this); } + realvec exp() const { return MF::vml_exp(*this); } + realvec exp10() const { return MF::vml_exp10(*this); } + realvec exp2() const { return MF::vml_exp2(*this); } + realvec expm1() const { return MF::vml_expm1(*this); } + realvec fabs() const { return vabs_f32(v); } + realvec fdim(realvec y) const { return MF::vml_fdim(*this, y); } + realvec floor() const { + // return vrndm_f32(v); + return MF::vml_floor(*this); + } + realvec_t fma(realvec_t y, realvec_t z) const { + return vfma_f32(z.v, v, y.v); + } + realvec fmax(realvec y) const { return vmax_f32(v, y.v); } + realvec fmin(realvec y) const { return vmin_f32(v, y.v); } + realvec fmod(realvec y) const { return MF::vml_fmod(*this, y); } + realvec frexp(intvec_t *r) const { return MF::vml_frexp(*this, r); } + realvec hypot(realvec y) const { return MF::vml_hypot(*this, y); } + intvec_t ilogb() const { return MF::vml_ilogb(*this); } + boolvec_t isfinite() const { return MF::vml_isfinite(*this); } + boolvec_t isinf() const { return MF::vml_isinf(*this); } + boolvec_t isnan() const { return MF::vml_isnan(*this); } + boolvec_t isnormal() const { return MF::vml_isnormal(*this); } + realvec ldexp(int_t n) const { return MF::vml_ldexp(*this, n); } + realvec ldexp(intvec_t n) const { return MF::vml_ldexp(*this, n); } + realvec log() const { return MF::vml_log(*this); } + realvec log10() const { return MF::vml_log10(*this); } + realvec log1p() const { return MF::vml_log1p(*this); } + realvec log2() const { return MF::vml_log2(*this); } + realvec_t mad(realvec_t y, realvec_t z) const { + // TODO: vfma_f32 + return vmla_f32(z.v, v, y.v); + } + realvec nextafter(realvec y) const { return MF::vml_nextafter(*this, y); } + realvec pow(realvec y) const { return MF::vml_pow(*this, y); } + realvec rcp() const { + realvec r = vrecpe_f32(v); + r *= vrecps_f32(v, r); + r *= vrecps_f32(v, r); + return r; + } + realvec remainder(realvec y) const { return MF::vml_remainder(*this, y); } + realvec rint() const { + // return vrndn_f32(v); + return MF::vml_rint(*this); + } + realvec round() const { + // return vrnda_f32(v); + return MF::vml_round(*this); + } + realvec rsqrt() const { + realvec r = vrsqrte_f32(v); + r *= vrsqrts_f32(v, r * r); + r *= vrsqrts_f32(v, r * r); + return r; + } + boolvec_t signbit() const { return MF::vml_signbit(*this); } + realvec sin() const { return MF::vml_sin(*this); } + realvec sinh() const { return MF::vml_sinh(*this); } + realvec sqrt() const { return *this * rsqrt(); } + realvec tan() const { return MF::vml_tan(*this); } + realvec tanh() const { return MF::vml_tanh(*this); } + realvec trunc() const { + // return vrnd_f32(v); + return MF::vml_trunc(*this); + } +}; + +// boolvec definitions + +inline intvec<float, 2> boolvec<float, 2>::as_int() const { + return vreinterpret_s32_u32(v); +} + +inline intvec<float, 2> boolvec<float, 2>::convert_int() const { + return -as_int(); +} + +inline boolvec<float, 2> boolvec<float, 2>::ifthen(boolvec_t x, + boolvec_t y) const { + return vbsl_u32(v, x.v, y.v); +} + +inline intvec<float, 2> boolvec<float, 2>::ifthen(intvec_t x, + intvec_t y) const { + return vbsl_s32(v, x.v, y.v); +} + +inline realvec<float, 2> boolvec<float, 2>::ifthen(realvec_t x, + realvec_t y) const { + return vbsl_f32(v, x.v, y.v); +} + +// intvec definitions + +inline realvec<float, 2> intvec<float, 2>::as_float() const { + return vreinterpret_f32_s32(v); +} + +inline realvec<float, 2> intvec<float, 2>::convert_float() const { + return vcvt_f32_s32(v); +} + +inline intvec<float, 2> intvec<float, 2>::rotate(int_t n) const { + return MF::vml_rotate(*this, n); +} + +inline intvec<float, 2> intvec<float, 2>::rotate(intvec_t n) const { + return MF::vml_rotate(*this, n); +} + } // namespace vecmathlib -#endif // #ifndef VEC_NEON_FLOAT2_H +#endif // #ifndef VEC_NEON_FLOAT2_H |