diff --git a/include/eve/arch/ppc/spec.hpp b/include/eve/arch/ppc/spec.hpp index 578a7fa3a9..a8b8798af0 100644 --- a/include/eve/arch/ppc/spec.hpp +++ b/include/eve/arch/ppc/spec.hpp @@ -53,12 +53,32 @@ namespace eve # if !defined(EVE_ABI_DETECTED) && defined(SPY_SIMD_IS_PPC_VMX) # define EVE_CURRENT_ABI ::eve::ppc_ -# define EVE_CURRENT_API ::eve::vmx_ +# if defined(SPY_SIMD_IS_PPC_VMX_3_01) +# define EVE_CURRENT_API ::eve::vmx_3_01_ +# elif defined(SPY_SIMD_IS_PPC_VMX_3_00) +# define EVE_CURRENT_API ::eve::vmx_3_00_ +# elif defined(SPY_SIMD_IS_PPC_VMX_2_07) +# define EVE_CURRENT_API ::eve::vmx_2_07_ +# elif defined(SPY_SIMD_IS_PPC_VMX_2_06) +# define EVE_CURRENT_API ::eve::vmx_2_06_ +# elif defined(SPY_SIMD_IS_PPC_VMX_2_05) +# define EVE_CURRENT_API ::eve::vmx_2_05_ +# elif defined(SPY_SIMD_IS_PPC_VMX_2_03) +# define EVE_CURRENT_API ::eve::vmx_2_03_ +# endif # define EVE_ABI_NAMESPACE ppc_abi_v0 # define EVE_ABI_DETECTED # elif !defined(EVE_ABI_DETECTED) && defined(SPY_SIMD_IS_PPC_VSX) # define EVE_CURRENT_ABI ::eve::ppc_ -# define EVE_CURRENT_API ::eve::vsx_ +# if defined(SPY_SIMD_IS_PPC_VSX_3_01) +# define EVE_CURRENT_API ::eve::vsx_3_01_ +# elif defined(SPY_SIMD_IS_PPC_VSX_3_00) +# define EVE_CURRENT_API ::eve::vsx_3_00_ +# elif defined(SPY_SIMD_IS_PPC_VSX_2_07) +# define EVE_CURRENT_API ::eve::vsx_2_07_ +# elif defined(SPY_SIMD_IS_PPC_VSX_2_06) +# define EVE_CURRENT_API ::eve::vsx_2_06_ +# endif # define EVE_ABI_NAMESPACE ppc_abi_v0 # define EVE_ABI_DETECTED # endif diff --git a/include/eve/arch/ppc/tags.hpp b/include/eve/arch/ppc/tags.hpp index 11b90e97f4..f7f680244a 100644 --- a/include/eve/arch/ppc/tags.hpp +++ b/include/eve/arch/ppc/tags.hpp @@ -7,6 +7,7 @@ //================================================================================================== #pragma once +#include "eve/detail/spy.hpp" #include #include #include @@ -36,14 +37,34 @@ namespace eve //================================================================================================ // Dispatching tag for V*X SIMD implementation //================================================================================================ - struct vmx_ : simd_api { using is_ppc = void; }; - struct vsx_ : simd_api { using is_ppc = void; }; + struct vmx_ : simd_api { using is_ppc = void; }; + struct vmx_2_03_ : simd_api { using is_ppc = void; }; + struct vmx_2_05_ : simd_api { using is_ppc = void; }; + struct vmx_2_06_ : simd_api { using is_ppc = void; }; + struct vmx_2_07_ : simd_api { using is_ppc = void; }; + struct vmx_3_00_ : simd_api { using is_ppc = void; }; + struct vmx_3_01_ : simd_api { using is_ppc = void; }; + struct vsx_ : simd_api { using is_ppc = void; }; + struct vsx_2_06_ : simd_api { using is_ppc = void; }; + struct vsx_2_07_ : simd_api { using is_ppc = void; }; + struct vsx_3_00_ : simd_api { using is_ppc = void; }; + struct vsx_3_01_ : simd_api { using is_ppc = void; }; //================================================================================================ // V*X extension tag objects //================================================================================================ - inline constexpr vmx_ vmx = {}; - inline constexpr vsx_ vsx = {}; + inline constexpr vmx_ vmx = {}; + inline constexpr vmx_2_03_ vmx_2_03 = {}; + inline constexpr vmx_2_05_ vmx_2_05 = {}; + inline constexpr vmx_2_06_ vmx_2_06 = {}; + inline constexpr vmx_2_07_ vmx_2_07 = {}; + inline constexpr vmx_3_00_ vmx_3_00 = {}; + inline constexpr vmx_3_01_ vmx_3_01 = {}; + inline constexpr vsx_ vsx = {}; + inline constexpr vsx_2_06_ vsx_2_06 = {}; + inline constexpr vsx_2_07_ vsx_2_07 = {}; + inline constexpr vsx_3_00_ vsx_3_00 = {}; + inline constexpr vsx_3_01_ vsx_3_01 = {}; // clang-format on //================================================================================================ diff --git a/include/eve/detail/spy.hpp b/include/eve/detail/spy.hpp index 62a8b2fb75..7b7b8d6d3a 100644 --- a/include/eve/detail/spy.hpp +++ b/include/eve/detail/spy.hpp @@ -823,28 +823,38 @@ namespace avx512 #if !defined(SPY_SIMD_DETECTED) && defined(__VSX__) # define SPY_SIMD_IS_PPC_VSX # if defined(_ARCH_PWR10) +# define SPY_SIMD_IS_PPC_VSX_3_01 # define SPY_SIMD_DETECTED ::spy::detail::simd_version::vsx_3_01_ # elif defined(_ARCH_PWR9) +# define SPY_SIMD_IS_PPC_VSX_3_00 # define SPY_SIMD_DETECTED ::spy::detail::simd_version::vsx_3_00_ # elif defined(_ARCH_PWR8) +# define SPY_SIMD_IS_PPC_VSX_2_07 # define SPY_SIMD_DETECTED ::spy::detail::simd_version::vsx_2_07_ # elif defined(_ARCH_PWR7) +# define SPY_SIMD_IS_PPC_VSX_2_06 # define SPY_SIMD_DETECTED ::spy::detail::simd_version::vsx_2_06_ # endif #endif #if !defined(SPY_SIMD_DETECTED) && (defined(__ALTIVEC__) || defined(__VEC__)) # define SPY_SIMD_IS_PPC_VMX # if defined(_ARCH_PWR10) +# define SPY_SIMD_IS_PPC_VMX_3_01 # define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_3_01_ # elif defined(_ARCH_PWR9) +# define SPY_SIMD_IS_PPC_VMX_3_00 # define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_3_00_ # elif defined(_ARCH_PWR8) +# define SPY_SIMD_IS_PPC_VMX_2_07 # define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_2_07_ # elif defined(_ARCH_PWR7) +# define SPY_SIMD_IS_PPC_VMX_2_06 # define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_2_06_ # elif defined(_ARCH_PWR6) +# define SPY_SIMD_IS_PPC_VMX_2_05 # define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_2_05_ # elif defined(_ARCH_PWR5) +# define SPY_SIMD_IS_PPC_VMX_2_03 # define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_2_03_ # endif # define SPY_SIMD_DETECTED ::spy::detail::simd_version::vmx_ diff --git a/include/eve/module/core/regular/impl/simd/ppc/sqrt.hpp b/include/eve/module/core/regular/impl/simd/ppc/sqrt.hpp index 661af6e5f6..2cb1a897ae 100644 --- a/include/eve/module/core/regular/impl/simd/ppc/sqrt.hpp +++ b/include/eve/module/core/regular/impl/simd/ppc/sqrt.hpp @@ -24,7 +24,8 @@ sqrt_(EVE_SUPPORTS(vmx_), wide const& v0) noexcept requires ppc_abi ) { - if constexpr( current_api == vmx ) + if constexpr( current_api >= vsx ) return vec_sqrt(v0.storage()); + else { auto that = if_else(v0, v0 * rsqrt(v0), v0); if constexpr( platform::supports_invalids ) @@ -33,7 +34,6 @@ sqrt_(EVE_SUPPORTS(vmx_), wide const& v0) noexcept requires ppc_abi { if constexpr( std::is_floating_point_v ) { - if constexpr( current_api == vmx ) { return if_else(v0, v0 * raw(rsqrt)(v0), eve::zero); } - else { return vec_sqrt(v0.storage()); } + if constexpr( current_api >= vsx ) return vec_sqrt(v0.storage()); + else return if_else(v0, v0 * raw(rsqrt)(v0), eve::zero); } } } diff --git a/include/eve/module/core/regular/impl/simd/ppc/store.hpp b/include/eve/module/core/regular/impl/simd/ppc/store.hpp index d66aec0f7e..985715ed89 100644 --- a/include/eve/module/core/regular/impl/simd/ppc/store.hpp +++ b/include/eve/module/core/regular/impl/simd/ppc/store.hpp @@ -20,16 +20,12 @@ store_(EVE_SUPPORTS(vmx_), { if constexpr( !std::is_pointer_v ) { - if constexpr( current_api == eve::vmx ) vec_st(value.storage(), 0, ptr.get()); - else store(value, ptr.get()); + if constexpr( current_api >= eve::vsx ) store(value, ptr.get()); + else vec_st(value.storage(), 0, ptr.get()); } else if constexpr( N::value * sizeof(T) == ppc_::bytes ) { - if constexpr( current_api >= eve::vmx ) - { - *((typename wide::storage_type *)(ptr)) = value; - } - else if constexpr( current_api >= eve::vsx ) + if constexpr( current_api >= eve::vsx ) { // 64bits integrals are not supported by vec_vsx_st on some compilers if constexpr( sizeof(T) == 8 && std::is_integral_v ) @@ -38,7 +34,11 @@ store_(EVE_SUPPORTS(vmx_), } else { vec_vsx_st(value.storage(), 0, ptr); } } + else + { + *((typename wide::storage_type *)(ptr)) = value; + } } - else { memcpy(ptr, (T const *)(&value), N::value * sizeof(T)); } + else memcpy(ptr, (T const *)(&value), N::value * sizeof(T)); } } diff --git a/test/unit/arch/is_supported.cpp b/test/unit/arch/is_supported.cpp index 9b0921ac68..99996b12a9 100644 --- a/test/unit/arch/is_supported.cpp +++ b/test/unit/arch/is_supported.cpp @@ -43,8 +43,18 @@ TTS_CASE("Static detections of API") std::cout << "\n"; std::cout << "========================\n"; std::cout << "PPC SIMD extensions\n"; - std::cout << "VSX : " << std::boolalpha << (eve::current_api >= eve::vsx ) << "\n"; - std::cout << "VMX : " << std::boolalpha << (eve::current_api >= eve::vmx ) << "\n"; + std::cout << "VMX: " << std::boolalpha << (eve::current_api >= eve::vmx ) << "\n"; + std::cout << " - VMX 2.03: " << std::boolalpha << (eve::current_api >= eve::vmx_2_03 ) << "\n"; + std::cout << " - VMX 2.05: " << std::boolalpha << (eve::current_api >= eve::vmx_2_05 ) << "\n"; + std::cout << " - VMX 2.06: " << std::boolalpha << (eve::current_api >= eve::vmx_2_06 ) << "\n"; + std::cout << " - VMX 2.07: " << std::boolalpha << (eve::current_api >= eve::vmx_2_07 ) << "\n"; + std::cout << " - VMX 3.00: " << std::boolalpha << (eve::current_api >= eve::vmx_3_00 ) << "\n"; + std::cout << " - VMX 3.01: " << std::boolalpha << (eve::current_api >= eve::vmx_3_01 ) << "\n"; + std::cout << "VSX: " << std::boolalpha << (eve::current_api >= eve::vsx ) << "\n"; + std::cout << " - VSX 2.06: " << std::boolalpha << (eve::current_api >= eve::vsx_2_06 ) << "\n"; + std::cout << " - VSX 2.07: " << std::boolalpha << (eve::current_api >= eve::vsx_2_07 ) << "\n"; + std::cout << " - VSX 3.00: " << std::boolalpha << (eve::current_api >= eve::vsx_3_00 ) << "\n"; + std::cout << " - VSX 3.01: " << std::boolalpha << (eve::current_api >= eve::vsx_3_01 ) << "\n"; std::cout << "\n"; std::cout << "========================\n"; std::cout << "ARM SIMD extensions\n";