diff --git a/modules/core/include/opencv2/core/vsx_utils.hpp b/modules/core/include/opencv2/core/vsx_utils.hpp index 4d5a694bae..aafc6c07b1 100644 --- a/modules/core/include/opencv2/core/vsx_utils.hpp +++ b/modules/core/include/opencv2/core/vsx_utils.hpp @@ -257,8 +257,27 @@ VSX_IMPL_1VRG(vec_udword2, vec_udword2, vpopcntd, vec_popcntu) VSX_IMPL_1VRG(vec_udword2, vec_dword2, vpopcntd, vec_popcntu) // converts between single and double-precision -VSX_REDIRECT_1RG(vec_float4, vec_double2, vec_cvfo, vec_floate) -VSX_REDIRECT_1RG(vec_double2, vec_float4, vec_cvfo, vec_doubleo) +// vec_floate and vec_doubleo are available since Power10 and z14 +#if defined(__POWER10__) || (defined(__powerpc64__) && defined(__ARCH_PWR10__) +// Use VSX double<->float conversion instructions (if supported by the architecture) + VSX_REDIRECT_1RG(vec_float4, vec_double2, vec_cvfo, vec_floate) + VSX_REDIRECT_1RG(vec_double2, vec_float4, vec_cvfo, vec_doubleo) +#else +// Fallback: implement vec_cvfo using scalar operations (to ensure successful linking) + static inline vec_float4 vec_cvfo(const vec_double2& a) + { + float r0 = static_cast(reinterpret_cast(&a)[0]); + float r1 = static_cast(reinterpret_cast(&a)[1]); + return (vec_float4){r0, 0.f, r1, 0.f}; + } + + static inline vec_double2 vec_cvfo(const vec_float4& a) + { + double r0 = static_cast(reinterpret_cast(&a)[0]); + double r1 = static_cast(reinterpret_cast(&a)[2]); + return (vec_double2){r0, r1}; + } +#endif // converts word and doubleword to double-precision #undef vec_ctd