@@ -33,6 +33,37 @@ namespace xsimd
3333
3434 namespace kernel
3535 {
36+ // builtin_t<T> - the scalar type as it would be used for a vector intrinsic
37+ // VSX vector intrinsics do not support long, unsigned long, and char
38+ // The builtin<T> definition can be used to map the incoming
39+ // type to the right one to be used with the intrinsics.
40+ template <typename T>
41+ struct builtin_scalar
42+ {
43+ using type = T;
44+ };
45+
46+ template <>
47+ struct builtin_scalar <unsigned long >
48+ {
49+ using type = unsigned long long ;
50+ };
51+
52+ template <>
53+ struct builtin_scalar <long >
54+ {
55+ using type = long long ;
56+ };
57+
58+ template <>
59+ struct builtin_scalar <char >
60+ {
61+ using type = typename std::conditional<std::is_signed<char >::value, signed char , unsigned char >::type;
62+ };
63+
64+ template <typename T>
65+ using builtin_t = typename builtin_scalar<T>::type;
66+
3667 template <class A , class T >
3768 XSIMD_INLINE batch<T, A> avg (batch<T, A> const &, batch<T, A> const &, requires_arch<common>) noexcept ;
3869 template <class A , class T >
@@ -218,7 +249,7 @@ namespace xsimd
218249 template <class A , class T , class = std::enable_if_t <std::is_scalar<T>::value>>
219250 XSIMD_INLINE batch<T, A> broadcast (T val, requires_arch<vsx>) noexcept
220251 {
221- return vec_splats (val);
252+ return vec_splats (static_cast < builtin_t <T>>( val) );
222253 }
223254
224255 // ceil
@@ -421,18 +452,18 @@ namespace xsimd
421452 return ~vec_cmpeq (self.data, self.data);
422453 }
423454
424- // load_aligned
455+ // load_unaligned
425456 template <class A , class T , class = std::enable_if_t <std::is_scalar<T>::value>>
426- XSIMD_INLINE batch<T, A> load_aligned (T const * mem, convert<T>, requires_arch<vsx>) noexcept
457+ XSIMD_INLINE batch<T, A> load_unaligned (T const * mem, convert<T>, requires_arch<vsx>) noexcept
427458 {
428- return vec_ld ( 0 , reinterpret_cast < const typename batch<T, A>::register_type*>(mem) );
459+ return ( typename batch<T, A>::register_type) vec_xl ( 0 , ( builtin_t <T>*)mem );
429460 }
430461
431- // load_unaligned
462+ // load_aligned
432463 template <class A , class T , class = std::enable_if_t <std::is_scalar<T>::value>>
433- XSIMD_INLINE batch<T, A> load_unaligned (T const * mem, convert<T>, requires_arch<vsx>) noexcept
464+ XSIMD_INLINE batch<T, A> load_aligned (T const * mem, convert<T>, requires_arch<vsx>) noexcept
434465 {
435- return vec_vsx_ld ( 0 , ( typename batch<T, A>::register_type const *)mem );
466+ return load_unaligned<A>(mem, kernel::convert<T> {}, vsx {} );
436467 }
437468
438469 // load_complex
@@ -758,14 +789,14 @@ namespace xsimd
758789 template <class A , class T , class = std::enable_if_t <std::is_scalar<T>::value>>
759790 XSIMD_INLINE void store_aligned (T* mem, batch<T, A> const & self, requires_arch<vsx>) noexcept
760791 {
761- return vec_st (self. data , 0 , reinterpret_cast < typename batch<T, A>::register_type*>(mem) );
792+ vec_xst (( typename batch<T, A>::register_type)self. data , 0 , ( builtin_t <T>*)mem );
762793 }
763794
764795 // store_unaligned
765796 template <class A , class T , class = std::enable_if_t <std::is_scalar<T>::value>>
766797 XSIMD_INLINE void store_unaligned (T* mem, batch<T, A> const & self, requires_arch<vsx>) noexcept
767798 {
768- return vec_vsx_st (self. data , 0 , reinterpret_cast < typename batch<T, A>::register_type*>(mem) );
799+ store_aligned<A>(mem, self, vsx {} );
769800 }
770801
771802 // sub
0 commit comments