diff --git a/simgear/math/simd.hxx b/simgear/math/simd.hxx index 81782efa..3074e342 100644 --- a/simgear/math/simd.hxx +++ b/simgear/math/simd.hxx @@ -504,10 +504,10 @@ inline simd4_tabs(simd4_t v) { # endif -# ifdef __AVX_unsupported__ +# ifdef __AVX__ # include # include -//# include +// # include "avxintrin-emu.h" template class simd4_t @@ -634,36 +634,29 @@ inline float hsum_pd_avx(__m256d v) { template<> inline double magnitude2(simd4_t v) { - return hsum_pd_avx(v.v4()*v.v4()); + return hsum_pd_avx(_mm256_mul_pd(v.v4(),v.v4())); } template<> inline double dot(simd4_t v1, const simd4_t& v2) { - return hsum_pd_avx(v1.v4()*v2.v4()); + return hsum_pd_avx(_mm256_mul_pd(v1.v4(),v2.v4())); } +#ifdef __AVX2__ template<> inline simd4_t cross(const simd4_t& v1, const simd4_t& v2) { -#if 1 - // http://threadlocalmutex.com/?p=8 + // https://gist.github.com/L2Program/219e07581e69110e7942 __m256d v41 = v1.v4(), v42 = v2.v4(); - __m256d a = _mm256_shuffle_pd(v41, v41, _MM_SHUFFLE(3, 0, 2, 1)); - __m256d b = _mm256_shuffle_pd(v42, v42, _MM_SHUFFLE(3, 0, 2, 1)); - __m256d c = _mm256_sub_pd(_mm256_mul_pd(v41, b), _mm256_mul_pd(a, v42)); - return _mm256_shuffle_pd(c, c, _MM_SHUFFLE(3, 0, 2, 1)); -#else - v1 = _mm256_sub_pd( - _mm256_mul_pd( - _mm256_shuffle_pd(v1.v4(),v1.v4(),_MM_SHUFFLE(3, 0, 2, 1)), - _mm256_shuffle_pd(v2.v4(),v2.v4(),_MM_SHUFFLE(3, 1, 0, 2))), - _mm256_mul_pd( - _mm256_shuffle_pd(v1.v4(),v1.v4(),_MM_SHUFFLE(3, 1, 0, 2)), - _mm256_shuffle_pd(v2.v4(),v2.v4(),_MM_SHUFFLE(3, 0, 2, 1))) - ); - return v1; -#endif + return _mm256_sub_pd( + _mm256_mul_pd( + _mm256_permute4x64_pd(v41,_MM_SHUFFLE(3, 0, 2, 1)), + _mm256_permute4x64_pd(v42,_MM_SHUFFLE(3, 1, 0, 2))), + _mm256_mul_pd( + _mm256_permute4x64_pd(v41,_MM_SHUFFLE(3, 1, 0, 2)), + _mm256_permute4x64_pd(v42,_MM_SHUFFLE(3, 0, 2, 1)))); } +#endif template inline simd4_t min(simd4_t v1, const simd4_t& v2) { diff --git a/simgear/math/simd4x4.hxx b/simgear/math/simd4x4.hxx index a199d5bb..bbf6908b 100644 --- a/simgear/math/simd4x4.hxx +++ b/simgear/math/simd4x4.hxx @@ -514,10 +514,10 @@ inline simd4_t transform(const simd4x4_t& m, const simd # endif -# ifdef __AVX_unsupported__ +# ifdef __AVX__ # include # include -//# include +// # include "avxintrin-emu.h" template<> class simd4x4_t @@ -690,25 +690,18 @@ inline simd4x4_t rotation_matrix(double angle, const simd4_t inline simd4x4_t transpose(simd4x4_t m) { - simd4x4_t mtx; -#if 1 - for (int i=0; i<4; ++i) { - for(int j=0; j<4; ++j) { - mtx.ptr()[j][i] = m.ptr()[i][j]; - } - } -#else - __m256d T0 = _mm256_unpacklo_pd(m.m4x4()[0], m.m4x4()[1]); - __m256d T1 = _mm256_unpacklo_pd(m.m4x4()[2], m.m4x4()[3]); - __m256d T2 = _mm256_unpackhi_pd(m.m4x4()[0], m.m4x4()[1]); - __m256d T3 = _mm256_unpackhi_pd(m.m4x4()[2], m.m4x4()[3]); +// http://stackoverflow.com/questions/36167517/m256d-transpose4-equivalent + __m256d tmp0 = _mm256_shuffle_pd(m.m4x4()[0], m.m4x4()[1], 0x0); + __m256d tmp2 = _mm256_shuffle_pd(m.m4x4()[0], m.m4x4()[1], 0xF); + __m256d tmp1 = _mm256_shuffle_pd(m.m4x4()[2], m.m4x4()[3], 0x0); + __m256d tmp3 = _mm256_shuffle_pd(m.m4x4()[2], m.m4x4()[3], 0xF); - mtx.m4x4()[0] = _mm256_unpacklo_pd(T0, T1); - mtx.m4x4()[1] = _mm256_unpackhi_pd(T0, T1); - mtx.m4x4()[2] = _mm256_unpacklo_pd(T2, T3); - mtx.m4x4()[3] = _mm256_unpackhi_pd(T2, T3); -#endif - return mtx; + m.m4x4()[0] = _mm256_permute2f128_pd(tmp0, tmp1, 0x20); + m.m4x4()[1] = _mm256_permute2f128_pd(tmp2, tmp3, 0x20); + m.m4x4()[2] = _mm256_permute2f128_pd(tmp0, tmp1, 0x31); + m.m4x4()[3] = _mm256_permute2f128_pd(tmp2, tmp3, 0x31); + + return m; } inline void translate(simd4x4_t& m, const simd4_t& dist) {