1e78f53d1SNikolas Klauser // -*- C++ -*- 2e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===// 3e78f53d1SNikolas Klauser // 4e78f53d1SNikolas Klauser // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5e78f53d1SNikolas Klauser // See https://llvm.org/LICENSE.txt for license information. 6e78f53d1SNikolas Klauser // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7e78f53d1SNikolas Klauser // 8e78f53d1SNikolas Klauser //===----------------------------------------------------------------------===// 9e78f53d1SNikolas Klauser 10*ce777190SNikolas Klauser #ifndef _LIBCPP___CXX03_EXPERIMENTAL___SIMD_VEC_EXT_H 11*ce777190SNikolas Klauser #define _LIBCPP___CXX03_EXPERIMENTAL___SIMD_VEC_EXT_H 12e78f53d1SNikolas Klauser 1373fbae83SNikolas Klauser #include <__cxx03/__assert> 1473fbae83SNikolas Klauser #include <__cxx03/__bit/bit_ceil.h> 1573fbae83SNikolas Klauser #include <__cxx03/__utility/forward.h> 1673fbae83SNikolas Klauser #include <__cxx03/__utility/integer_sequence.h> 1773fbae83SNikolas Klauser #include <__cxx03/cstddef> 1873fbae83SNikolas Klauser #include <__cxx03/experimental/__config> 1973fbae83SNikolas Klauser #include <__cxx03/experimental/__simd/declaration.h> 2073fbae83SNikolas Klauser #include <__cxx03/experimental/__simd/traits.h> 2173fbae83SNikolas Klauser #include <__cxx03/experimental/__simd/utility.h> 22e78f53d1SNikolas Klauser 23e78f53d1SNikolas Klauser #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) 24e78f53d1SNikolas Klauser 25e78f53d1SNikolas Klauser _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL 26e78f53d1SNikolas Klauser inline namespace parallelism_v2 { 27e78f53d1SNikolas Klauser namespace simd_abi { 28e78f53d1SNikolas Klauser template <int _Np> 29e78f53d1SNikolas Klauser struct __vec_ext { 30e78f53d1SNikolas Klauser static constexpr size_t __simd_size = _Np; 31e78f53d1SNikolas Klauser }; 32e78f53d1SNikolas Klauser } // namespace simd_abi 33e78f53d1SNikolas Klauser 34e78f53d1SNikolas Klauser template <int _Np> 35e78f53d1SNikolas Klauser inline constexpr bool is_abi_tag_v<simd_abi::__vec_ext<_Np>> = _Np > 0 && _Np <= 32; 36e78f53d1SNikolas Klauser 37e78f53d1SNikolas Klauser template <class _Tp, int _Np> 38e78f53d1SNikolas Klauser struct __simd_storage<_Tp, simd_abi::__vec_ext<_Np>> { 39e78f53d1SNikolas Klauser _Tp __data __attribute__((__vector_size__(std::__bit_ceil((sizeof(_Tp) * _Np))))); 40e78f53d1SNikolas Klauser 41e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI _Tp __get(size_t __idx) const noexcept { 42e78f53d1SNikolas Klauser _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx >= 0 && __idx < _Np, "Index is out of bounds"); 43e78f53d1SNikolas Klauser return __data[__idx]; 44e78f53d1SNikolas Klauser } 45e78f53d1SNikolas Klauser _LIBCPP_HIDE_FROM_ABI void __set(size_t __idx, _Tp __v) noexcept { 46e78f53d1SNikolas Klauser _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx >= 0 && __idx < _Np, "Index is out of bounds"); 47e78f53d1SNikolas Klauser __data[__idx] = __v; 48e78f53d1SNikolas Klauser } 49e78f53d1SNikolas Klauser }; 50e78f53d1SNikolas Klauser 51e78f53d1SNikolas Klauser template <class _Tp, int _Np> 52e78f53d1SNikolas Klauser struct __mask_storage<_Tp, simd_abi::__vec_ext<_Np>> 53e78f53d1SNikolas Klauser : __simd_storage<decltype(experimental::__choose_mask_type<_Tp>()), simd_abi::__vec_ext<_Np>> {}; 54e78f53d1SNikolas Klauser 55e78f53d1SNikolas Klauser template <class _Tp, int _Np> 56e78f53d1SNikolas Klauser struct __simd_operations<_Tp, simd_abi::__vec_ext<_Np>> { 57e78f53d1SNikolas Klauser using _SimdStorage = __simd_storage<_Tp, simd_abi::__vec_ext<_Np>>; 58e78f53d1SNikolas Klauser using _MaskStorage = __mask_storage<_Tp, simd_abi::__vec_ext<_Np>>; 59e78f53d1SNikolas Klauser 60e78f53d1SNikolas Klauser static _LIBCPP_HIDE_FROM_ABI _SimdStorage __broadcast(_Tp __v) noexcept { 61e78f53d1SNikolas Klauser _SimdStorage __result; 62e78f53d1SNikolas Klauser for (int __i = 0; __i < _Np; ++__i) { 63e78f53d1SNikolas Klauser __result.__set(__i, __v); 64e78f53d1SNikolas Klauser } 65e78f53d1SNikolas Klauser return __result; 66e78f53d1SNikolas Klauser } 67e78f53d1SNikolas Klauser 68e78f53d1SNikolas Klauser template <class _Generator, size_t... _Is> 69e78f53d1SNikolas Klauser static _LIBCPP_HIDE_FROM_ABI _SimdStorage __generate_init(_Generator&& __g, std::index_sequence<_Is...>) { 70e78f53d1SNikolas Klauser return _SimdStorage{{__g(std::integral_constant<size_t, _Is>())...}}; 71e78f53d1SNikolas Klauser } 72e78f53d1SNikolas Klauser 73e78f53d1SNikolas Klauser template <class _Generator> 74e78f53d1SNikolas Klauser static _LIBCPP_HIDE_FROM_ABI _SimdStorage __generate(_Generator&& __g) noexcept { 75e78f53d1SNikolas Klauser return __generate_init(std::forward<_Generator>(__g), std::make_index_sequence<_Np>()); 76e78f53d1SNikolas Klauser } 77e78f53d1SNikolas Klauser 78e78f53d1SNikolas Klauser template <class _Up> 79e78f53d1SNikolas Klauser static _LIBCPP_HIDE_FROM_ABI void __load(_SimdStorage& __s, const _Up* __mem) noexcept { 80e78f53d1SNikolas Klauser for (size_t __i = 0; __i < _Np; __i++) 81e78f53d1SNikolas Klauser __s.__data[__i] = static_cast<_Tp>(__mem[__i]); 82e78f53d1SNikolas Klauser } 83e78f53d1SNikolas Klauser 84e78f53d1SNikolas Klauser template <class _Up> 85e78f53d1SNikolas Klauser static _LIBCPP_HIDE_FROM_ABI void __store(_SimdStorage __s, _Up* __mem) noexcept { 86e78f53d1SNikolas Klauser for (size_t __i = 0; __i < _Np; __i++) 87e78f53d1SNikolas Klauser __mem[__i] = static_cast<_Up>(__s.__data[__i]); 88e78f53d1SNikolas Klauser } 89e78f53d1SNikolas Klauser }; 90e78f53d1SNikolas Klauser 91e78f53d1SNikolas Klauser template <class _Tp, int _Np> 92e78f53d1SNikolas Klauser struct __mask_operations<_Tp, simd_abi::__vec_ext<_Np>> { 93e78f53d1SNikolas Klauser using _MaskStorage = __mask_storage<_Tp, simd_abi::__vec_ext<_Np>>; 94e78f53d1SNikolas Klauser 95e78f53d1SNikolas Klauser static _LIBCPP_HIDE_FROM_ABI _MaskStorage __broadcast(bool __v) noexcept { 96e78f53d1SNikolas Klauser _MaskStorage __result; 97e78f53d1SNikolas Klauser auto __all_bits_v = experimental::__set_all_bits<_Tp>(__v); 98e78f53d1SNikolas Klauser for (int __i = 0; __i < _Np; ++__i) { 99e78f53d1SNikolas Klauser __result.__set(__i, __all_bits_v); 100e78f53d1SNikolas Klauser } 101e78f53d1SNikolas Klauser return __result; 102e78f53d1SNikolas Klauser } 103e78f53d1SNikolas Klauser 104e78f53d1SNikolas Klauser static _LIBCPP_HIDE_FROM_ABI void __load(_MaskStorage& __s, const bool* __mem) noexcept { 105e78f53d1SNikolas Klauser for (size_t __i = 0; __i < _Np; __i++) 106e78f53d1SNikolas Klauser __s.__data[__i] = experimental::__set_all_bits<_Tp>(__mem[__i]); 107e78f53d1SNikolas Klauser } 108e78f53d1SNikolas Klauser 109e78f53d1SNikolas Klauser static _LIBCPP_HIDE_FROM_ABI void __store(_MaskStorage __s, bool* __mem) noexcept { 110e78f53d1SNikolas Klauser for (size_t __i = 0; __i < _Np; __i++) 111e78f53d1SNikolas Klauser __mem[__i] = static_cast<bool>(__s.__data[__i]); 112e78f53d1SNikolas Klauser } 113e78f53d1SNikolas Klauser }; 114e78f53d1SNikolas Klauser 115e78f53d1SNikolas Klauser } // namespace parallelism_v2 116e78f53d1SNikolas Klauser _LIBCPP_END_NAMESPACE_EXPERIMENTAL 117e78f53d1SNikolas Klauser 118e78f53d1SNikolas Klauser #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) 119*ce777190SNikolas Klauser #endif // _LIBCPP___CXX03_EXPERIMENTAL___SIMD_VEC_EXT_H 120