26#ifndef _GLIBCXX_EXPERIMENTAL_SIMD_SVE_H_
27#define _GLIBCXX_EXPERIMENTAL_SIMD_SVE_H_
29#if __cplusplus >= 201703L
31#if !_GLIBCXX_SIMD_HAVE_SVE
32#error "simd_sve.h may only be included when SVE on ARM is available"
35_GLIBCXX_SIMD_BEGIN_NAMESPACE
38template <
typename _Tp>
40 __get_sve_value_type()
42 if constexpr (is_integral_v<_Tp>)
44 if constexpr (is_signed_v<_Tp>)
46 if constexpr (
sizeof(_Tp) == 1)
48 else if constexpr (
sizeof(_Tp) == 2)
50 else if constexpr (
sizeof(_Tp) == 4)
52 else if constexpr (
sizeof(_Tp) == 8)
59 if constexpr (
sizeof(_Tp) == 1)
61 else if constexpr (
sizeof(_Tp) == 2)
63 else if constexpr (
sizeof(_Tp) == 4)
65 else if constexpr (
sizeof(_Tp) == 8)
73 if constexpr (is_floating_point_v<_Tp>)
75 if constexpr (
sizeof(_Tp) == 4)
77 else if constexpr (
sizeof(_Tp) == 8)
85template <
typename _Tp>
86 using __get_sve_value_type_t =
decltype(__get_sve_value_type<_Tp>());
88typedef svbool_t __sve_bool_type __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
90template <
typename _Tp,
size_t _Np>
91 struct __sve_vector_type;
93template <
typename _Tp,
size_t _Np>
94 using __sve_vector_type_t =
typename __sve_vector_type<_Tp, _Np>::type;
97 struct __sve_vector_type<int8_t, _Np>
99 typedef svint8_t __sve_vlst_type __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
101 inline static __sve_vlst_type
102 __sve_broadcast(int8_t __dup)
103 {
return svdup_s8(__dup); }
105 inline static __sve_bool_type
107 {
return svwhilelt_b8(
size_t(0), _Np); };
109 using type = __sve_vlst_type;
113 struct __sve_vector_type<uint8_t, _Np>
115 typedef svuint8_t __sve_vlst_type __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
117 inline static __sve_vlst_type
118 __sve_broadcast(uint8_t __dup)
119 {
return svdup_u8(__dup); }
121 inline static __sve_bool_type
123 {
return svwhilelt_b8(
size_t(0), _Np); };
125 using type = __sve_vlst_type;
129 struct __sve_vector_type<int16_t, _Np>
131 typedef svint16_t __sve_vlst_type __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
133 inline static __sve_vlst_type
134 __sve_broadcast(int16_t __dup)
135 {
return svdup_s16(__dup); }
137 inline static __sve_bool_type
139 {
return svwhilelt_b16(
size_t(0), _Np); };
141 using type = __sve_vlst_type;
145 struct __sve_vector_type<uint16_t, _Np>
147 typedef svuint16_t __sve_vlst_type __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
149 inline static __sve_vlst_type
150 __sve_broadcast(uint16_t __dup)
151 {
return svdup_u16(__dup); }
153 inline static __sve_bool_type
155 {
return svwhilelt_b16(
size_t(0), _Np); };
157 using type = __sve_vlst_type;
161 struct __sve_vector_type<int32_t, _Np>
163 typedef svint32_t __sve_vlst_type __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
165 inline static __sve_vlst_type
166 __sve_broadcast(int32_t __dup)
167 {
return svdup_s32(__dup); }
169 inline static __sve_bool_type
171 {
return svwhilelt_b32(
size_t(0), _Np); };
173 using type = __sve_vlst_type;
177 struct __sve_vector_type<uint32_t, _Np>
179 typedef svuint32_t __sve_vlst_type __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
181 inline static __sve_vlst_type
182 __sve_broadcast(uint32_t __dup)
183 {
return svdup_u32(__dup); }
185 inline static __sve_bool_type
187 {
return svwhilelt_b32(
size_t(0), _Np); };
189 using type = __sve_vlst_type;
193 struct __sve_vector_type<int64_t, _Np>
195 typedef svint64_t __sve_vlst_type __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
197 inline static __sve_vlst_type
198 __sve_broadcast(int64_t __dup)
199 {
return svdup_s64(__dup); }
201 inline static __sve_bool_type
203 {
return svwhilelt_b64(
size_t(0), _Np); };
205 using type = __sve_vlst_type;
209 struct __sve_vector_type<uint64_t, _Np>
211 typedef svuint64_t __sve_vlst_type __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
213 inline static __sve_vlst_type
214 __sve_broadcast(uint64_t __dup)
215 {
return svdup_u64(__dup); }
217 inline static __sve_bool_type
219 {
return svwhilelt_b64(
size_t(0), _Np); };
221 using type = __sve_vlst_type;
225 struct __sve_vector_type<float, _Np>
227 typedef svfloat32_t __sve_vlst_type __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
229 inline static __sve_vlst_type
230 __sve_broadcast(
float __dup)
231 {
return svdup_f32(__dup); }
233 inline static __sve_bool_type
235 {
return svwhilelt_b32(
size_t(0), _Np); };
237 using type = __sve_vlst_type;
241 struct __sve_vector_type<double, _Np>
243 typedef svfloat64_t __sve_vlst_type __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
245 inline static __sve_vlst_type
246 __sve_broadcast(
double __dup)
247 {
return svdup_f64(__dup); }
249 inline static __sve_bool_type
251 {
return svwhilelt_b64(
size_t(0), _Np); };
253 using type = __sve_vlst_type;
256template <
typename _Tp,
size_t _Np>
257 struct __sve_vector_type
258 : __sve_vector_type<__get_sve_value_type_t<_Tp>, _Np>
261template <
size_t _Size>
262 struct __sve_mask_type
264 static_assert((_Size & (_Size - 1)) != 0,
"This trait may only be used for non-power-of-2 "
265 "sizes. Power-of-2 sizes must be specialized.");
267 using type =
typename __sve_mask_type<std::__bit_ceil(_Size)>::type;
270template <
size_t _Size>
271 using __sve_mask_type_t =
typename __sve_mask_type<_Size>::type;
274 struct __sve_mask_type<1>
276 using type = __sve_bool_type;
278 using __sve_mask_uint_type = uint8_t;
280 typedef svuint8_t __sve_mask_vector_type
281 __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
284 __sve_mask_active_count(type __active_mask, type __pred)
285 {
return svcntp_b8(__active_mask, __pred); }
288 __sve_mask_first_true()
289 {
return svptrue_pat_b8(SV_VL1); }
292 __sve_mask_next_true(type __active_mask, type __pred)
293 {
return svpnext_b8(__active_mask, __pred); }
296 __sve_mask_get(type __active_mask,
size_t __i)
297 {
return __sve_mask_vector_type(svdup_u8_z(__active_mask, 1))[__i] != 0;}
299 inline static const __sve_mask_vector_type __index0123 = svindex_u8(0, 1);
303 struct __sve_mask_type<2>
305 using type = __sve_bool_type;
307 using __sve_mask_uint_type = uint16_t;
309 typedef svuint16_t __sve_mask_vector_type
310 __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
313 __sve_mask_active_count(type __active_mask, type __pred)
314 {
return svcntp_b16(__active_mask, __pred); }
317 __sve_mask_first_true()
318 {
return svptrue_pat_b16(SV_VL1); }
321 __sve_mask_next_true(type __active_mask, type __pred)
322 {
return svpnext_b16(__active_mask, __pred); }
325 __sve_mask_get(type __active_mask,
size_t __i)
326 {
return __sve_mask_vector_type(svdup_u16_z(__active_mask, 1))[__i] != 0;}
328 inline static const __sve_mask_vector_type __index0123 = svindex_u16(0, 1);
332 struct __sve_mask_type<4>
334 using type = __sve_bool_type;
336 using __sve_mask_uint_type = uint32_t;
338 typedef svuint32_t __sve_mask_vector_type
339 __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
342 __sve_mask_active_count(type __active_mask, type __pred)
343 {
return svcntp_b32(__active_mask, __pred); }
346 __sve_mask_first_true()
347 {
return svptrue_pat_b32(SV_VL1); }
350 __sve_mask_next_true(type __active_mask, type __pred)
351 {
return svpnext_b32(__active_mask, __pred); }
354 __sve_mask_get(type __active_mask,
size_t __i)
355 {
return __sve_mask_vector_type(svdup_u32_z(__active_mask, 1))[__i] != 0;}
357 inline static const __sve_mask_vector_type __index0123 = svindex_u32(0, 1);
361 struct __sve_mask_type<8>
363 using type = __sve_bool_type;
365 using __sve_mask_uint_type = uint64_t;
367 typedef svuint64_t __sve_mask_vector_type
368 __attribute__((arm_sve_vector_bits(__ARM_FEATURE_SVE_BITS)));
371 __sve_mask_active_count(type __active_mask, type __pred)
372 {
return svcntp_b64(__active_mask, __pred); }
375 __sve_mask_first_true()
376 {
return svptrue_pat_b64(SV_VL1); }
379 __sve_mask_next_true(type __active_mask, type __pred)
380 {
return svpnext_b64(__active_mask, __pred); }
383 __sve_mask_get(type __active_mask,
size_t __i)
384 {
return __sve_mask_vector_type(svdup_u64_z(__active_mask, 1))[__i] != 0;}
386 inline static const __sve_mask_vector_type __index0123 = svindex_u64(0, 1);
389template <
typename _To,
typename _From>
390 _GLIBCXX_SIMD_INTRINSIC
constexpr auto
391 __sve_reinterpret_cast(_From __v)
393 if constexpr (std::is_same_v<_To, int32_t>)
394 return svreinterpret_s32(__v);
395 else if constexpr (std::is_same_v<_To, int64_t>)
396 return svreinterpret_s64(__v);
397 else if constexpr (std::is_same_v<_To, float32_t>)
398 return svreinterpret_f32(__v);
399 else if constexpr (std::is_same_v<_To, float64_t>)
400 return svreinterpret_f64(__v);
402 __assert_unreachable<_To>();
405template <
typename _Tp,
size_t _W
idth>
406 struct _SveSimdWrapper
408 static_assert(__is_vectorizable_v<_Tp>);
410 static_assert(_Width >= 2);
412 using _BuiltinType = __sve_vector_type_t<_Tp, _Width>;
414 using value_type = _Tp;
416 static inline constexpr size_t _S_full_size =
sizeof(_BuiltinType) /
sizeof(value_type);
418 static inline constexpr int _S_size = _Width;
420 static inline constexpr bool _S_is_partial = _S_full_size != _S_size;
422 _BuiltinType _M_data;
424 _GLIBCXX_SIMD_INTRINSIC
constexpr _SveSimdWrapper<_Tp, _S_full_size>
425 __as_full_vector()
const
428 _GLIBCXX_SIMD_INTRINSIC
constexpr
429 _SveSimdWrapper(initializer_list<_Tp> __init)
430 : _M_data(__generate_from_n_evaluations<_Width, _BuiltinType>(
431 [&](auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
432 return __init.
begin()[__i.value];
436 _GLIBCXX_SIMD_INTRINSIC
constexpr
437 _SveSimdWrapper() =
default;
439 _GLIBCXX_SIMD_INTRINSIC
constexpr
440 _SveSimdWrapper(
const _SveSimdWrapper&) =
default;
442 _GLIBCXX_SIMD_INTRINSIC
constexpr
443 _SveSimdWrapper(_SveSimdWrapper&&) =
default;
445 _GLIBCXX_SIMD_INTRINSIC
constexpr _SveSimdWrapper&
446 operator=(
const _SveSimdWrapper&) =
default;
448 _GLIBCXX_SIMD_INTRINSIC
constexpr _SveSimdWrapper&
449 operator=(_SveSimdWrapper&&) =
default;
451 _GLIBCXX_SIMD_INTRINSIC
constexpr
452 _SveSimdWrapper(__sve_vector_type_t<_Tp, _Width> __x)
456 template <
typename... _As,
typename =
enable_if_t<((is_same_v<simd_abi::scalar, _As> && ...)
457 &&
sizeof...(_As) <= _Width)>>
458 _GLIBCXX_SIMD_INTRINSIC
constexpr
459 operator _SimdTuple<_Tp, _As...>()
const
461 return __generate_from_n_evaluations<
sizeof...(_As), _SimdTuple<_Tp, _As...>>(
462 [&](
auto __i)
constexpr _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
463 return _M_data[int(__i)];
467 _GLIBCXX_SIMD_INTRINSIC
constexpr
468 operator const _BuiltinType&()
const
471 _GLIBCXX_SIMD_INTRINSIC
constexpr
472 operator _BuiltinType&()
475 _GLIBCXX_SIMD_INTRINSIC
constexpr _Tp
476 operator[](
size_t __i)
const
477 {
return _M_data[__i]; }
479 template <
size_t __i>
480 _GLIBCXX_SIMD_INTRINSIC
constexpr _Tp
481 operator[](_SizeConstant<__i>)
const
482 {
return _M_data[__i]; }
484 _GLIBCXX_SIMD_INTRINSIC
constexpr void
485 _M_set(
size_t __i, _Tp __x)
490 _GLIBCXX_SIMD_INTRINSIC
constexpr bool
491 _M_is_constprop()
const
494 _GLIBCXX_SIMD_INTRINSIC
constexpr bool
495 _M_is_constprop_none_of()
const
498 _GLIBCXX_SIMD_INTRINSIC
constexpr bool
499 _M_is_constprop_all_of()
const
503template <
size_t _Bits,
size_t _W
idth>
504 struct _SveMaskWrapper
506 using _BuiltinSveMaskType = __sve_mask_type<_Bits>;
508 using _BuiltinSveVectorType = __sve_vector_type<__int_with_sizeof_t<_Bits>, _Width>;
510 using _BuiltinType =
typename _BuiltinSveMaskType::type;
512 using value_type = bool;
514 static constexpr size_t _S_full_size =
sizeof(_BuiltinType);
516 _GLIBCXX_SIMD_INTRINSIC
constexpr _SveMaskWrapper<_Bits, _S_full_size>
517 __as_full_vector()
const
520 _GLIBCXX_SIMD_INTRINSIC
constexpr
521 _SveMaskWrapper() =
default;
523 _GLIBCXX_SIMD_INTRINSIC
constexpr
524 _SveMaskWrapper(_BuiltinType __k)
528 _GLIBCXX_SIMD_INTRINSIC
529 operator const _BuiltinType&()
const
532 _GLIBCXX_SIMD_INTRINSIC
533 operator _BuiltinType&()
536 _GLIBCXX_SIMD_INTRINSIC _BuiltinType
540 _GLIBCXX_SIMD_INTRINSIC
constexpr value_type
541 operator[](
size_t __i)
const
543 return _BuiltinSveMaskType::__sve_mask_get(_M_data, __i);
546 template <
size_t __i>
547 _GLIBCXX_SIMD_INTRINSIC
constexpr value_type
548 operator[](_SizeConstant<__i>)
const
550 return _BuiltinSveMaskType::__sve_mask_get(_M_data, __i);
553 _GLIBCXX_SIMD_INTRINSIC
constexpr void
554 _M_set(
size_t __i, value_type __x)
557 = svcmpeq(_BuiltinSveVectorType::__sve_active_mask(), _BuiltinSveMaskType::__index0123,
558 typename _BuiltinSveMaskType::__sve_mask_uint_type(__i));
561 _M_data = svorr_z(_BuiltinSveVectorType::__sve_active_mask(), _M_data, __index);
563 _M_data = svbic_z(_BuiltinSveVectorType::__sve_active_mask(), _M_data, __index);
566 _GLIBCXX_SIMD_INTRINSIC
constexpr bool
567 _M_is_constprop()
const
570 _GLIBCXX_SIMD_INTRINSIC
constexpr bool
571 _M_is_constprop_none_of()
const
574 _GLIBCXX_SIMD_INTRINSIC
constexpr bool
575 _M_is_constprop_all_of()
const
578 _BuiltinType _M_data;
581struct _CommonImplSve;
583template <
typename _Abi,
typename = __detail::__odr_helper>
586template <
typename _Abi,
typename = __detail::__odr_helper>
589template <
int _UsedBytes,
int>
590 struct simd_abi::_SveAbi
592 template <
typename _Tp>
593 static constexpr size_t _S_size = _UsedBytes /
sizeof(_Tp);
595 struct _IsValidAbiTag
596 : __bool_constant<(_UsedBytes > 1)>
599 template <
typename _Tp>
600 struct _IsValidSizeFor
601 : __bool_constant<(_UsedBytes / sizeof(_Tp) > 1 && _UsedBytes % sizeof(_Tp) == 0
602 && _UsedBytes <= __sve_vectorized_size_bytes)>
605 template <
typename _Tp>
607 : conjunction<_IsValidAbiTag, __bool_constant<__have_sve>,
608 __bool_constant<(__vectorized_sizeof<_Tp>() > sizeof(_Tp))>,
609 _IsValidSizeFor<_Tp>>
612 template <
typename _Tp>
613 static constexpr bool _S_is_valid_v = _IsValid<_Tp>::value;
615 using _CommonImpl = _CommonImplSve;
617 using _SimdImpl = _SimdImplSve<_SveAbi<_UsedBytes>>;
619 using _MaskImpl = _MaskImplSve<_SveAbi<_UsedBytes>>;
621 template <
typename _Tp>
622 using _MaskMember = _SveMaskWrapper<
sizeof(_Tp), _S_size<_Tp>>;
624 template <
typename _Tp,
bool = _S_is_val
id_v<_Tp>>
625 struct __traits : _InvalidTraits
628 template <
typename _Tp>
629 struct __traits<_Tp, true>
632 using _SimdImpl = _SimdImplSve<_SveAbi<_UsedBytes>>;
633 using _MaskImpl = _MaskImplSve<_SveAbi<_UsedBytes>>;
635 using _SimdMember = _SveSimdWrapper<_Tp, _S_size<_Tp>>;
636 using _MaskMember = _SveMaskWrapper<
sizeof(_Tp), _S_size<_Tp>>;
638 static constexpr size_t _S_simd_align =
alignof(_SimdMember);
639 static constexpr size_t _S_mask_align =
alignof(_MaskMember);
641 static constexpr size_t _S_full_size = _SimdMember::_S_full_size;
642 static constexpr bool _S_is_partial = _SimdMember::_S_is_partial;
646 _GLIBCXX_SIMD_ALWAYS_INLINE
explicit
647 operator __sve_vector_type_t<_Tp, _S_size<_Tp>>()
const
648 {
return __data(*
static_cast<const simd<_Tp, _SveAbi<_UsedBytes>
>*>(
this)); }
653 using _Ap = __sve_vector_type_t<_Tp, _S_size<_Tp>>;
658 _GLIBCXX_SIMD_ALWAYS_INLINE
constexpr
659 _SimdCastType(_Ap __a)
663 _GLIBCXX_SIMD_ALWAYS_INLINE
constexpr
664 operator _SimdMember()
const
670 _GLIBCXX_SIMD_ALWAYS_INLINE
explicit
671 operator __sve_mask_type_t<sizeof(_Tp)>()
const
673 return __data(*
static_cast<const simd_mask<_Tp, _SveAbi<_UsedBytes>
>*>(
this));
679 using _Ap = __sve_mask_type_t<
sizeof(_Tp)>;
684 _GLIBCXX_SIMD_ALWAYS_INLINE
constexpr
685 _MaskCastType(_Ap __a)
689 _GLIBCXX_SIMD_ALWAYS_INLINE
constexpr
690 operator _MaskMember()
const
695 template <
typename _Tp>
696 static constexpr size_t _S_full_size = __traits<_Tp>::_S_full_size;
698 template <
typename _Tp>
699 static constexpr bool _S_is_partial = __traits<_Tp>::_S_is_partial;
702template <
typename _Tp,
size_t _Np>
703 using __sve_mask = __sve_mask_type<
sizeof(_Tp)>;
712 template <
typename _From,
typename _To,
size_t _ToSize>
713 static inline constexpr bool __converts_via_decomposition_v =
sizeof(_From) !=
sizeof(_To);
715 template <
typename _Tp,
typename _Up,
size_t _Np>
716 _GLIBCXX_SIMD_INTRINSIC
static constexpr __sve_vector_type_t<_Tp, _Np>
717 _S_load(
const _Up* __p, _SveMaskWrapper<
sizeof(_Tp), _Np> __k)
719 using _STp = __get_sve_value_type_t<_Tp>;
720 using _SUp = __get_sve_value_type_t<_Up>;
721 using _V = __sve_vector_type_t<_Tp, _Np>;
722 const _SUp* __up =
reinterpret_cast<const _SUp*
>(__p);
724 if constexpr (std::is_same_v<_Tp, _Up>)
725 return _V(svld1(__k._M_data, __up));
726 if constexpr (std::is_integral_v<_Tp> && std::is_integral_v<_Up>
727 && (
sizeof(_Tp) >
sizeof(_Up)))
729 if constexpr (std::is_same_v<_SUp, int8_t>)
731 if constexpr (std::is_same_v<_STp, int16_t>)
732 return _V(svld1sb_s16(__k._M_data, __up));
733 if constexpr (std::is_same_v<_STp, uint16_t>)
734 return _V(svld1sb_u16(__k._M_data, __up));
735 if constexpr (std::is_same_v<_STp, int32_t>)
736 return _V(svld1sb_s32(__k._M_data, __up));
737 if constexpr (std::is_same_v<_STp, uint32_t>)
738 return _V(svld1sb_u32(__k._M_data, __up));
739 if constexpr (std::is_same_v<_STp, int64_t>)
740 return _V(svld1sb_s64(__k._M_data, __up));
741 if constexpr (std::is_same_v<_STp, uint64_t>)
742 return _V(svld1sb_u64(__k._M_data, __up));
744 if constexpr (std::is_same_v<_SUp, uint8_t>)
746 if constexpr (std::is_same_v<_STp, int16_t>)
747 return _V(svld1ub_s16(__k._M_data, __up));
748 if constexpr (std::is_same_v<_STp, uint16_t>)
749 return _V(svld1ub_u16(__k._M_data, __up));
750 if constexpr (std::is_same_v<_STp, int32_t>)
751 return _V(svld1ub_s32(__k._M_data, __up));
752 if constexpr (std::is_same_v<_STp, uint32_t>)
753 return _V(svld1ub_u32(__k._M_data, __up));
754 if constexpr (std::is_same_v<_STp, int64_t>)
755 return _V(svld1ub_s64(__k._M_data, __up));
756 if constexpr (std::is_same_v<_STp, uint64_t>)
757 return _V(svld1ub_u64(__k._M_data, __up));
759 if constexpr (std::is_same_v<_SUp, int16_t>)
761 if constexpr (std::is_same_v<_STp, int32_t>)
762 return _V(svld1sh_s32(__k._M_data, __up));
763 if constexpr (std::is_same_v<_STp, uint32_t>)
764 return _V(svld1sh_u32(__k._M_data, __up));
765 if constexpr (std::is_same_v<_STp, int64_t>)
766 return _V(svld1sh_s64(__k._M_data, __up));
767 if constexpr (std::is_same_v<_STp, uint64_t>)
768 return _V(svld1sh_u64(__k._M_data, __up));
770 if constexpr (std::is_same_v<_SUp, uint16_t>)
772 if constexpr (std::is_same_v<_STp, int32_t>)
773 return _V(svld1uh_s32(__k._M_data, __up));
774 if constexpr (std::is_same_v<_STp, uint32_t>)
775 return _V(svld1uh_u32(__k._M_data, __up));
776 if constexpr (std::is_same_v<_STp, int64_t>)
777 return _V(svld1uh_s64(__k._M_data, __up));
778 if constexpr (std::is_same_v<_STp, uint64_t>)
779 return _V(svld1uh_u64(__k._M_data, __up));
781 if constexpr (std::is_same_v<_SUp, int32_t>)
783 if constexpr (std::is_same_v<_STp, int64_t>)
784 return _V(svld1sw_s64(__k._M_data, __up));
785 if constexpr (std::is_same_v<_STp, uint64_t>)
786 return _V(svld1sw_u64(__k._M_data, __up));
788 if constexpr (std::is_same_v<_SUp, uint32_t>)
790 if constexpr (std::is_same_v<_STp, int64_t>)
791 return _V(svld1uw_s64(__k._M_data, __up));
792 if constexpr (std::is_same_v<_STp, uint64_t>)
793 return _V(svld1uw_u64(__k._M_data, __up));
796 return __generate_from_n_evaluations<_Np, __sve_vector_type_t<_Tp, _Np>>(
797 [&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
798 return __k[__i] ?
static_cast<_Tp
>(__p[__i]) : _Tp{};
802 template <
typename _Tp,
typename _Up,
size_t _Np>
803 _GLIBCXX_SIMD_INTRINSIC
static constexpr void
804 _S_store(_Up* __p, _SveSimdWrapper<_Tp, _Np> __x, _SveMaskWrapper<
sizeof(_Tp), _Np> __k)
806 using _SUp = __get_sve_value_type_t<_Up>;
807 using _STp = __get_sve_value_type_t<_Tp>;
809 _SUp* __up =
reinterpret_cast<_SUp*
>(__p);
811 if constexpr (std::is_same_v<_Tp, _Up>)
812 return svst1(__k._M_data, __up, __x);
813 if constexpr (std::is_integral_v<_Tp> && std::is_integral_v<_Up>
814 && (
sizeof(_Tp) >
sizeof(_Up)))
816 if constexpr (std::is_same_v<_SUp, int8_t> && std::is_signed_v<_STp>)
817 return svst1b(__k._M_data, __up, __x);
818 if constexpr (std::is_same_v<_SUp, uint8_t> && std::is_unsigned_v<_STp>)
819 return svst1b(__k._M_data, __up, __x);
820 if constexpr (std::is_same_v<_SUp, int16_t> && std::is_signed_v<_STp>)
821 return svst1h(__k._M_data, __up, __x);
822 if constexpr (std::is_same_v<_SUp, uint16_t> && std::is_unsigned_v<_STp>)
823 return svst1h(__k._M_data, __up, __x);
824 if constexpr (std::is_same_v<_SUp, int32_t> && std::is_signed_v<_STp>)
825 return svst1w(__k._M_data, __up, __x);
826 if constexpr (std::is_same_v<_SUp, uint32_t> && std::is_unsigned_v<_STp>)
827 return svst1w(__k._M_data, __up, __x);
830 __execute_n_times<_Np>([&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
832 __p[__i] =
static_cast<_Up
>(__x[__i]);
836 template <
typename _Tp,
size_t _Np>
837 _GLIBCXX_SIMD_INTRINSIC
static constexpr __sve_vector_type_t<_Tp, _Np>
838 _S_blend(_SveMaskWrapper<
sizeof(_Tp), _Np> __k, _SveSimdWrapper<_Tp, _Np> __at0,
839 _SveSimdWrapper<_Tp, _Np> __at1)
840 {
return svsel(__k._M_data, __at1._M_data, __at0._M_data); }
842 template <
size_t _Np,
bool _Sanitized>
843 _GLIBCXX_SIMD_INTRINSIC
static constexpr void
844 _S_store_bool_array(_BitMask<_Np, _Sanitized> __x,
bool* __mem)
846 __execute_n_times<_Np>([&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
847 __mem[__i] = __x[__i];
852template <
typename _Abi,
typename>
855 template <
typename _Tp>
856 using _MaskMember =
typename _Abi::template _MaskMember<_Tp>;
858 template <
typename _Tp>
859 using _SimdMember =
typename _Abi::template __traits<_Tp>::_SimdMember;
861 using _CommonImpl =
typename _Abi::_CommonImpl;
862 using _SuperImpl =
typename _Abi::_SimdImpl;
863 using _MaskImpl =
typename _Abi::_MaskImpl;
865 template <
typename _Tp>
866 static constexpr size_t _S_full_size = _Abi::template _S_full_size<_Tp>;
868 template <
typename _Tp>
869 static constexpr size_t _S_size = _Abi::template _S_size<_Tp>;
871 template <
typename _Tp>
872 using _TypeTag = _Tp*;
874 using abi_type = _Abi;
876 template <
typename _Tp>
877 _GLIBCXX_SIMD_INTRINSIC
static constexpr auto
878 _S_broadcast(_Tp __x)
noexcept
880 return __sve_vector_type<_Tp, __sve_vectorized_size_bytes /
sizeof(_Tp)>
881 ::__sve_broadcast(__x);
884 template <
typename _Fp,
typename _Tp>
885 inline static constexpr _SimdMember<_Tp>
886 _S_generator(_Fp&& __gen, _TypeTag<_Tp>)
888 constexpr size_t _Np = _S_size<_Tp>;
889 _SveSimdWrapper<_Tp, _Np> __ret;
890 __execute_n_times<_S_size<_Tp>>(
891 [&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { __ret._M_set(__i, __gen(__i)); });
895 template <
typename _Tp,
typename _Up>
896 _GLIBCXX_SIMD_INTRINSIC
static constexpr _SimdMember<_Tp>
897 _S_load(
const _Up* __mem, _TypeTag<_Tp>)
noexcept
899 constexpr size_t _Np = _S_size<_Tp>;
900 _SimdMember<_Tp> __ret = _CommonImpl::template _S_load<_Tp, _Up, _Np>(
901 __mem, _SveMaskWrapper<
sizeof(_Tp), _Np>{
902 __sve_vector_type<_Tp, _Np>::__sve_active_mask()});
906 template <
typename _Tp,
size_t _Np,
typename _Up>
907 static constexpr inline _SveSimdWrapper<_Tp, _Np>
908 _S_masked_load(_SveSimdWrapper<_Tp, _Np> __merge, _MaskMember<_Tp> __k,
const _Up* __mem)
911 __sve_vector_type_t<_Tp, _Np> __v
912 = _CommonImpl::template _S_load<_Tp, _Up, _Np>(__mem, __k);
913 __sve_vector_type_t<_Tp, _Np> __ret = svsel(__k._M_data, __v, __merge._M_data);
917 template <
typename _Tp,
typename _Up>
918 _GLIBCXX_SIMD_INTRINSIC
static constexpr void
919 _S_store(_SimdMember<_Tp> __v, _Up* __mem, _TypeTag<_Tp>)
noexcept
921 constexpr size_t _Np = _S_size<_Tp>;
922 _CommonImpl::template _S_store<_Tp, _Up, _Np>(
923 __mem, __v, __sve_vector_type<_Tp, _Np>::__sve_active_mask());
926 template <
typename _Tp,
typename _Up,
size_t _Np>
927 static constexpr inline void
928 _S_masked_store(
const _SveSimdWrapper<_Tp, _Np> __v, _Up* __mem,
929 const _SveMaskWrapper<
sizeof(_Tp), _Np> __k)
noexcept
930 { _CommonImpl::template _S_store<_Tp, _Up, _Np>(__mem, __v, __k); }
932 template <
typename _Tp,
size_t _Np>
933 _GLIBCXX_SIMD_INTRINSIC
static constexpr _MaskMember<_Tp>
934 _S_negate(_SveSimdWrapper<_Tp, _Np> __x)
noexcept
936 return svcmpeq(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data,
937 __sve_vector_type<_Tp, _Np>::__sve_broadcast(_Tp{}));
940 template <
typename _Tp,
typename _BinaryOperation>
941 _GLIBCXX_SIMD_INTRINSIC
static constexpr _Tp
942 _S_reduce(simd<_Tp, _Abi> __x, _BinaryOperation&& __binary_op)
944 auto __x_data = __x._M_data;
945 constexpr size_t _Np = simd_size_v<_Tp, _Abi>;
946 using __sve_vec_t = __sve_vector_type_t<_Tp, _Np>;
947 std::size_t __i = __x.size();
948 for (; (__i % 2) != 1; __i /= 2)
950 __x_data = __binary_op(simd<_Tp, _Abi>(
951 __private_init, _SveSimdWrapper<_Tp, _Np>(
952 __sve_vec_t(svuzp1(__x_data, __x_data)))),
954 __private_init, _SveSimdWrapper<_Tp, _Np>(
955 __sve_vec_t(svuzp2(__x_data, __x_data))))
958 _Tp __res = __x_data[0];
959 for (
size_t __ri = 1; __ri != __i; __ri++)
960 __res = __binary_op(__x_data[__ri], __res);
964 template <
typename _Tp>
965 _GLIBCXX_SIMD_INTRINSIC
static constexpr _Tp
966 _S_reduce(simd<_Tp, _Abi> __x, plus<>)
968 return svaddv(__sve_vector_type<_Tp, _S_size<_Tp>>::__sve_active_mask(), __x._M_data);
971 template <
typename _Tp>
972 _GLIBCXX_SIMD_INTRINSIC
static constexpr _Tp
973 _S_reduce(simd<_Tp, _Abi> __x, bit_and<>)
975 return svandv(__sve_vector_type<_Tp, _S_size<_Tp>>::__sve_active_mask(), __x._M_data);
978 template <
typename _Tp>
979 _GLIBCXX_SIMD_INTRINSIC
static constexpr _Tp
980 _S_reduce(simd<_Tp, _Abi> __x, bit_or<>)
982 return svorv(__sve_vector_type<_Tp, _S_size<_Tp>>::__sve_active_mask(), __x._M_data);
985 template <
typename _Tp>
986 _GLIBCXX_SIMD_INTRINSIC
static constexpr _Tp
987 _S_reduce(simd<_Tp, _Abi> __x, bit_xor<>)
989 return sveorv(__sve_vector_type<_Tp, _S_size<_Tp>>::__sve_active_mask(), __x._M_data);
992 template <
typename _Tp>
993 _GLIBCXX_SIMD_INTRINSIC
static constexpr _Tp
994 _S_reduce(simd<_Tp, _Abi> __x, __detail::_Maximum())
996 return svmaxv(__sve_vector_type<_Tp, _S_size<_Tp>>::__sve_active_mask(), __x._M_data);
999 template <
typename _Tp>
1000 _GLIBCXX_SIMD_INTRINSIC
static constexpr _Tp
1001 _S_reduce(simd<_Tp, _Abi> __x, __detail::_Minimum())
1003 return svminv(__sve_vector_type<_Tp, _S_size<_Tp>>::__sve_active_mask(), __x._M_data);
1006 template <
typename _Tp,
size_t _Np>
1007 _GLIBCXX_SIMD_NORMAL_MATH _GLIBCXX_SIMD_INTRINSIC
static constexpr
1008 __sve_vector_type_t<_Tp, _Np>
1009 _S_min(_SveSimdWrapper<_Tp, _Np> __a, _SveSimdWrapper<_Tp, _Np> __b)
1011 return svmin_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __a._M_data, __b._M_data);
1014 template <
typename _Tp,
size_t _Np>
1015 _GLIBCXX_SIMD_NORMAL_MATH _GLIBCXX_SIMD_INTRINSIC
static constexpr
1016 __sve_vector_type_t<_Tp, _Np>
1017 _S_max(_SveSimdWrapper<_Tp, _Np> __a, _SveSimdWrapper<_Tp, _Np> __b)
1019 return svmax_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __a._M_data, __b._M_data);
1022 template <
typename _Tp,
size_t _Np>
1023 _GLIBCXX_SIMD_NORMAL_MATH _GLIBCXX_SIMD_INTRINSIC
static constexpr
1024 pair<_SveSimdWrapper<_Tp, _Np>, _SveSimdWrapper<_Tp, _Np>>
1025 _S_minmax(_SveSimdWrapper<_Tp, _Np> __a, _SveSimdWrapper<_Tp, _Np> __b)
1028 svmin_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __a._M_data, __b._M_data),
1029 svmax_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __a._M_data, __b._M_data)
1033 template <
typename _Tp,
size_t _Np>
1034 _GLIBCXX_SIMD_INTRINSIC
static constexpr __sve_vector_type_t<_Tp, _Np>
1035 _S_complement(_SveSimdWrapper<_Tp, _Np> __x)
noexcept
1037 if constexpr (is_floating_point_v<_Tp>)
1039 using _Ip = __get_sve_value_type_t<__int_for_sizeof_t<_Tp>>;
1040 return __sve_reinterpret_cast<_Tp>(
1041 svnot_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(),
1042 __sve_reinterpret_cast<_Ip>(__x)));
1045 return svnot_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data);
1048 template <
typename _Tp,
size_t _Np>
1049 _GLIBCXX_SIMD_INTRINSIC
static constexpr _SveSimdWrapper<_Tp, _Np>
1050 _S_unary_minus(_SveSimdWrapper<_Tp, _Np> __x)
noexcept
1052 return svmul_x(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data,
1053 static_cast<_Tp
>(-1));
1056 template <
typename _Tp,
size_t _Np>
1057 _GLIBCXX_SIMD_INTRINSIC
static constexpr __sve_vector_type_t<_Tp, _Np>
1058 _S_plus(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1059 {
return __x._M_data + __y._M_data; }
1061 template <
typename _Tp,
size_t _Np>
1062 _GLIBCXX_SIMD_INTRINSIC
static constexpr __sve_vector_type_t<_Tp, _Np>
1063 _S_minus(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1064 {
return __x._M_data - __y._M_data; }
1066 template <
typename _Tp,
size_t _Np>
1067 _GLIBCXX_SIMD_INTRINSIC
static constexpr __sve_vector_type_t<_Tp, _Np>
1068 _S_multiplies(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1069 {
return __x._M_data * __y._M_data; }
1071 template <
typename _Tp,
size_t _Np>
1072 _GLIBCXX_SIMD_INTRINSIC
static constexpr __sve_vector_type_t<_Tp, _Np>
1073 _S_divides(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1075 __sve_vector_type_t<_Tp, _Np> __y_padded
1076 = svsel(__sve_vector_type<_Tp, _Np>::__sve_active_mask(),
1077 __y._M_data, __sve_vector_type<_Tp, _Np>::__sve_broadcast(1));
1078 return __x._M_data / __y_padded;
1081 template <
typename _Tp,
size_t _Np>
1082 _GLIBCXX_SIMD_INTRINSIC
static constexpr __sve_vector_type_t<_Tp, _Np>
1083 _S_modulus(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1085 __sve_vector_type_t<_Tp, _Np> __y_padded
1086 = svsel(__sve_vector_type<_Tp, _Np>::__sve_active_mask(),
1087 __y._M_data, __sve_vector_type<_Tp, _Np>::__sve_broadcast(1));
1088 return __x._M_data % __y_padded;
1091 template <
typename _Tp,
size_t _Np>
1092 _GLIBCXX_SIMD_INTRINSIC
static constexpr __sve_vector_type_t<_Tp, _Np>
1093 _S_bit_and(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1095 if constexpr (is_floating_point_v<_Tp>)
1097 using _Ip = __get_sve_value_type_t<__int_for_sizeof_t<_Tp>>;
1098 return __sve_reinterpret_cast<_Tp>(
1099 svand_x(__sve_vector_type<_Tp, _Np>::__sve_active_mask(),
1100 __sve_reinterpret_cast<_Ip>(__x), __sve_reinterpret_cast<_Ip>(__y)));
1103 return svand_x(__sve_vector_type<_Tp, _Np>::__sve_active_mask(),
1104 __x._M_data, __y._M_data);
1107 template <
typename _Tp,
size_t _Np>
1108 _GLIBCXX_SIMD_INTRINSIC
static constexpr __sve_vector_type_t<_Tp, _Np>
1109 _S_bit_or(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1111 if constexpr (is_floating_point_v<_Tp>)
1113 using _Ip = __get_sve_value_type_t<__int_for_sizeof_t<_Tp>>;
1114 return __sve_reinterpret_cast<_Tp>(
1115 svorr_x(__sve_vector_type<_Tp, _Np>::__sve_active_mask(),
1116 __sve_reinterpret_cast<_Ip>(__x), __sve_reinterpret_cast<_Ip>(__y)));
1119 return svorr_x(__sve_vector_type<_Tp, _Np>::__sve_active_mask(),
1120 __x._M_data, __y._M_data);
1123 template <
typename _Tp,
size_t _Np>
1124 _GLIBCXX_SIMD_INTRINSIC
static constexpr __sve_vector_type_t<_Tp, _Np>
1125 _S_bit_xor(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1127 if constexpr (is_floating_point_v<_Tp>)
1129 using _Ip = __get_sve_value_type_t<__int_for_sizeof_t<_Tp>>;
1130 return __sve_reinterpret_cast<_Tp>(
1131 sveor_x(__sve_vector_type<_Tp, _Np>::__sve_active_mask(),
1132 __sve_reinterpret_cast<_Ip>(__x), __sve_reinterpret_cast<_Ip>(__y)));
1135 return sveor_x(__sve_vector_type<_Tp, _Np>::__sve_active_mask(),
1136 __x._M_data, __y._M_data);
1139 template <
typename _Tp,
size_t _Np>
1140 _GLIBCXX_SIMD_INTRINSIC
static __sve_vector_type_t<_Tp, _Np>
1141 _S_bit_shift_left(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1142 {
return __x._M_data << __y._M_data; }
1144 template <
typename _Tp,
size_t _Np>
1145 _GLIBCXX_SIMD_INTRINSIC
static __sve_vector_type_t<_Tp, _Np>
1146 _S_bit_shift_right(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1147 {
return __x._M_data >> __y._M_data; }
1149 template <
typename _Tp,
size_t _Np>
1150 _GLIBCXX_SIMD_INTRINSIC
static constexpr __sve_vector_type_t<_Tp, _Np>
1151 _S_bit_shift_left(_SveSimdWrapper<_Tp, _Np> __x,
int __y)
1152 {
return __x._M_data << __y; }
1154 template <
typename _Tp,
size_t _Np>
1155 _GLIBCXX_SIMD_INTRINSIC
static constexpr __sve_vector_type_t<_Tp, _Np>
1156 _S_bit_shift_right(_SveSimdWrapper<_Tp, _Np> __x,
int __y)
1157 {
return __x._M_data >> __y; }
1159 template <
typename _Tp,
size_t _Np>
1160 _GLIBCXX_SIMD_INTRINSIC
static constexpr void
1161 _S_increment(_SveSimdWrapper<_Tp, _Np>& __x)
1162 { __x = __x._M_data + 1; }
1164 template <
typename _Tp,
size_t _Np>
1165 _GLIBCXX_SIMD_INTRINSIC
static constexpr void
1166 _S_decrement(_SveSimdWrapper<_Tp, _Np>& __x)
1167 { __x = __x._M_data - 1; }
1169 template <
typename _Tp,
size_t _Np>
1170 _GLIBCXX_SIMD_INTRINSIC
static constexpr _MaskMember<_Tp>
1171 _S_equal_to(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1173 return svcmpeq(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data, __y._M_data);
1176 template <
typename _Tp,
size_t _Np>
1177 _GLIBCXX_SIMD_INTRINSIC
static constexpr _MaskMember<_Tp>
1178 _S_not_equal_to(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1180 return svcmpne(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data, __y._M_data);
1183 template <
typename _Tp,
size_t _Np>
1184 _GLIBCXX_SIMD_INTRINSIC
static constexpr _MaskMember<_Tp>
1185 _S_less(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1187 return svcmplt(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data, __y._M_data);
1190 template <
typename _Tp,
size_t _Np>
1191 _GLIBCXX_SIMD_INTRINSIC
static constexpr _MaskMember<_Tp>
1192 _S_less_equal(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1194 return svcmple(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data, __y._M_data);
1198#define _GLIBCXX_SIMD_MATH_FALLBACK(__name) \
1199 template <typename _Tp, size_t _Np, typename... _More> \
1200 static _SveSimdWrapper<_Tp, _Np> _S_##__name(const _SveSimdWrapper<_Tp, _Np>& __x, \
1201 const _More&... __more) \
1203 _SveSimdWrapper<_Tp, _Np> __r; \
1204 __execute_n_times<_Np>([&](auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { \
1205 __r._M_set(__i, __name(__x[__i], __more[__i]...)); \
1210#define _GLIBCXX_SIMD_MATH_FALLBACK_FIXEDRET(_RetTp, __name) \
1211 template <typename _Tp, typename... _More> \
1212 static auto _S_##__name(const _Tp& __x, const _More&... __more) \
1214 return __fixed_size_storage_t<_RetTp, _Tp::_S_size>::_S_generate( \
1215 [&](auto __meta) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { \
1216 return __meta._S_generator( \
1217 [&](auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { \
1218 return __name(__x[__meta._S_offset + __i], \
1219 __more[__meta._S_offset + __i]...); \
1220 }, static_cast<_RetTp*>(nullptr)); \
1224 _GLIBCXX_SIMD_MATH_FALLBACK(acos)
1225 _GLIBCXX_SIMD_MATH_FALLBACK(asin)
1226 _GLIBCXX_SIMD_MATH_FALLBACK(atan)
1227 _GLIBCXX_SIMD_MATH_FALLBACK(atan2)
1228 _GLIBCXX_SIMD_MATH_FALLBACK(cos)
1229 _GLIBCXX_SIMD_MATH_FALLBACK(sin)
1230 _GLIBCXX_SIMD_MATH_FALLBACK(tan)
1231 _GLIBCXX_SIMD_MATH_FALLBACK(acosh)
1232 _GLIBCXX_SIMD_MATH_FALLBACK(asinh)
1233 _GLIBCXX_SIMD_MATH_FALLBACK(atanh)
1234 _GLIBCXX_SIMD_MATH_FALLBACK(cosh)
1235 _GLIBCXX_SIMD_MATH_FALLBACK(sinh)
1236 _GLIBCXX_SIMD_MATH_FALLBACK(tanh)
1237 _GLIBCXX_SIMD_MATH_FALLBACK(exp)
1238 _GLIBCXX_SIMD_MATH_FALLBACK(exp2)
1239 _GLIBCXX_SIMD_MATH_FALLBACK(expm1)
1240 _GLIBCXX_SIMD_MATH_FALLBACK_FIXEDRET(
int, ilogb)
1241 _GLIBCXX_SIMD_MATH_FALLBACK(log)
1242 _GLIBCXX_SIMD_MATH_FALLBACK(log10)
1243 _GLIBCXX_SIMD_MATH_FALLBACK(log1p)
1244 _GLIBCXX_SIMD_MATH_FALLBACK(log2)
1245 _GLIBCXX_SIMD_MATH_FALLBACK(logb)
1248 _GLIBCXX_SIMD_MATH_FALLBACK(scalbn)
1249 _GLIBCXX_SIMD_MATH_FALLBACK(scalbln)
1250 _GLIBCXX_SIMD_MATH_FALLBACK(cbrt)
1251 _GLIBCXX_SIMD_MATH_FALLBACK(pow)
1252 _GLIBCXX_SIMD_MATH_FALLBACK(erf)
1253 _GLIBCXX_SIMD_MATH_FALLBACK(erfc)
1254 _GLIBCXX_SIMD_MATH_FALLBACK(lgamma)
1255 _GLIBCXX_SIMD_MATH_FALLBACK(tgamma)
1257 _GLIBCXX_SIMD_MATH_FALLBACK_FIXEDRET(
long, lrint)
1258 _GLIBCXX_SIMD_MATH_FALLBACK_FIXEDRET(
long long, llrint)
1260 _GLIBCXX_SIMD_MATH_FALLBACK_FIXEDRET(
long, lround)
1261 _GLIBCXX_SIMD_MATH_FALLBACK_FIXEDRET(
long long, llround)
1263 _GLIBCXX_SIMD_MATH_FALLBACK(fmod)
1264 _GLIBCXX_SIMD_MATH_FALLBACK(remainder)
1266 template <
typename _Tp,
size_t _Np>
1267 static _SveSimdWrapper<_Tp, _Np>
1268 _S_remquo(
const _SveSimdWrapper<_Tp, _Np> __x,
const _SveSimdWrapper<_Tp, _Np> __y,
1269 __fixed_size_storage_t<int, _Np>* __z)
1271 _SveSimdWrapper<_Tp, _Np> __r{};
1272 __execute_n_times<_Np>([&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
1274 __r._M_set(__i, remquo(__x[__i], __y[__i], &__tmp));
1275 __z->_M_set(__i, __tmp);
1280 template <
typename _Tp,
size_t _Np>
1281 _GLIBCXX_SIMD_INTRINSIC
static __fixed_size_storage_t<int, _Np>
1282 _S_fpclassify(_SveSimdWrapper<_Tp, _Np> __x)
1284 __fixed_size_storage_t<int, _Np> __r{};
1285 __execute_n_times<_Np>([&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
1286 __r._M_set(__i, std::fpclassify(__x[__i]));
1292 _GLIBCXX_SIMD_MATH_FALLBACK(nextafter)
1293 _GLIBCXX_SIMD_MATH_FALLBACK(fdim)
1295#undef _GLIBCXX_SIMD_MATH_FALLBACK
1296#undef _GLIBCXX_SIMD_MATH_FALLBACK_FIXEDRET
1298 template <
typename _Tp,
size_t _Np,
typename _Op>
1299 static constexpr _MaskMember<_Tp>
1300 __fp_cmp(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y, _Op __op)
1302 using _Ip = __get_sve_value_type_t<__int_for_sizeof_t<_Tp>>;
1303 using _VI = __sve_vector_type_t<_Ip, _Np>;
1304 using _WI = _SveSimdWrapper<_Ip, _Np>;
1305 const _WI __fmv = __sve_vector_type<_Ip, _Np>::__sve_broadcast(__finite_max_v<_Ip>);
1306 const _WI __zerov = __sve_vector_type<_Ip, _Np>::__sve_broadcast(0);
1307 const _WI __xn = _VI(__sve_reinterpret_cast<_Ip>(__x));
1308 const _WI __yn = _VI(__sve_reinterpret_cast<_Ip>(__y));
1311 = svsel(_S_less(__xn, __zerov), _S_unary_minus(_WI(_S_bit_and(__xn, __fmv))), __xn);
1313 = svsel(_S_less(__yn, __zerov), _S_unary_minus(_WI(_S_bit_and(__yn, __fmv))), __yn);
1314 return svbic_z(__sve_vector_type<_Ip, _Np>::__sve_active_mask(), __op(__xp, __yp)._M_data,
1315 _SuperImpl::_S_isunordered(__x, __y)._M_data);
1318 template <
typename _Tp,
size_t _Np>
1319 static constexpr _MaskMember<_Tp>
1320 _S_isgreater(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
noexcept
1321 {
return __fp_cmp(__x, __y, [](
auto __xp,
auto __yp) {
return _S_less(__yp, __xp); }); }
1323 template <
typename _Tp,
size_t _Np>
1324 static constexpr _MaskMember<_Tp>
1325 _S_isgreaterequal(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
noexcept
1326 {
return __fp_cmp(__x, __y, [](
auto __xp,
auto __yp) {
return _S_less_equal(__yp, __xp); }); }
1328 template <
typename _Tp,
size_t _Np>
1329 static constexpr _MaskMember<_Tp>
1330 _S_isless(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
noexcept
1331 {
return __fp_cmp(__x, __y, [](
auto __xp,
auto __yp) {
return _S_less(__xp, __yp); }); }
1333 template <
typename _Tp,
size_t _Np>
1334 static constexpr _MaskMember<_Tp>
1335 _S_islessequal(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
noexcept
1336 {
return __fp_cmp(__x, __y, [](
auto __xp,
auto __yp) {
return _S_less_equal(__xp, __yp); }); }
1338 template <
typename _Tp,
size_t _Np>
1339 static constexpr _MaskMember<_Tp>
1340 _S_islessgreater(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
noexcept
1342 return svbic_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(),
1343 _SuperImpl::_S_not_equal_to(__x, __y)._M_data,
1344 _SuperImpl::_S_isunordered(__x, __y)._M_data);
1347 template <
typename _Tp,
size_t _Np>
1348 _GLIBCXX_SIMD_INTRINSIC
static _SveSimdWrapper<_Tp, _Np>
1349 _S_abs(_SveSimdWrapper<_Tp, _Np> __x)
noexcept
1350 {
return svabs_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data); }
1352 template <
typename _Tp,
size_t _Np>
1353 _GLIBCXX_SIMD_INTRINSIC
static _SveSimdWrapper<_Tp, _Np>
1354 _S_fabs(_SveSimdWrapper<_Tp, _Np> __x)
noexcept
1355 {
return svabs_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data); }
1357 template <
typename _Tp,
size_t _Np>
1358 _GLIBCXX_SIMD_INTRINSIC
static _SveSimdWrapper<_Tp, _Np>
1359 _S_sqrt(_SveSimdWrapper<_Tp, _Np> __x)
noexcept
1360 {
return svsqrt_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data); }
1362 template <
typename _Tp,
size_t _Np>
1363 _GLIBCXX_SIMD_INTRINSIC
static _SveSimdWrapper<_Tp, _Np>
1364 _S_ldexp(_SveSimdWrapper<_Tp, _Np> __x, __fixed_size_storage_t<int, _Np> __y)
noexcept
1366 auto __sve_register = __y.first;
1367 if constexpr (std::is_same_v<_Tp, float>)
1368 return svscale_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data,
1369 __sve_register._M_data);
1372 __sve_vector_type_t<int64_t, _Np> __sve_d_register = svunpklo(__sve_register);
1373 return svscale_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data,
1378 template <
typename _Tp,
size_t _Np>
1379 _GLIBCXX_SIMD_INTRINSIC
static _SveSimdWrapper<_Tp, _Np>
1380 _S_fma(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y,
1381 _SveSimdWrapper<_Tp, _Np> __z)
1383 return svmad_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data, __y._M_data,
1387 template <
typename _Tp,
size_t _Np>
1388 _GLIBCXX_SIMD_INTRINSIC
static _SveSimdWrapper<_Tp, _Np>
1389 _S_fmax(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1391 return svmaxnm_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data, __y._M_data);
1394 template <
typename _Tp,
size_t _Np>
1395 _GLIBCXX_SIMD_INTRINSIC
static _SveSimdWrapper<_Tp, _Np>
1396 _S_fmin(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1398 return svminnm_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data, __y._M_data);
1401 template <
typename _Tp,
size_t _Np>
1402 _GLIBCXX_SIMD_INTRINSIC
static _MaskMember<_Tp>
1403 _S_isfinite([[maybe_unused]] _SveSimdWrapper<_Tp, _Np> __x)
1405#if __FINITE_MATH_ONLY__
1406 return __sve_vector_type_t<_Tp, _Np>::__sve_all_true_mask();
1410 using _Ip = __get_sve_value_type_t<__int_for_sizeof_t<_Tp>>;
1411 const __sve_vector_type_t<_Ip, _Np> __absn = __sve_reinterpret_cast<_Ip>(_S_abs(__x));
1412 const __sve_vector_type_t<_Ip, _Np> __maxn
1413 = __sve_reinterpret_cast<_Ip>(
1414 __sve_vector_type<_Tp, _Np>::__sve_broadcast(__finite_max_v<_Tp>));
1416 return _S_less_equal(_SveSimdWrapper<_Ip, _Np>{__absn}, _SveSimdWrapper<_Ip, _Np>{__maxn});
1420 template <
typename _Tp,
size_t _Np>
1421 _GLIBCXX_SIMD_INTRINSIC
static _MaskMember<_Tp>
1422 _S_isinf([[maybe_unused]] _SveSimdWrapper<_Tp, _Np> __x)
1424#if __FINITE_MATH_ONLY__
1427 return _S_equal_to<_Tp, _Np>(_S_abs(__x), _S_broadcast(__infinity_v<_Tp>));
1431 template <
typename _Tp,
size_t _Np>
1432 _GLIBCXX_SIMD_INTRINSIC
static _MaskMember<_Tp>
1433 _S_isnan([[maybe_unused]] _SveSimdWrapper<_Tp, _Np> __x)
1435#if __FINITE_MATH_ONLY__
1438 return svcmpuo(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data, __x._M_data);
1442 template <
typename _Tp,
size_t _Np>
1443 _GLIBCXX_SIMD_INTRINSIC
static _MaskMember<_Tp>
1444 _S_isnormal(_SveSimdWrapper<_Tp, _Np> __x)
1446 using _Ip = __get_sve_value_type_t<__int_for_sizeof_t<_Tp>>;
1447 using _V = __sve_vector_type_t<_Ip, _Np>;
1448 using _VW = _SveSimdWrapper<_Ip, _Np>;
1450 const _V __absn = __sve_reinterpret_cast<_Ip>(_S_abs(__x));
1451 const _V __minn = __sve_reinterpret_cast<_Ip>(
1452 __sve_vector_type<_Tp, _Np>::__sve_broadcast(__norm_min_v<_Tp>));
1453#if __FINITE_MATH_ONLY__
1454 return _S_greater_equal(_VW{__absn}, _VW{__minn});
1456 const _V __maxn = __sve_reinterpret_cast<_Ip>(
1457 __sve_vector_type<_Tp, _Np>::__sve_broadcast(__finite_max_v<_Tp>));
1458 return _MaskImpl::_S_bit_and(_S_less_equal(_VW{__minn}, _VW{__absn}),
1459 _S_less_equal(_VW{__absn}, _VW{__maxn}));
1463 template <
typename _Tp,
size_t _Np>
1464 _GLIBCXX_SIMD_INTRINSIC
static _MaskMember<_Tp>
1465 _S_signbit(_SveSimdWrapper<_Tp, _Np> __x)
1467 using _Ip = __get_sve_value_type_t<__int_for_sizeof_t<_Tp>>;
1468 using _V = __sve_vector_type_t<_Ip, _Np>;
1469 using _VW = _SveSimdWrapper<_Ip, _Np>;
1471 const _V __xn = __sve_reinterpret_cast<_Ip>(__x);
1472 const _V __zeron = __sve_vector_type<_Ip, _Np>::__sve_broadcast(0);
1473 return _S_less(_VW{__xn}, _VW{__zeron});
1476 template <
typename _Tp,
size_t _Np>
1477 _GLIBCXX_SIMD_INTRINSIC
static _MaskMember<_Tp>
1478 _S_isunordered(_SveSimdWrapper<_Tp, _Np> __x, _SveSimdWrapper<_Tp, _Np> __y)
1480 return svcmpuo(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data, __y._M_data);
1483 template <
typename _Tp,
size_t _Np>
1484 _GLIBCXX_SIMD_INTRINSIC
static _SveSimdWrapper<_Tp, _Np>
1485 _S_nearbyint(_SveSimdWrapper<_Tp, _Np> __x)
noexcept
1486 {
return svrinti_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data); }
1488 template <
typename _Tp,
size_t _Np>
1489 _GLIBCXX_SIMD_INTRINSIC
static _SveSimdWrapper<_Tp, _Np>
1490 _S_rint(_SveSimdWrapper<_Tp, _Np> __x)
noexcept
1491 {
return _SuperImpl::_S_nearbyint(__x); }
1493 template <
typename _Tp,
size_t _Np>
1494 _GLIBCXX_SIMD_INTRINSIC
static _SveSimdWrapper<_Tp, _Np>
1495 _S_trunc(_SveSimdWrapper<_Tp, _Np> __x)
noexcept
1496 {
return svrintz_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data); }
1498 template <
typename _Tp,
size_t _Np>
1499 _GLIBCXX_SIMD_INTRINSIC
static _SveSimdWrapper<_Tp, _Np>
1500 _S_round(_SveSimdWrapper<_Tp, _Np> __x)
noexcept
1501 {
return svrinta_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data); }
1503 template <
typename _Tp,
size_t _Np>
1504 _GLIBCXX_SIMD_INTRINSIC
static _SveSimdWrapper<_Tp, _Np>
1505 _S_floor(_SveSimdWrapper<_Tp, _Np> __x)
noexcept
1506 {
return svrintm_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data); }
1508 template <
typename _Tp,
size_t _Np>
1509 _GLIBCXX_SIMD_INTRINSIC
static _SveSimdWrapper<_Tp, _Np>
1510 _S_ceil(_SveSimdWrapper<_Tp, _Np> __x)
noexcept
1511 {
return svrintp_z(__sve_vector_type<_Tp, _Np>::__sve_active_mask(), __x._M_data); }
1513 template <
typename _Tp,
size_t _Bits,
size_t _Np>
1514 _GLIBCXX_SIMD_INTRINSIC
static constexpr void
1515 _S_masked_assign(_SveMaskWrapper<_Bits, _Np> __k, _SveSimdWrapper<_Tp, _Np>& __lhs,
1516 __type_identity_t<_SveSimdWrapper<_Tp, _Np>> __rhs)
1517 { __lhs = _CommonImpl::_S_blend(__k, __lhs, __rhs); }
1519 template <
typename _Tp,
size_t _Bits,
size_t _Np>
1520 _GLIBCXX_SIMD_INTRINSIC
static constexpr void
1521 _S_masked_assign(_SveMaskWrapper<_Bits, _Np> __k, _SveSimdWrapper<_Tp, _Np>& __lhs,
1522 __type_identity_t<_Tp> __rhs)
1523 { __lhs = _CommonImpl::_S_blend(__k, __lhs, __data(simd<_Tp, _Abi>(__rhs))); }
1525 template <
typename _Op,
typename _Tp,
size_t _Bits,
size_t _Np>
1526 _GLIBCXX_SIMD_INTRINSIC
static constexpr void
1527 _S_masked_cassign(
const _SveMaskWrapper<_Bits, _Np> __k, _SveSimdWrapper<_Tp, _Np>& __lhs,
1528 const __type_identity_t<_SveSimdWrapper<_Tp, _Np>> __rhs, _Op __op)
1530 __lhs = _CommonImpl::_S_blend(__k, __lhs,
1531 _SveSimdWrapper<_Tp, _Np>(__op(_SuperImpl{}, __lhs, __rhs)));
1534 template <
typename _Op,
typename _Tp,
size_t _Bits,
size_t _Np>
1535 _GLIBCXX_SIMD_INTRINSIC
static constexpr void
1536 _S_masked_cassign(
const _SveMaskWrapper<_Bits, _Np> __k, _SveSimdWrapper<_Tp, _Np>& __lhs,
1537 const __type_identity_t<_Tp> __rhs, _Op __op)
1538 { _S_masked_cassign(__k, __lhs, _S_broadcast(__rhs), __op); }
1540 template <
typename _Tp,
size_t _Np,
typename _Up>
1541 _GLIBCXX_SIMD_INTRINSIC
static constexpr void
1542 _S_set(_SveSimdWrapper<_Tp, _Np>& __v,
int __i, _Up&& __x)
noexcept
1543 { __v._M_set(__i,
static_cast<_Up&&
>(__x)); }
1545 template <
template <
typename>
class _Op,
typename _Tp,
size_t _Bits,
size_t _Np>
1546 _GLIBCXX_SIMD_INTRINSIC
static constexpr _SveSimdWrapper<_Tp, _Np>
1547 _S_masked_unary(
const _SveMaskWrapper<_Bits, _Np> __k,
const _SveSimdWrapper<_Tp, _Np> __v)
1549 auto __vv = simd<_Tp, _Abi>{__private_init, __v};
1550 _Op<
decltype(__vv)> __op;
1551 return _CommonImpl::_S_blend(__k, __v, __data(__op(__vv)));
1555template <
typename _Abi,
typename>
1558 template <
typename _Tp>
1559 using _MaskMember =
typename _Abi::template _MaskMember<_Tp>;
1561 template <
typename _Tp>
1562 using _TypeTag = _Tp*;
1564 template <
typename _Tp>
1565 static constexpr size_t _S_size = simd_size_v<_Tp, _Abi>;
1567 template <
typename _Tp>
1568 _GLIBCXX_SIMD_INTRINSIC
static constexpr _MaskMember<_Tp>
1569 _S_broadcast(
bool __x)
1571 constexpr size_t _Np = simd_size_v<_Tp, _Abi>;
1572 __sve_bool_type __tr = __sve_vector_type<_Tp, _Np>::__sve_active_mask();
1573 __sve_bool_type __fl = svpfalse_b();
1574 return __x ? __tr : __fl;
1577 template <
typename _Tp>
1578 _GLIBCXX_SIMD_INTRINSIC
static constexpr _MaskMember<_Tp>
1579 _S_load(
const bool* __mem)
1581 constexpr size_t _Np = simd_size_v<_Tp, _Abi>;
1582 const uint8_t* __p =
reinterpret_cast<const uint8_t*
>(__mem);
1583 __sve_bool_type __u8_active_mask = __sve_vector_type<uint8_t, _Np>::__sve_active_mask();
1584 __sve_vector_type_t<uint8_t, _Np> __u8_vec_mask_load = svld1(__u8_active_mask, __p);
1585 __sve_bool_type __u8_mask = svcmpne(__u8_active_mask, __u8_vec_mask_load, 0);
1587 __sve_bool_type __tp_mask = __u8_mask;
1588 for (
size_t __up_size = 1; __up_size !=
sizeof(_Tp); __up_size *= 2)
1590 __tp_mask = svunpklo(__tp_mask);
1593 _SveMaskWrapper<
sizeof(_Tp), simd_size_v<_Tp, _Abi>> __r{__tp_mask};
1597 template <
size_t _Bits,
size_t _Np>
1598 static inline _SveMaskWrapper<_Bits, _Np>
1599 _S_masked_load(_SveMaskWrapper<_Bits, _Np> __merge, _SveMaskWrapper<_Bits, _Np> __mask,
1600 const bool* __mem)
noexcept
1602 _SveMaskWrapper<_Bits, _Np> __r;
1604 __execute_n_times<_Np>([&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
1606 __r._M_set(__i, __mem[__i]);
1608 __r._M_set(__i, __merge[__i]);
1614 template <
size_t _Bits,
size_t _Np>
1615 _GLIBCXX_SIMD_INTRINSIC
static constexpr void
1616 _S_store(_SveMaskWrapper<_Bits, _Np> __v,
bool* __mem)
noexcept
1618 __execute_n_times<_Np>([&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
1619 __mem[__i] = __v[__i];
1623 template <
size_t _Bits,
size_t _Np>
1624 _GLIBCXX_SIMD_INTRINSIC
static constexpr void
1625 _S_masked_store(
const _SveMaskWrapper<_Bits, _Np> __v,
bool* __mem,
1626 const _SveMaskWrapper<_Bits, _Np> __k)
noexcept
1628 __execute_n_times<_Np>([&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
1630 __mem[__i] = __v[__i];
1634 template <
size_t _Bits,
size_t _Np>
1635 _GLIBCXX_SIMD_INTRINSIC
static constexpr _SanitizedBitMask<_Np>
1636 _S_to_bits(_SveMaskWrapper<_Bits, _Np> __x)
1639 __execute_n_times<_Np>([&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
1640 __r |= _ULLong(__x[__i]) << __i;
1645 template <
size_t _Np,
typename _Tp>
1646 _GLIBCXX_SIMD_INTRINSIC
static _MaskMember<_Tp>
1647 _S_from_bitmask(_SanitizedBitMask<_Np> __bits, _TypeTag<_Tp>)
1649 _SveMaskWrapper<
sizeof(_Tp), _Np> __r;
1650 __execute_n_times<_Np>([&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
1651 __r._M_set(__i, __bits[__i]);
1656 template <
typename _Tp,
typename _Up,
typename _UAbi>
1657 _GLIBCXX_SIMD_INTRINSIC
static constexpr auto
1658 _S_convert(simd_mask<_Up, _UAbi> __x)
1660 using _R = _SveMaskWrapper<
sizeof(_Tp), simd_size_v<_Tp, _Abi>>;
1661 if constexpr (__is_scalar_abi<_UAbi>())
1663 _R __r{__sve_bool_type(svpfalse())};
1664 __r._M_set(0, __data(__x));
1667 if constexpr (__is_sve_abi<_UAbi>())
1669 if constexpr (
sizeof(_Up) ==
sizeof(_Tp))
1671 if constexpr (
sizeof(_Up) <
sizeof(_Tp))
1673 __sve_bool_type __xmdata = __data(__x)._M_data;
1674 __sve_bool_type __r = __xmdata;
1675 for (
size_t __up_size =
sizeof(_Up); __up_size !=
sizeof(_Tp); __up_size *= 2)
1677 __r = svunpklo(__r);
1683 _R __r{__sve_bool_type(svpfalse())};
1684 constexpr size_t __min_size
1685 =
std::min(simd_size_v<_Tp, _Abi>, simd_mask<_Up, _UAbi>::size());
1686 __execute_n_times<__min_size>(
1687 [&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { __r._M_set(__i, __x[__i]); });
1691 if constexpr (__is_neon_abi<_UAbi>())
1693 _R __r{__sve_bool_type(svpfalse())};
1694 constexpr size_t __min_size
1695 =
std::min(simd_size_v<_Tp, _Abi>, simd_mask<_Up, _UAbi>::size());
1696 __execute_n_times<__min_size>(
1697 [&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA { __r._M_set(__i, __x[__i]); });
1700 if constexpr (__is_fixed_size_abi<_UAbi>())
1702 return _S_convert<_Tp>(__data(__x));
1707 template <
typename _Tp,
size_t _Np,
bool _Sanitized>
1708 _GLIBCXX_SIMD_INTRINSIC
static constexpr _MaskMember<_Tp>
1709 _S_convert(_BitMask<_Np, _Sanitized> __x)
1711 _MaskMember<_Tp> __r{};
1712 __execute_n_times<_Np>([&](
auto __i) _GLIBCXX_SIMD_ALWAYS_INLINE_LAMBDA {
1713 __r._M_set(__i, __x[__i]);
1718 template <
size_t _Bits,
size_t _Np>
1719 _GLIBCXX_SIMD_INTRINSIC
static constexpr _SveMaskWrapper<_Bits, _Np>
1720 _S_logical_and(
const _SveMaskWrapper<_Bits, _Np>& __x,
const _SveMaskWrapper<_Bits, _Np>& __y)
1722 return svand_z(_SveMaskWrapper<_Bits, _Np>::_BuiltinSveVectorType::__sve_active_mask(),
1723 __x._M_data, __y._M_data);
1726 template <
size_t _Bits,
size_t _Np>
1727 _GLIBCXX_SIMD_INTRINSIC
static constexpr _SveMaskWrapper<_Bits, _Np>
1728 _S_logical_or(
const _SveMaskWrapper<_Bits, _Np>& __x,
const _SveMaskWrapper<_Bits, _Np>& __y)
1730 return svorr_z(_SveMaskWrapper<_Bits, _Np>::_BuiltinSveVectorType::__sve_active_mask(),
1731 __x._M_data, __y._M_data);
1734 template <
size_t _Bits,
size_t _Np>
1735 _GLIBCXX_SIMD_INTRINSIC
static constexpr _SveMaskWrapper<_Bits, _Np>
1736 _S_bit_not(
const _SveMaskWrapper<_Bits, _Np>& __x)
1738 return svnot_z(_SveMaskWrapper<_Bits, _Np>::_BuiltinSveVectorType::__sve_active_mask(),
1742 template <
size_t _Bits,
size_t _Np>
1743 _GLIBCXX_SIMD_INTRINSIC
static constexpr _SveMaskWrapper<_Bits, _Np>
1744 _S_bit_and(
const _SveMaskWrapper<_Bits, _Np>& __x,
const _SveMaskWrapper<_Bits, _Np>& __y)
1746 return svand_z(_SveMaskWrapper<_Bits, _Np>::_BuiltinSveVectorType::__sve_active_mask(),
1747 __x._M_data, __y._M_data);
1750 template <
size_t _Bits,
size_t _Np>
1751 _GLIBCXX_SIMD_INTRINSIC
static constexpr _SveMaskWrapper<_Bits, _Np>
1752 _S_bit_or(
const _SveMaskWrapper<_Bits, _Np>& __x,
const _SveMaskWrapper<_Bits, _Np>& __y)
1754 return svorr_z(_SveMaskWrapper<_Bits, _Np>::_BuiltinSveVectorType::__sve_active_mask(),
1755 __x._M_data, __y._M_data);
1758 template <
size_t _Bits,
size_t _Np>
1759 _GLIBCXX_SIMD_INTRINSIC
static constexpr _SveMaskWrapper<_Bits, _Np>
1760 _S_bit_xor(
const _SveMaskWrapper<_Bits, _Np>& __x,
const _SveMaskWrapper<_Bits, _Np>& __y)
1762 return sveor_z(_SveMaskWrapper<_Bits, _Np>::_BuiltinSveVectorType::__sve_active_mask(),
1763 __x._M_data, __y._M_data);
1766 template <
size_t _Bits,
size_t _Np>
1767 static constexpr void
1768 _S_set(_SveMaskWrapper<_Bits, _Np>& __k,
int __i,
bool __x)
noexcept
1770 auto __index = svcmpeq(_SveMaskWrapper<_Bits, _Np>::_BuiltinSveVectorType::__sve_active_mask(),
1771 __sve_mask_type<_Bits>::__index0123,
1772 typename __sve_mask_type<_Bits>::__sve_mask_uint_type(__i));
1774 __k._M_data = svorr_z(_SveMaskWrapper<_Bits, _Np>::_BuiltinSveVectorType::__sve_active_mask(),
1775 __k._M_data, __index);
1777 __k._M_data = svbic_z(_SveMaskWrapper<_Bits, _Np>::_BuiltinSveVectorType::__sve_active_mask(),
1778 __k._M_data, __index);
1781 template <
size_t _Bits,
size_t _Np>
1782 _GLIBCXX_SIMD_INTRINSIC
static void
1783 _S_masked_assign(_SveMaskWrapper<_Bits, _Np> __k, _SveMaskWrapper<_Bits, _Np>& __lhs,
1784 _SveMaskWrapper<_Bits, _Np> __rhs)
1785 { __lhs._M_data = svsel(__k._M_data, __rhs._M_data, __lhs._M_data); }
1787 template <
size_t _Bits,
size_t _Np>
1788 _GLIBCXX_SIMD_INTRINSIC
static void
1789 _S_masked_assign(_SveMaskWrapper<_Bits, _Np> __k, _SveMaskWrapper<_Bits, _Np>& __lhs,
1793 = svsel(__k._M_data, _S_broadcast<__int_with_sizeof_t<_Bits>>(__rhs), __lhs._M_data);
1796 template <
typename _Tp>
1797 _GLIBCXX_SIMD_INTRINSIC
static int
1798 _S_popcount(simd_mask<_Tp, _Abi> __k)
1800 constexpr size_t _Np = simd_size_v<_Tp, _Abi>;
1802 return __sve_mask_type<
sizeof(_Tp)>::__sve_mask_active_count(
1803 __sve_vector_type<_Tp, _Np>::__sve_active_mask(), __k._M_data);
1806 template <
typename _Tp>
1807 _GLIBCXX_SIMD_INTRINSIC
static bool
1808 _S_all_of(simd_mask<_Tp, _Abi> __k)
1809 {
return _S_popcount(__k) == simd_size_v<_Tp, _Abi>; }
1811 template <
typename _Tp>
1812 _GLIBCXX_SIMD_INTRINSIC
static bool
1813 _S_any_of(simd_mask<_Tp, _Abi> __k)
1815 return svptest_any(__sve_vector_type<_Tp, simd_size_v<_Tp, _Abi>>::__sve_active_mask(),
1819 template <
typename _Tp>
1820 _GLIBCXX_SIMD_INTRINSIC
static bool
1821 _S_none_of(simd_mask<_Tp, _Abi> __k)
1823 return !svptest_any(__sve_vector_type<_Tp, simd_size_v<_Tp, _Abi>>::__sve_active_mask(),
1827 template <
typename _Tp>
1828 _GLIBCXX_SIMD_INTRINSIC
static bool
1829 _S_some_of(simd_mask<_Tp, _Abi> __k)
1831 int __msk_count = _S_popcount(__k);
1832 return (__msk_count > 0) && (__msk_count < (int) simd_size_v<_Tp, _Abi>);
1835 template <
typename _Tp>
1836 _GLIBCXX_SIMD_INTRINSIC
static int
1837 _S_find_first_set(simd_mask<_Tp, _Abi> __k)
1839 return svclastb(svpfirst(__k._M_data, svpfalse()),
1840 -1, __sve_mask_type<
sizeof(_Tp)>::__index0123);
1843 template <
typename _Tp>
1844 _GLIBCXX_SIMD_INTRINSIC
static int
1845 _S_find_last_set(simd_mask<_Tp, _Abi> __k)
1846 {
return svclastb(__k._M_data, -1, __sve_mask_type<
sizeof(_Tp)>::__index0123); }
1849_GLIBCXX_SIMD_END_NAMESPACE
__bool_constant< true > true_type
The type used as a compile-time boolean with true value.
typename enable_if< _Cond, _Tp >::type enable_if_t
Alias template for enable_if.
_Tp * begin(valarray< _Tp > &__va) noexcept
Return an iterator pointing to the first element of the valarray.
constexpr const _Tp & min(const _Tp &, const _Tp &)
This does what you think it does.