1 // -*- C++ -*- 2 //===----------------------------------------------------------------------===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H 11 #define _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H 12 13 #include <__assert> 14 #include <__config> 15 #include <__cstddef/size_t.h> 16 #include <__type_traits/integral_constant.h> 17 #include <experimental/__simd/declaration.h> 18 #include <experimental/__simd/traits.h> 19 20 #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) 21 22 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL 23 inline namespace parallelism_v2 { 24 namespace simd_abi { 25 struct __scalar { 26 static constexpr size_t __simd_size = 1; 27 }; 28 } // namespace simd_abi 29 30 template <> 31 inline constexpr bool is_abi_tag_v<simd_abi::__scalar> = true; 32 33 template <class _Tp> 34 struct __simd_storage<_Tp, simd_abi::__scalar> { 35 _Tp __data; 36 37 _LIBCPP_HIDE_FROM_ABI _Tp __get([[maybe_unused]] size_t __idx) const noexcept { 38 _LIBCPP_ASSERT_UNCATEGORIZED(__idx == 0, "Index is out of bounds"); 39 return __data; 40 } 41 _LIBCPP_HIDE_FROM_ABI void __set([[maybe_unused]] size_t __idx, _Tp __v) noexcept { 42 _LIBCPP_ASSERT_UNCATEGORIZED(__idx == 0, "Index is out of bounds"); 43 __data = __v; 44 } 45 }; 46 47 template <class _Tp> 48 struct __mask_storage<_Tp, simd_abi::__scalar> : __simd_storage<bool, simd_abi::__scalar> {}; 49 50 template <class _Tp> 51 struct __simd_operations<_Tp, simd_abi::__scalar> { 52 using _SimdStorage _LIBCPP_NODEBUG = __simd_storage<_Tp, simd_abi::__scalar>; 53 using _MaskStorage _LIBCPP_NODEBUG = __mask_storage<_Tp, simd_abi::__scalar>; 54 55 static _LIBCPP_HIDE_FROM_ABI _SimdStorage __broadcast(_Tp __v) noexcept { return {__v}; } 56 57 template <class _Generator> 58 static _LIBCPP_HIDE_FROM_ABI _SimdStorage __generate(_Generator&& __g) noexcept { 59 return {__g(std::integral_constant<size_t, 0>())}; 60 } 61 62 template <class _Up> 63 static _LIBCPP_HIDE_FROM_ABI void __load(_SimdStorage& __s, const _Up* __mem) noexcept { 64 __s.__data = static_cast<_Tp>(__mem[0]); 65 } 66 67 template <class _Up> 68 static _LIBCPP_HIDE_FROM_ABI void __store(_SimdStorage __s, _Up* __mem) noexcept { 69 *__mem = static_cast<_Up>(__s.__data); 70 } 71 72 static _LIBCPP_HIDE_FROM_ABI void __increment(_SimdStorage& __s) noexcept { ++__s.__data; } 73 74 static _LIBCPP_HIDE_FROM_ABI void __decrement(_SimdStorage& __s) noexcept { --__s.__data; } 75 76 static _LIBCPP_HIDE_FROM_ABI _MaskStorage __negate(_SimdStorage __s) noexcept { return {!__s.__data}; } 77 78 static _LIBCPP_HIDE_FROM_ABI _SimdStorage __bitwise_not(_SimdStorage __s) noexcept { 79 return {static_cast<_Tp>(~__s.__data)}; 80 } 81 82 static _LIBCPP_HIDE_FROM_ABI _SimdStorage __unary_minus(_SimdStorage __s) noexcept { 83 return {static_cast<_Tp>(-__s.__data)}; 84 } 85 }; 86 87 template <class _Tp> 88 struct __mask_operations<_Tp, simd_abi::__scalar> { 89 using _MaskStorage _LIBCPP_NODEBUG = __mask_storage<_Tp, simd_abi::__scalar>; 90 91 static _LIBCPP_HIDE_FROM_ABI _MaskStorage __broadcast(bool __v) noexcept { return {__v}; } 92 93 static _LIBCPP_HIDE_FROM_ABI void __load(_MaskStorage& __s, const bool* __mem) noexcept { __s.__data = __mem[0]; } 94 95 static _LIBCPP_HIDE_FROM_ABI void __store(_MaskStorage __s, bool* __mem) noexcept { __mem[0] = __s.__data; } 96 }; 97 98 } // namespace parallelism_v2 99 _LIBCPP_END_NAMESPACE_EXPERIMENTAL 100 101 #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) 102 #endif // _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H 103