|
30 | 30 | namespace Ray { |
31 | 31 | namespace NS { |
32 | 32 |
|
33 | | -template <> force_inline __m256 _mm_cast(__m256i x) { return _mm256_castsi256_ps(x); } |
34 | | -template <> force_inline __m256i _mm_cast(__m256 x) { return _mm256_castps_si256(x); } |
| 33 | +template <> force_inline __m256 _mm_cast(const __m256i x) { return _mm256_castsi256_ps(x); } |
| 34 | +template <> force_inline __m256i _mm_cast(const __m256 x) { return _mm256_castps_si256(x); } |
35 | 35 |
|
36 | 36 | template <> class fixed_size_simd<int, 8>; |
37 | 37 | template <> class fixed_size_simd<unsigned, 8>; |
@@ -417,14 +417,22 @@ template <> class fixed_size_simd<int, 8> { |
417 | 417 |
|
418 | 418 | force_inline void vectorcall blend_to(const fixed_size_simd<int, 8> mask, const fixed_size_simd<int, 8> v1) { |
419 | 419 | validate_mask(mask); |
| 420 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 421 | + vec_ = _mm256_blendv_epi8(vec_, v1.vec_, mask.vec_); |
| 422 | +#else |
420 | 423 | vec_ = _mm256_castps_si256( |
421 | 424 | _mm256_blendv_ps(_mm256_castsi256_ps(vec_), _mm256_castsi256_ps(v1.vec_), _mm256_castsi256_ps(mask.vec_))); |
| 425 | +#endif |
422 | 426 | } |
423 | 427 |
|
424 | 428 | force_inline void vectorcall blend_inv_to(const fixed_size_simd<int, 8> mask, const fixed_size_simd<int, 8> v1) { |
425 | 429 | validate_mask(mask); |
| 430 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 431 | + vec_ = _mm256_blendv_epi8(v1.vec_, vec_, mask.vec_); |
| 432 | +#else |
426 | 433 | vec_ = _mm256_castps_si256( |
427 | 434 | _mm256_blendv_ps(_mm256_castsi256_ps(v1.vec_), _mm256_castsi256_ps(vec_), _mm256_castsi256_ps(mask.vec_))); |
| 435 | +#endif |
428 | 436 | } |
429 | 437 |
|
430 | 438 | force_inline int movemask() const { return _mm256_movemask_ps(_mm256_castsi256_ps(vec_)); } |
@@ -469,22 +477,38 @@ template <> class fixed_size_simd<int, 8> { |
469 | 477 |
|
470 | 478 | force_inline static fixed_size_simd<int, 8> vectorcall and_not(const fixed_size_simd<int, 8> v1, |
471 | 479 | const fixed_size_simd<int, 8> v2) { |
| 480 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 481 | + return _mm256_andnot_si256(v1.vec_, v2.vec_); |
| 482 | +#else |
472 | 483 | return _mm256_castps_si256(_mm256_andnot_ps(_mm256_castsi256_ps(v1.vec_), _mm256_castsi256_ps(v2.vec_))); |
| 484 | +#endif |
473 | 485 | } |
474 | 486 |
|
475 | 487 | friend force_inline fixed_size_simd<int, 8> vectorcall operator&(const fixed_size_simd<int, 8> v1, |
476 | 488 | const fixed_size_simd<int, 8> v2) { |
| 489 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 490 | + return _mm256_and_si256(v1.vec_, v2.vec_); |
| 491 | +#else |
477 | 492 | return _mm256_castps_si256(_mm256_and_ps(_mm256_castsi256_ps(v1.vec_), _mm256_castsi256_ps(v2.vec_))); |
| 493 | +#endif |
478 | 494 | } |
479 | 495 |
|
480 | 496 | friend force_inline fixed_size_simd<int, 8> vectorcall operator|(const fixed_size_simd<int, 8> v1, |
481 | 497 | const fixed_size_simd<int, 8> v2) { |
| 498 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 499 | + return _mm256_or_si256(v1.vec_, v2.vec_); |
| 500 | +#else |
482 | 501 | return _mm256_castps_si256(_mm256_or_ps(_mm256_castsi256_ps(v1.vec_), _mm256_castsi256_ps(v2.vec_))); |
| 502 | +#endif |
483 | 503 | } |
484 | 504 |
|
485 | 505 | friend force_inline fixed_size_simd<int, 8> vectorcall operator^(const fixed_size_simd<int, 8> v1, |
486 | 506 | const fixed_size_simd<int, 8> v2) { |
| 507 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 508 | + return _mm256_xor_si256(v1.vec_, v2.vec_); |
| 509 | +#else |
487 | 510 | return _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(v1.vec_), _mm256_castsi256_ps(v2.vec_))); |
| 511 | +#endif |
488 | 512 | } |
489 | 513 |
|
490 | 514 | friend avx2_inline fixed_size_simd<int, 8> vectorcall operator+(const fixed_size_simd<int, 8> v1, |
@@ -760,8 +784,12 @@ template <> class fixed_size_simd<unsigned, 8> { |
760 | 784 | return operator-=(fixed_size_simd<unsigned, 8>{rhs}); |
761 | 785 | } |
762 | 786 |
|
763 | | - fixed_size_simd<unsigned, 8> &vectorcall operator*=(const fixed_size_simd<unsigned, 8> rhs) { |
| 787 | + avx2_inline fixed_size_simd<unsigned, 8> &vectorcall operator*=(const fixed_size_simd<unsigned, 8> rhs) { |
| 788 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 789 | + vec_ = _mm256_mullo_epi32(vec_, rhs.vec_); |
| 790 | +#else |
764 | 791 | UNROLLED_FOR(i, 8, { comp_[i] *= rhs.comp_[i]; }) |
| 792 | +#endif |
765 | 793 | return *this; |
766 | 794 | } |
767 | 795 |
|
@@ -855,15 +883,23 @@ template <> class fixed_size_simd<unsigned, 8> { |
855 | 883 | force_inline void vectorcall blend_to(const fixed_size_simd<unsigned, 8> mask, |
856 | 884 | const fixed_size_simd<unsigned, 8> v1) { |
857 | 885 | validate_mask(mask); |
| 886 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 887 | + vec_ = _mm256_blendv_epi8(vec_, v1.vec_, mask.vec_); |
| 888 | +#else |
858 | 889 | vec_ = _mm256_castps_si256( |
859 | 890 | _mm256_blendv_ps(_mm256_castsi256_ps(vec_), _mm256_castsi256_ps(v1.vec_), _mm256_castsi256_ps(mask.vec_))); |
| 891 | +#endif |
860 | 892 | } |
861 | 893 |
|
862 | 894 | force_inline void vectorcall blend_inv_to(const fixed_size_simd<unsigned, 8> mask, |
863 | 895 | const fixed_size_simd<unsigned, 8> v1) { |
864 | 896 | validate_mask(mask); |
| 897 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 898 | + vec_ = _mm256_blendv_epi8(v1.vec_, vec_, mask.vec_); |
| 899 | +#else |
865 | 900 | vec_ = _mm256_castps_si256( |
866 | 901 | _mm256_blendv_ps(_mm256_castsi256_ps(v1.vec_), _mm256_castsi256_ps(vec_), _mm256_castsi256_ps(mask.vec_))); |
| 902 | +#endif |
867 | 903 | } |
868 | 904 |
|
869 | 905 | force_inline int movemask() const { return _mm256_movemask_ps(_mm256_castsi256_ps(vec_)); } |
@@ -908,22 +944,38 @@ template <> class fixed_size_simd<unsigned, 8> { |
908 | 944 |
|
909 | 945 | force_inline static fixed_size_simd<unsigned, 8> vectorcall and_not(const fixed_size_simd<unsigned, 8> v1, |
910 | 946 | const fixed_size_simd<unsigned, 8> v2) { |
| 947 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 948 | + return _mm256_andnot_si256(v1.vec_, v2.vec_); |
| 949 | +#else |
911 | 950 | return _mm256_castps_si256(_mm256_andnot_ps(_mm256_castsi256_ps(v1.vec_), _mm256_castsi256_ps(v2.vec_))); |
| 951 | +#endif |
912 | 952 | } |
913 | 953 |
|
914 | 954 | friend force_inline fixed_size_simd<unsigned, 8> vectorcall operator&(const fixed_size_simd<unsigned, 8> v1, |
915 | 955 | const fixed_size_simd<unsigned, 8> v2) { |
| 956 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 957 | + return _mm256_and_si256(v1.vec_, v2.vec_); |
| 958 | +#else |
916 | 959 | return _mm256_castps_si256(_mm256_and_ps(_mm256_castsi256_ps(v1.vec_), _mm256_castsi256_ps(v2.vec_))); |
| 960 | +#endif |
917 | 961 | } |
918 | 962 |
|
919 | 963 | friend force_inline fixed_size_simd<unsigned, 8> vectorcall operator|(const fixed_size_simd<unsigned, 8> v1, |
920 | 964 | const fixed_size_simd<unsigned, 8> v2) { |
| 965 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 966 | + return _mm256_or_si256(v1.vec_, v2.vec_); |
| 967 | +#else |
921 | 968 | return _mm256_castps_si256(_mm256_or_ps(_mm256_castsi256_ps(v1.vec_), _mm256_castsi256_ps(v2.vec_))); |
| 969 | +#endif |
922 | 970 | } |
923 | 971 |
|
924 | 972 | friend force_inline fixed_size_simd<unsigned, 8> vectorcall operator^(const fixed_size_simd<unsigned, 8> v1, |
925 | 973 | const fixed_size_simd<unsigned, 8> v2) { |
| 974 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 975 | + return _mm256_xor_si256(v1.vec_, v2.vec_); |
| 976 | +#else |
926 | 977 | return _mm256_castps_si256(_mm256_xor_ps(_mm256_castsi256_ps(v1.vec_), _mm256_castsi256_ps(v2.vec_))); |
| 978 | +#endif |
927 | 979 | } |
928 | 980 |
|
929 | 981 | friend avx2_inline fixed_size_simd<unsigned, 8> vectorcall operator+(const fixed_size_simd<unsigned, 8> v1, |
@@ -1328,17 +1380,25 @@ force_inline fixed_size_simd<int, 8> vectorcall select(const fixed_size_simd<U, |
1328 | 1380 | const fixed_size_simd<int, 8> vec1, |
1329 | 1381 | const fixed_size_simd<int, 8> vec2) { |
1330 | 1382 | validate_mask(mask); |
| 1383 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 1384 | + return _mm256_blendv_epi8(vec2.vec_, vec1.vec_, mask.vec_); |
| 1385 | +#else |
1331 | 1386 | return _mm256_castps_si256( |
1332 | 1387 | _mm256_blendv_ps(_mm256_castsi256_ps(vec2.vec_), _mm256_castsi256_ps(vec1.vec_), _mm_cast<__m256>(mask.vec_))); |
| 1388 | +#endif |
1333 | 1389 | } |
1334 | 1390 |
|
1335 | 1391 | template <typename U> |
1336 | 1392 | force_inline fixed_size_simd<unsigned, 8> vectorcall select(const fixed_size_simd<U, 8> mask, |
1337 | 1393 | const fixed_size_simd<unsigned, 8> vec1, |
1338 | 1394 | const fixed_size_simd<unsigned, 8> vec2) { |
1339 | 1395 | validate_mask(mask); |
| 1396 | +#if defined(USE_AVX2) || defined(USE_AVX512) |
| 1397 | + return _mm256_blendv_epi8(vec2.vec_, vec1.vec_, mask.vec_); |
| 1398 | +#else |
1340 | 1399 | return _mm256_castps_si256( |
1341 | 1400 | _mm256_blendv_ps(_mm256_castsi256_ps(vec2.vec_), _mm256_castsi256_ps(vec1.vec_), _mm_cast<__m256>(mask.vec_))); |
| 1401 | +#endif |
1342 | 1402 | } |
1343 | 1403 |
|
1344 | 1404 | } // namespace NS |
|
0 commit comments