diff --git a/simgear/math/simd.hxx b/simgear/math/simd.hxx index 6adf62de..a32a85ea 100644 --- a/simgear/math/simd.hxx +++ b/simgear/math/simd.hxx @@ -30,6 +30,7 @@ # include #elif defined(__GNUC__) && defined(__ARM_NEON__) # include +# include #endif #include @@ -65,7 +66,8 @@ inline simd4_t abs(simd4_t v) { } template -inline T magnitude2(simd4_t v) { +inline T magnitude2(const simd4_t& vi) { + simd4_t v(vi); T mag2 = 0; v = v*v; for (int i=0; i& v) { } template -inline T dot(simd4_t v1, const simd4_t& v2) { - T dp = 0; - v1 *= v2; +inline T dot(const simd4_t& v1, const simd4_t& v2) { + simd4_t v(v1*v2); + T dp = T(0); for (int i=0; i - inline simd4_t& operator=(simd4_t v) { - for (int i=0; i& operator=(const simd4_t& v) { + *this = simd4_t(v); return *this; } @@ -192,7 +193,7 @@ public: } inline simd4_t& operator+=(const simd4_t& v) { for (int i=0; i& operator-=(const simd4_t& v) { for (int i=0; i& operator*=(const simd4_t& v) { for (int i=0; i& operator/=(T s) { - return operator*=(1/s); + for (int i=0; i& operator/=(const T v[N]) { for (int i=0; i& operator/=(const simd4_t& v) { for (int i=0; i inline simd4_t operator-(const simd4_t& v) { - simd4_t r = T(0); + simd4_t r(T(0)); r -= v; return r; } @@ -300,16 +304,16 @@ namespace simd4 { static const uint32_t m2a32[] alignas(16) = { 0xffffffff,0xffffffff,0,0 -}; + }; static const uint32_t m3a32[] alignas(16) = { 0xffffffff,0xffffffff,0xffffffff,0 -}; + }; static const uint64_t m2a64[] alignas(32) = { 0xffffffffffffffff,0xffffffffffffffff,0,0 -}; + }; static const uint64_t m3a64[] alignas(32) = { 0xffffffffffffffff,0xffffffffffffffff,0xffffffffffffffff,0 -}; + }; }; /* namespace simd4 */ @@ -329,9 +333,7 @@ public: simd4_t(float f) {} simd4_t(float x, float y) : simd4_t(x,y,0,0) {} simd4_t(float x, float y, float z) : simd4_t(x,y,z,0) {} - simd4_t(float x, float y, float z, float w) { - simd4 = _mm_set_ps(w,z,y,x); - } + simd4_t(float x, float y, float z, float w) {} simd4_t(const __vec4f_t v) {} simd4_t(const simd4_t& v) {} simd4_t(const simd4_t& v) {} @@ -414,6 +416,19 @@ public: static const __m128 fmask2 = _mm_load_ps((const float*)simd4::m2a32); static const __m128 fmask3 = _mm_load_ps((const float*)simd4::m3a32); +template<> +inline simd4_t::simd4_t(float x, float y, float z, float w) { + simd4 = _mm_set_ps(w,z,y,x); +} +template<> +inline simd4_t::simd4_t(float x, float y, float z, float w) { + simd4 = _mm_and_ps(_mm_set_ps(w,z,y,x), fmask3); +} +template<> +inline simd4_t::simd4_t(float x, float y, float z, float w) { + simd4 = _mm_and_ps(_mm_set_ps(w,z,y,x), fmask2); +} + template<> inline simd4_t::simd4_t(const simd4_t& v) { simd4 = v.v4(); @@ -499,13 +514,13 @@ namespace simd4 # endif template<> -inline float magnitude2(simd4_t v) { - return hsum_ps_sse(v.v4()*v.v4()); +inline float magnitude2(const simd4_t& v) { + return hsum_ps_sse(_mm_mul_ps(v.v4(),v.v4())); } template<> -inline float dot(simd4_t v1, const simd4_t& v2) { - return hsum_ps_sse(v1.v4()*v2.v4()); +inline float dot(const simd4_t& v1, const simd4_t& v2) { + return hsum_ps_sse(_mm_mul_ps(v1.v4(),v2.v4())); } template<> @@ -560,9 +575,7 @@ public: simd4_t(double d) {} simd4_t(double x, double y) : simd4_t(x,y,0,0) {} simd4_t(double x, double y, double z) : simd4_t(x,y,z,0) {} - simd4_t(double x, double y, double z, double w) { - simd4 = _mm256_set_pd(w,z,y,x); - } + simd4_t(double x, double y, double z, double w) {} simd4_t(const __vec4d_t v) {} simd4_t(const simd4_t& v) {} simd4_t(const simd4_t& v) {} @@ -645,6 +658,19 @@ public: static const __m256d dmask2 = _mm256_load_pd((const double*)simd4::m2a64); static const __m256d dmask3 = _mm256_load_pd((const double*)simd4::m3a64); +template<> +inline simd4_t::simd4_t(double x, double y, double z, double w) { + simd4 = _mm256_set_pd(w,z,y,x); +} +template<> +inline simd4_t::simd4_t(double x, double y, double z, double w) { + simd4 = _mm256_and_pd(_mm256_set_pd(w,z,y,x), dmask3); +} +template<> +inline simd4_t::simd4_t(double x, double y, double z, double w) { + simd4 = _mm256_and_pd(_mm256_set_pd(w,z,y,x), dmask2); +} + template<> inline simd4_t::simd4_t(const simd4_t& v) { simd4 = v.v4(); @@ -720,12 +746,12 @@ inline static double hsum_pd_avx(__m256d v) { } template<> -inline double magnitude2(simd4_t v) { +inline double magnitude2(const simd4_t& v) { return hsum_pd_avx(_mm256_mul_pd(v.v4(),v.v4())); } template<> -inline double dot(simd4_t v1, const simd4_t& v2) { +inline double dot(const simd4_t& v1, const simd4_t& v2) { return hsum_pd_avx(_mm256_mul_pd(v1.v4(),v2.v4())); } @@ -784,10 +810,7 @@ public: simd4_t(double d) {} simd4_t(double x, double y) : simd4_t(x,y,0,0) {} simd4_t(double x, double y, double z) : simd4_t(x,y,z,0) {} - simd4_t(double x, double y, double z, double w) { - simd4[0] = _mm_set_pd(y,x); - simd4[1] = _mm_set_pd(w,z); - } + simd4_t(double x, double y, double z, double w) {} simd4_t(const __vec4d_t v) {} simd4_t(const simd4_t& v) {} simd4_t(const simd4_t& v) {} @@ -883,6 +906,22 @@ public: static const __m128d dmask3 = _mm_load_pd((const double*)(simd4::m3a64+2)); +template<> +inline simd4_t::simd4_t(double x, double y, double z, double w) { + simd4[0] = _mm_set_pd(y,x); + simd4[1] = _mm_set_pd(w,z); +} +template<> +inline simd4_t::simd4_t(double x, double y, double z, double w) { + simd4[0] = _mm_set_pd(y,x); + simd4[1] = _mm_and_pd(_mm_set_pd(w,z), dmask3); +} +template<> +inline simd4_t::simd4_t(double x, double y, double z, double w) { + simd4[0] = _mm_set_pd(y,x); + simd4[1] = _mm_setzero_pd(); +} + template<> inline simd4_t::simd4_t(const simd4_t& v) { simd4[0] = v.v4()[0]; @@ -973,15 +1012,19 @@ inline static double hsum_pd_sse(const __m128d vd[2]) { } template<> -inline double magnitude2(simd4_t v) { - v *= v; - return hsum_pd_sse(v.v4()); +inline double magnitude2(const simd4_t& v) { + __m128d v2[2]; + v2[0] = _mm_mul_pd(v.v4()[0],v.v4()[0]); + v2[1] = _mm_mul_pd(v.v4()[1],v.v4()[1]); + return hsum_pd_sse(v2); } template<> -inline double dot(simd4_t v1, const simd4_t& v2) { - v1 *= v2; - return hsum_pd_sse(v1.v4()); +inline double dot(const simd4_t& v1, const simd4_t& v2) { + __m128d mv[2]; + mv[0] = _mm_mul_pd(v1.v4()[0],v2.v4()[0]); + mv[1] = _mm_mul_pd(v1.v4()[1],v2.v4()[1]); + return hsum_pd_sse(mv); } template<> @@ -1050,9 +1093,7 @@ public: simd4_t(int i) {} simd4_t(int x, int y) : simd4_t(x,y,0,0) {} simd4_t(int x, int y, int z) : simd4_t(x,y,z,0) {} - simd4_t(int x, int y, int z, int w) { - simd4 = _mm_set_epi32(w,z,y,x); - } + simd4_t(int x, int y, int z, int w) {} simd4_t(const __vec4i_t v) {} simd4_t(const simd4_t& v) {} simd4_t(const simd4_t& v) {} @@ -1149,6 +1190,19 @@ public: static const __m128i imask2 = _mm_load_si128((__m128i*)simd4::m2a32); static const __m128i imask3 = _mm_load_si128((__m128i*)simd4::m3a32); +template<> +inline simd4_t::simd4_t(int x, int y, int z, int w) { + simd4 = _mm_set_epi32(w,z,y,x); +} +template<> +inline simd4_t::simd4_t(int x, int y, int z, int w) { + simd4 = _mm_and_si128(_mm_set_epi32(w,z,y,x), imask3); +} +template<> +inline simd4_t::simd4_t(int x, int y, int z, int w) { + simd4 = _mm_and_si128(_mm_set_epi32(w,z,y,x), imask2); +} + template<> inline simd4_t::simd4_t(const simd4_t& v) { simd4 = v.v4(); @@ -1233,9 +1287,5 @@ inline simd4_t max(simd4_t v1, const simd4_t& v2) { # endif -# ifdef __ARM_NEON__ -# include -# endif - #endif /* __SIMD_H__ */ diff --git a/simgear/math/simd4x4.hxx b/simgear/math/simd4x4.hxx index a6414d12..b880bb97 100644 --- a/simgear/math/simd4x4.hxx +++ b/simgear/math/simd4x4.hxx @@ -20,6 +20,10 @@ #include +#if defined(__GNUC__) && defined(__ARM_NEON__) +# include +#endif + #include template class simd4x4_t; @@ -1174,10 +1178,5 @@ inline simd4_t transform(const simd4x4_t& m, const simd4_t -# endif - - #endif /* __SIMD4X4_H__ */