15f757f3fSDimitry Andric // -*- C++ -*- 25f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 35f757f3fSDimitry Andric // 45f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 55f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 65f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 75f757f3fSDimitry Andric // 85f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 95f757f3fSDimitry Andric 105f757f3fSDimitry Andric #ifndef _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H 115f757f3fSDimitry Andric #define _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H 125f757f3fSDimitry Andric 13*0fca6ea1SDimitry Andric #include <__assert> 145f757f3fSDimitry Andric #include <cstddef> 155f757f3fSDimitry Andric #include <experimental/__config> 16cb14a3feSDimitry Andric #include <experimental/__simd/declaration.h> 175f757f3fSDimitry Andric #include <experimental/__simd/traits.h> 185f757f3fSDimitry Andric 195f757f3fSDimitry Andric #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) 205f757f3fSDimitry Andric 215f757f3fSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL 225f757f3fSDimitry Andric inline namespace parallelism_v2 { 235f757f3fSDimitry Andric namespace simd_abi { 245f757f3fSDimitry Andric struct __scalar { 255f757f3fSDimitry Andric static constexpr size_t __simd_size = 1; 265f757f3fSDimitry Andric }; 275f757f3fSDimitry Andric } // namespace simd_abi 285f757f3fSDimitry Andric 295f757f3fSDimitry Andric template <> 305f757f3fSDimitry Andric inline constexpr bool is_abi_tag_v<simd_abi::__scalar> = true; 315f757f3fSDimitry Andric 325f757f3fSDimitry Andric template <class _Tp> 335f757f3fSDimitry Andric struct __simd_storage<_Tp, simd_abi::__scalar> { 345f757f3fSDimitry Andric _Tp __data; 355f757f3fSDimitry Andric 365f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp __get([[maybe_unused]] size_t __idx) const noexcept { 375f757f3fSDimitry Andric _LIBCPP_ASSERT_UNCATEGORIZED(__idx == 0, "Index is out of bounds"); 385f757f3fSDimitry Andric return __data; 395f757f3fSDimitry Andric } 405f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI void __set([[maybe_unused]] size_t __idx, _Tp __v) noexcept { 415f757f3fSDimitry Andric _LIBCPP_ASSERT_UNCATEGORIZED(__idx == 0, "Index is out of bounds"); 425f757f3fSDimitry Andric __data = __v; 435f757f3fSDimitry Andric } 445f757f3fSDimitry Andric }; 455f757f3fSDimitry Andric 465f757f3fSDimitry Andric template <class _Tp> 475f757f3fSDimitry Andric struct __mask_storage<_Tp, simd_abi::__scalar> : __simd_storage<bool, simd_abi::__scalar> {}; 485f757f3fSDimitry Andric 495f757f3fSDimitry Andric template <class _Tp> 505f757f3fSDimitry Andric struct __simd_operations<_Tp, simd_abi::__scalar> { 515f757f3fSDimitry Andric using _SimdStorage = __simd_storage<_Tp, simd_abi::__scalar>; 525f757f3fSDimitry Andric using _MaskStorage = __mask_storage<_Tp, simd_abi::__scalar>; 535f757f3fSDimitry Andric 545f757f3fSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _SimdStorage __broadcast(_Tp __v) noexcept { return {__v}; } 555f757f3fSDimitry Andric 565f757f3fSDimitry Andric template <class _Generator> 575f757f3fSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _SimdStorage __generate(_Generator&& __g) noexcept { 585f757f3fSDimitry Andric return {__g(std::integral_constant<size_t, 0>())}; 595f757f3fSDimitry Andric } 607a6dacacSDimitry Andric 617a6dacacSDimitry Andric template <class _Up> 627a6dacacSDimitry Andric static _LIBCPP_HIDE_FROM_ABI void __load(_SimdStorage& __s, const _Up* __mem) noexcept { 637a6dacacSDimitry Andric __s.__data = static_cast<_Tp>(__mem[0]); 647a6dacacSDimitry Andric } 65*0fca6ea1SDimitry Andric 66*0fca6ea1SDimitry Andric template <class _Up> 67*0fca6ea1SDimitry Andric static _LIBCPP_HIDE_FROM_ABI void __store(_SimdStorage __s, _Up* __mem) noexcept { 68*0fca6ea1SDimitry Andric *__mem = static_cast<_Up>(__s.__data); 69*0fca6ea1SDimitry Andric } 705f757f3fSDimitry Andric }; 715f757f3fSDimitry Andric 725f757f3fSDimitry Andric template <class _Tp> 735f757f3fSDimitry Andric struct __mask_operations<_Tp, simd_abi::__scalar> { 745f757f3fSDimitry Andric using _MaskStorage = __mask_storage<_Tp, simd_abi::__scalar>; 755f757f3fSDimitry Andric 765f757f3fSDimitry Andric static _LIBCPP_HIDE_FROM_ABI _MaskStorage __broadcast(bool __v) noexcept { return {__v}; } 777a6dacacSDimitry Andric 787a6dacacSDimitry Andric static _LIBCPP_HIDE_FROM_ABI void __load(_MaskStorage& __s, const bool* __mem) noexcept { __s.__data = __mem[0]; } 79*0fca6ea1SDimitry Andric 80*0fca6ea1SDimitry Andric static _LIBCPP_HIDE_FROM_ABI void __store(_MaskStorage __s, bool* __mem) noexcept { __mem[0] = __s.__data; } 815f757f3fSDimitry Andric }; 825f757f3fSDimitry Andric 835f757f3fSDimitry Andric } // namespace parallelism_v2 845f757f3fSDimitry Andric _LIBCPP_END_NAMESPACE_EXPERIMENTAL 855f757f3fSDimitry Andric 865f757f3fSDimitry Andric #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) 875f757f3fSDimitry Andric #endif // _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H 88