diff options
Diffstat (limited to 'vec_avx_float8.h')
-rw-r--r-- | vec_avx_float8.h | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/vec_avx_float8.h b/vec_avx_float8.h index bba77cb..2b1e386 100644 --- a/vec_avx_float8.h +++ b/vec_avx_float8.h @@ -182,13 +182,17 @@ namespace vecmathlib { boolvec_t convert_bool() const { // Result: convert_bool(0)=false, convert_bool(else)=true - // There is no intrinsic to compare with zero. Instead, we check +#ifdef __AVX2__ + return _mm256_castsi256_ps(_mm256_cmpeq_epi32(v, _mm256_setzero_si256())); +#else + // There is no intrinsic to compare to zero. Instead, we check // whether x is positive and x-1 is negative. intvec_t x = *this; // We know that boolvec_t values depend only on the sign bit // return (~(x-1) | x).as_bool(); // return x.as_bool() || !(x-1).as_bool(); return x.as_bool() || (x + (FP::signbit_mask - 1)).as_bool(); +#endif } realvec_t as_float() const; // defined after realvec realvec_t convert_float() const; // defined after realvec @@ -202,6 +206,9 @@ namespace vecmathlib { intvec_t operator+(intvec_t x) const { +#ifdef __AVX2__ + return _mm256_add_epi32(v, x.v); +#else __m128i vlo = _mm256_castsi256_si128(v); __m128i vhi = _mm256_extractf128_si256(v, 1); __m128i xvlo = _mm256_castsi256_si128(x.v); @@ -209,9 +216,13 @@ namespace vecmathlib { vlo = _mm_add_epi32(vlo, xvlo); vhi = _mm_add_epi32(vhi, xvhi); return _mm256_insertf128_si256(_mm256_castsi128_si256(vlo), vhi, 1); +#endif } intvec_t operator-(intvec_t x) const { +#ifdef __AVX2__ + return _mm256_sub_epi32(v, x.v); +#else __m128i vlo = _mm256_castsi256_si128(v); __m128i vhi = _mm256_extractf128_si256(v, 1); __m128i xvlo = _mm256_castsi256_si128(x.v); @@ -219,6 +230,7 @@ namespace vecmathlib { vlo = _mm_sub_epi32(vlo, xvlo); vhi = _mm_sub_epi32(vhi, xvhi); return _mm256_insertf128_si256(_mm256_castsi128_si256(vlo), vhi, 1); +#endif } intvec_t& operator+=(intvec_t const& x) { return *this=*this+x; } @@ -230,18 +242,30 @@ namespace vecmathlib { intvec_t operator&(intvec_t x) const { +#ifdef __AVX2__ + return _mm256_and_si256(v, x.v); +#else return _mm256_castps_si256(_mm256_and_ps(_mm256_castsi256_ps(v), _mm256_castsi256_ps(x.v))); +#endif } intvec_t operator|(intvec_t x) const { +#ifdef __AVX2__ + return _mm256_or_si256(v, x.v); +#else return _mm256_castps_si256(_mm256_or_ps(_mm256_castsi256_ps(v), _mm256_castsi256_ps(x.v))); +#endif } intvec_t operator^(intvec_t x) const { +#ifdef __AVX2__ + return _mm256_xor_si256(v, x.v); +#else return _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(v), _mm256_castsi256_ps(x.v))); +#endif } intvec_t& operator&=(intvec_t const& x) { return *this=*this&x; } @@ -254,56 +278,80 @@ namespace vecmathlib { intvec_t lsr(int_t n) const { +#ifdef __AVX2__ + return _mm256_srli_epi32(v, n); +#else __m128i vlo = _mm256_castsi256_si128(v); __m128i vhi = _mm256_extractf128_si256(v, 1); vlo = _mm_srli_epi32(vlo, n); vhi = _mm_srli_epi32(vhi, n); return _mm256_insertf128_si256(_mm256_castsi128_si256(vlo), vhi, 1); +#endif } intvec_t rotate(int_t n) const; intvec_t operator>>(int_t n) const { +#ifdef __AVX2__ + return _mm256_srai_epi32(v, n); +#else __m128i vlo = _mm256_castsi256_si128(v); __m128i vhi = _mm256_extractf128_si256(v, 1); vlo = _mm_srai_epi32(vlo, n); vhi = _mm_srai_epi32(vhi, n); return _mm256_insertf128_si256(_mm256_castsi128_si256(vlo), vhi, 1); +#endif } intvec_t operator<<(int_t n) const { +#ifdef __AVX2__ + return _mm256_slli_epi32(v, n); +#else __m128i vlo = _mm256_castsi256_si128(v); __m128i vhi = _mm256_extractf128_si256(v, 1); vlo = _mm_slli_epi32(vlo, n); vhi = _mm_slli_epi32(vhi, n); return _mm256_insertf128_si256(_mm256_castsi128_si256(vlo), vhi, 1); +#endif } 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 { +#ifdef __AVX2__ + return _mm256_srlv_epi32(v, n.v); +#else intvec_t r; for (int i=0; i<size; ++i) { r.set_elt(i, U((*this)[i]) >> U(n[i])); } return r; +#endif } intvec_t rotate(intvec_t n) const; intvec_t operator>>(intvec_t n) const { +#ifdef __AVX2__ + return _mm256_srav_epi32(v, n.v); +#else intvec_t r; for (int i=0; i<size; ++i) { r.set_elt(i, (*this)[i] >> n[i]); } return r; +#endif } intvec_t operator<<(intvec_t n) const { +#ifdef __AVX2__ + return _mm256_sllv_epi32(v, n.v); +#else intvec_t r; for (int i=0; i<size; ++i) { r.set_elt(i, (*this)[i] << n[i]); } return r; +#endif } intvec_t& operator>>=(intvec_t n) { return *this=*this>>n; } intvec_t& operator<<=(intvec_t n) { return *this=*this<<n; } @@ -315,20 +363,32 @@ namespace vecmathlib { boolvec_t operator==(intvec_t const& x) const { +#ifdef __AVX2__ + return _mm256_castsi256_ps(_mm256_cmpeq_epi32(v, x.v)); +#else return ! (*this != x); +#endif } boolvec_t operator!=(intvec_t const& x) const { +#ifdef __AVX2__ + return ! (*this == x); +#else return (*this ^ x).convert_bool(); +#endif } boolvec_t operator<(intvec_t const& x) const { +#ifdef __AVX2__ + return _mm256_castsi256_ps(_mm256_cmpgt_epi32(x.v, v)); +#else // return (*this - x).as_bool(); boolvec_t r; for (int i=0; i<size; ++i) { r.set_elt(i, (*this)[i] < x[i]); } return r; +#endif } boolvec_t operator<=(intvec_t const& x) const { @@ -359,7 +419,13 @@ namespace vecmathlib { typedef __m256 vector_t; static int const alignment = sizeof(vector_t); - static char const* name() { return "<AVX:8*float>"; } + static char const* name() { +#ifdef __AVX2__ + return "<AVX2:8*float>"; +#else + return "<AVX:8*float>"; +#endif + } void barrier() { __asm__("": "+x"(v)); } static_assert(size * sizeof(real_t) == sizeof(vector_t), @@ -715,7 +781,11 @@ namespace vecmathlib { inline intvec<float,8> intvec<float,8>::abs() const { +#ifdef __AVX2__ + return _mm256_abs_epi32(v); +#else return MF::vml_abs(*this); +#endif } inline realvec<float,8> intvec<float,8>::as_float() const |