103 lines · c
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-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H11#define _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H12 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_EXPERIMENTAL23inline namespace parallelism_v2 {24namespace simd_abi {25struct __scalar {26 static constexpr size_t __simd_size = 1;27};28} // namespace simd_abi29 30template <>31inline constexpr bool is_abi_tag_v<simd_abi::__scalar> = true;32 33template <class _Tp>34struct __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 47template <class _Tp>48struct __mask_storage<_Tp, simd_abi::__scalar> : __simd_storage<bool, simd_abi::__scalar> {};49 50template <class _Tp>51struct __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 87template <class _Tp>88struct __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_v299_LIBCPP_END_NAMESPACE_EXPERIMENTAL100 101#endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)102#endif // _LIBCPP_EXPERIMENTAL___SIMD_SCALAR_H103