xref: /llvm-project/libcxx/include/experimental/__simd/scalar.h (revision f69585235ec85d54e0f3fc41b2d5700430907f99)
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