10e30dd44SZhangyin // -*- C++ -*- 20e30dd44SZhangyin //===----------------------------------------------------------------------===// 30e30dd44SZhangyin // 40e30dd44SZhangyin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50e30dd44SZhangyin // See https://llvm.org/LICENSE.txt for license information. 60e30dd44SZhangyin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70e30dd44SZhangyin // 80e30dd44SZhangyin //===----------------------------------------------------------------------===// 90e30dd44SZhangyin 100e30dd44SZhangyin #ifndef _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H 110e30dd44SZhangyin #define _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H 120e30dd44SZhangyin 1337dca605SLouis Dionne #include <__assert> 14118f120eSLouis Dionne #include <__config> 15e99c4906SNikolas Klauser #include <__cstddef/size_t.h> 16d6832a61SLouis Dionne #include <__type_traits/integral_constant.h> 1750ae0da0SNikolas Klauser #include <experimental/__simd/declaration.h> 181314e877Sphilnik777 #include <experimental/__simd/traits.h> 190e30dd44SZhangyin 200e30dd44SZhangyin #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) 210e30dd44SZhangyin 220e30dd44SZhangyin _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL 230e30dd44SZhangyin inline namespace parallelism_v2 { 240e30dd44SZhangyin namespace simd_abi { 250e30dd44SZhangyin struct __scalar { 260e30dd44SZhangyin static constexpr size_t __simd_size = 1; 270e30dd44SZhangyin }; 280e30dd44SZhangyin } // namespace simd_abi 29e7a45c6dSZhangyin 301314e877Sphilnik777 template <> 311314e877Sphilnik777 inline constexpr bool is_abi_tag_v<simd_abi::__scalar> = true; 321314e877Sphilnik777 33e7a45c6dSZhangyin template <class _Tp> 34e7a45c6dSZhangyin struct __simd_storage<_Tp, simd_abi::__scalar> { 35e7a45c6dSZhangyin _Tp __data; 36e7a45c6dSZhangyin 37cf31d0ecSZhangYin _LIBCPP_HIDE_FROM_ABI _Tp __get([[maybe_unused]] size_t __idx) const noexcept { 38e7a45c6dSZhangyin _LIBCPP_ASSERT_UNCATEGORIZED(__idx == 0, "Index is out of bounds"); 39e7a45c6dSZhangyin return __data; 40e7a45c6dSZhangyin } 41cf31d0ecSZhangYin _LIBCPP_HIDE_FROM_ABI void __set([[maybe_unused]] size_t __idx, _Tp __v) noexcept { 42e7a45c6dSZhangyin _LIBCPP_ASSERT_UNCATEGORIZED(__idx == 0, "Index is out of bounds"); 43e7a45c6dSZhangyin __data = __v; 44e7a45c6dSZhangyin } 45e7a45c6dSZhangyin }; 46e7a45c6dSZhangyin 47e7a45c6dSZhangyin template <class _Tp> 48e7a45c6dSZhangyin struct __mask_storage<_Tp, simd_abi::__scalar> : __simd_storage<bool, simd_abi::__scalar> {}; 49e7a45c6dSZhangyin 50e7a45c6dSZhangyin template <class _Tp> 51e7a45c6dSZhangyin struct __simd_operations<_Tp, simd_abi::__scalar> { 52*f6958523SNikolas Klauser using _SimdStorage _LIBCPP_NODEBUG = __simd_storage<_Tp, simd_abi::__scalar>; 53*f6958523SNikolas Klauser using _MaskStorage _LIBCPP_NODEBUG = __mask_storage<_Tp, simd_abi::__scalar>; 54ed29f275SZhangyin 55cf31d0ecSZhangYin static _LIBCPP_HIDE_FROM_ABI _SimdStorage __broadcast(_Tp __v) noexcept { return {__v}; } 56593521b0SZhangYin 57593521b0SZhangYin template <class _Generator> 58593521b0SZhangYin static _LIBCPP_HIDE_FROM_ABI _SimdStorage __generate(_Generator&& __g) noexcept { 59593521b0SZhangYin return {__g(std::integral_constant<size_t, 0>())}; 60593521b0SZhangYin } 616bb5c989SZhangYin 626bb5c989SZhangYin template <class _Up> 636bb5c989SZhangYin static _LIBCPP_HIDE_FROM_ABI void __load(_SimdStorage& __s, const _Up* __mem) noexcept { 646bb5c989SZhangYin __s.__data = static_cast<_Tp>(__mem[0]); 656bb5c989SZhangYin } 66058e4454SZhangYin 67058e4454SZhangYin template <class _Up> 68058e4454SZhangYin static _LIBCPP_HIDE_FROM_ABI void __store(_SimdStorage __s, _Up* __mem) noexcept { 69058e4454SZhangYin *__mem = static_cast<_Up>(__s.__data); 70058e4454SZhangYin } 712c3d7d53SZhangYin 722c3d7d53SZhangYin static _LIBCPP_HIDE_FROM_ABI void __increment(_SimdStorage& __s) noexcept { ++__s.__data; } 732c3d7d53SZhangYin 742c3d7d53SZhangYin static _LIBCPP_HIDE_FROM_ABI void __decrement(_SimdStorage& __s) noexcept { --__s.__data; } 752c3d7d53SZhangYin 762c3d7d53SZhangYin static _LIBCPP_HIDE_FROM_ABI _MaskStorage __negate(_SimdStorage __s) noexcept { return {!__s.__data}; } 772c3d7d53SZhangYin 782c3d7d53SZhangYin static _LIBCPP_HIDE_FROM_ABI _SimdStorage __bitwise_not(_SimdStorage __s) noexcept { 792c3d7d53SZhangYin return {static_cast<_Tp>(~__s.__data)}; 802c3d7d53SZhangYin } 812c3d7d53SZhangYin 822c3d7d53SZhangYin static _LIBCPP_HIDE_FROM_ABI _SimdStorage __unary_minus(_SimdStorage __s) noexcept { 832c3d7d53SZhangYin return {static_cast<_Tp>(-__s.__data)}; 842c3d7d53SZhangYin } 85e7a45c6dSZhangyin }; 86e7a45c6dSZhangyin 87e7a45c6dSZhangyin template <class _Tp> 88e7a45c6dSZhangyin struct __mask_operations<_Tp, simd_abi::__scalar> { 89*f6958523SNikolas Klauser using _MaskStorage _LIBCPP_NODEBUG = __mask_storage<_Tp, simd_abi::__scalar>; 90ed29f275SZhangyin 91cf31d0ecSZhangYin static _LIBCPP_HIDE_FROM_ABI _MaskStorage __broadcast(bool __v) noexcept { return {__v}; } 926bb5c989SZhangYin 936bb5c989SZhangYin static _LIBCPP_HIDE_FROM_ABI void __load(_MaskStorage& __s, const bool* __mem) noexcept { __s.__data = __mem[0]; } 94058e4454SZhangYin 95058e4454SZhangYin static _LIBCPP_HIDE_FROM_ABI void __store(_MaskStorage __s, bool* __mem) noexcept { __mem[0] = __s.__data; } 96e7a45c6dSZhangyin }; 97e7a45c6dSZhangyin 980e30dd44SZhangyin } // namespace parallelism_v2 990e30dd44SZhangyin _LIBCPP_END_NAMESPACE_EXPERIMENTAL 1000e30dd44SZhangyin 1010e30dd44SZhangyin #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) 1020e30dd44SZhangyin #endif // _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H 103