xref: /freebsd-src/contrib/llvm-project/libcxx/include/experimental/__simd/simd_mask.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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_SIMD_MASK_H
115f757f3fSDimitry Andric #define _LIBCPP_EXPERIMENTAL___SIMD_SIMD_MASK_H
125f757f3fSDimitry Andric 
135f757f3fSDimitry Andric #include <__type_traits/is_same.h>
145f757f3fSDimitry Andric #include <cstddef>
155f757f3fSDimitry Andric #include <experimental/__config>
165f757f3fSDimitry Andric #include <experimental/__simd/declaration.h>
175f757f3fSDimitry Andric #include <experimental/__simd/reference.h>
185f757f3fSDimitry Andric #include <experimental/__simd/traits.h>
195f757f3fSDimitry Andric 
205f757f3fSDimitry Andric #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
215f757f3fSDimitry Andric 
225f757f3fSDimitry Andric _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
235f757f3fSDimitry Andric inline namespace parallelism_v2 {
245f757f3fSDimitry Andric 
255f757f3fSDimitry Andric // class template simd_mask [simd.mask.class]
265f757f3fSDimitry Andric // TODO: implement simd_mask class
275f757f3fSDimitry Andric template <class _Tp, class _Abi>
285f757f3fSDimitry Andric class simd_mask {
295f757f3fSDimitry Andric   using _Impl    = __mask_operations<_Tp, _Abi>;
305f757f3fSDimitry Andric   using _Storage = typename _Impl::_MaskStorage;
315f757f3fSDimitry Andric 
325f757f3fSDimitry Andric   _Storage __s_;
335f757f3fSDimitry Andric 
345f757f3fSDimitry Andric public:
355f757f3fSDimitry Andric   using value_type = bool;
365f757f3fSDimitry Andric   using reference  = __simd_reference<_Tp, _Storage, value_type>;
375f757f3fSDimitry Andric   using simd_type  = simd<_Tp, _Abi>;
385f757f3fSDimitry Andric   using abi_type   = _Abi;
395f757f3fSDimitry Andric 
405f757f3fSDimitry Andric   static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return simd_type::size(); }
415f757f3fSDimitry Andric 
425f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI simd_mask() noexcept = default;
435f757f3fSDimitry Andric 
445f757f3fSDimitry Andric   // broadcast constructor
455f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI explicit simd_mask(value_type __v) noexcept : __s_(_Impl::__broadcast(__v)) {}
465f757f3fSDimitry Andric 
475f757f3fSDimitry Andric   // implicit type conversion constructor
485f757f3fSDimitry Andric   template <class _Up, enable_if_t<!is_same_v<_Up, _Tp> && is_same_v<abi_type, simd_abi::fixed_size<size()>>, int> = 0>
495f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI simd_mask(const simd_mask<_Up, simd_abi::fixed_size<size()>>& __v) noexcept {
505f757f3fSDimitry Andric     for (size_t __i = 0; __i < size(); __i++) {
515f757f3fSDimitry Andric       (*this)[__i] = __v[__i];
525f757f3fSDimitry Andric     }
535f757f3fSDimitry Andric   }
545f757f3fSDimitry Andric 
557a6dacacSDimitry Andric   // load constructor
567a6dacacSDimitry Andric   template <class _Flags, enable_if_t<is_simd_flag_type_v<_Flags>, int> = 0>
577a6dacacSDimitry Andric   _LIBCPP_HIDE_FROM_ABI simd_mask(const value_type* __mem, _Flags) {
587a6dacacSDimitry Andric     _Impl::__load(__s_, _Flags::template __apply<simd_mask>(__mem));
597a6dacacSDimitry Andric   }
607a6dacacSDimitry Andric 
61*0fca6ea1SDimitry Andric   // copy functions
62*0fca6ea1SDimitry Andric   template <class _Flags, enable_if_t<is_simd_flag_type_v<_Flags>, int> = 0>
63*0fca6ea1SDimitry Andric   _LIBCPP_HIDE_FROM_ABI void copy_from(const value_type* __mem, _Flags) {
64*0fca6ea1SDimitry Andric     _Impl::__load(__s_, _Flags::template __apply<simd_mask>(__mem));
65*0fca6ea1SDimitry Andric   }
66*0fca6ea1SDimitry Andric 
67*0fca6ea1SDimitry Andric   template <class _Flags, enable_if_t<is_simd_flag_type_v<_Flags>, int> = 0>
68*0fca6ea1SDimitry Andric   _LIBCPP_HIDE_FROM_ABI void copy_to(value_type* __mem, _Flags) const {
69*0fca6ea1SDimitry Andric     _Impl::__store(__s_, _Flags::template __apply<simd_mask>(__mem));
70*0fca6ea1SDimitry Andric   }
71*0fca6ea1SDimitry Andric 
725f757f3fSDimitry Andric   // scalar access [simd.mask.subscr]
735f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI reference operator[](size_t __i) noexcept { return reference(__s_, __i); }
745f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI value_type operator[](size_t __i) const noexcept { return __s_.__get(__i); }
755f757f3fSDimitry Andric };
765f757f3fSDimitry Andric 
775f757f3fSDimitry Andric template <class _Tp, class _Abi>
785f757f3fSDimitry Andric inline constexpr bool is_simd_mask_v<simd_mask<_Tp, _Abi>> = true;
795f757f3fSDimitry Andric 
805f757f3fSDimitry Andric template <class _Tp>
815f757f3fSDimitry Andric using native_simd_mask = simd_mask<_Tp, simd_abi::native<_Tp>>;
825f757f3fSDimitry Andric 
835f757f3fSDimitry Andric template <class _Tp, int _Np>
845f757f3fSDimitry Andric using fixed_size_simd_mask = simd_mask<_Tp, simd_abi::fixed_size<_Np>>;
855f757f3fSDimitry Andric 
865f757f3fSDimitry Andric } // namespace parallelism_v2
875f757f3fSDimitry Andric _LIBCPP_END_NAMESPACE_EXPERIMENTAL
885f757f3fSDimitry Andric 
895f757f3fSDimitry Andric #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
905f757f3fSDimitry Andric #endif // _LIBCPP_EXPERIMENTAL___SIMD_SIMD_MASK_H
91