[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / libcxx / include / experimental / __simd / simd.h
blobdb4ebb8e4a381bb05f49c041c4863a5c09fc9fbb
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-exception
7 //
8 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H
11 #define _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H
13 #include <__type_traits/is_same.h>
14 #include <__type_traits/remove_cvref.h>
15 #include <__utility/forward.h>
16 #include <cstddef>
17 #include <experimental/__config>
18 #include <experimental/__simd/declaration.h>
19 #include <experimental/__simd/reference.h>
20 #include <experimental/__simd/traits.h>
21 #include <experimental/__simd/utility.h>
23 #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
25 _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL
26 inline namespace parallelism_v2 {
28 // class template simd [simd.class]
29 // TODO: implement simd class
30 template <class _Tp, class _Abi>
31 class simd {
32 using _Impl = __simd_operations<_Tp, _Abi>;
33 using _Storage = typename _Impl::_SimdStorage;
35 _Storage __s_;
37 public:
38 using value_type = _Tp;
39 using reference = __simd_reference<_Tp, _Storage, value_type>;
40 using mask_type = simd_mask<_Tp, _Abi>;
41 using abi_type = _Abi;
43 static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return simd_size_v<value_type, abi_type>; }
45 _LIBCPP_HIDE_FROM_ABI simd() noexcept = default;
47 // broadcast constructor
48 template <class _Up, enable_if_t<__can_broadcast_v<value_type, __remove_cvref_t<_Up>>, int> = 0>
49 _LIBCPP_HIDE_FROM_ABI simd(_Up&& __v) noexcept : __s_(_Impl::__broadcast(static_cast<value_type>(__v))) {}
51 // implicit type conversion constructor
52 template <class _Up,
53 enable_if_t<!is_same_v<_Up, _Tp> && is_same_v<abi_type, simd_abi::fixed_size<size()>> &&
54 __is_non_narrowing_convertible_v<_Up, value_type>,
55 int> = 0>
56 _LIBCPP_HIDE_FROM_ABI simd(const simd<_Up, simd_abi::fixed_size<size()>>& __v) noexcept {
57 for (size_t __i = 0; __i < size(); __i++) {
58 (*this)[__i] = static_cast<value_type>(__v[__i]);
62 // generator constructor
63 template <class _Generator, enable_if_t<__can_generate_v<value_type, _Generator, size()>, int> = 0>
64 explicit _LIBCPP_HIDE_FROM_ABI simd(_Generator&& __g) noexcept
65 : __s_(_Impl::__generate(std::forward<_Generator>(__g))) {}
67 // load constructor
68 template <class _Up, class _Flags, enable_if_t<__is_vectorizable_v<_Up> && is_simd_flag_type_v<_Flags>, int> = 0>
69 _LIBCPP_HIDE_FROM_ABI simd(const _Up* __mem, _Flags) {
70 _Impl::__load(__s_, _Flags::template __apply<simd>(__mem));
73 // scalar access [simd.subscr]
74 _LIBCPP_HIDE_FROM_ABI reference operator[](size_t __i) noexcept { return reference(__s_, __i); }
75 _LIBCPP_HIDE_FROM_ABI value_type operator[](size_t __i) const noexcept { return __s_.__get(__i); }
78 template <class _Tp, class _Abi>
79 inline constexpr bool is_simd_v<simd<_Tp, _Abi>> = true;
81 template <class _Tp>
82 using native_simd = simd<_Tp, simd_abi::native<_Tp>>;
84 template <class _Tp, int _Np>
85 using fixed_size_simd = simd<_Tp, simd_abi::fixed_size<_Np>>;
87 } // namespace parallelism_v2
88 _LIBCPP_END_NAMESPACE_EXPERIMENTAL
90 #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
91 #endif // _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H