libstdc++-v3/ChangeLog:
* include/bits/simd_flags.h: New file.
Signed-off-by: Matthias Kretz <[email protected]>
---
libstdc++-v3/include/bits/simd_flags.h | 265 +++++++++++++++++++++++++
1 file changed, 265 insertions(+)
create mode 100644 libstdc++-v3/include/bits/simd_flags.h
--
──────────────────────────────────────────────────────────────────────────
Dr. Matthias Kretz https://mattkretz.github.io
GSI Helmholtz Center for Heavy Ion Research https://gsi.de
std::simd
──────────────────────────────────────────────────────────────────────────diff --git a/libstdc++-v3/include/bits/simd_flags.h b/libstdc++-v3/include/bits/simd_flags.h
new file mode 100644
index 00000000000..ea5e4ca147c
--- /dev/null
+++ b/libstdc++-v3/include/bits/simd_flags.h
@@ -0,0 +1,265 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later WITH GCC-exception-3.1 */
+/* Copyright © 2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
+ * Matthias Kretz <[email protected]>
+ */
+
+#ifndef _GLIBCXX_SIMD_FLAGS_H
+#define _GLIBCXX_SIMD_FLAGS_H 1
+
+#ifdef _GLIBCXX_SYSHDR
+#pragma GCC system_header
+#endif
+
+#if __cplusplus >= 202400L
+
+#include "simd_details.h"
+
+namespace std::simd
+{
+ // [simd.traits]
+ // --- alignment ---
+ template <typename _Tp, typename _Up = typename _Tp::value_type>
+ struct alignment
+ {};
+
+ template <size_t _Bytes, typename _Abi>
+ struct alignment<basic_mask<_Bytes, _Abi>, bool>
+ : integral_constant<size_t, alignof(basic_mask<_Bytes, _Abi>)>
+ {};
+
+ template <typename _Tp, typename _Abi, __vectorizable _Up>
+ struct alignment<basic_vec<_Tp, _Abi>, _Up>
+ : integral_constant<size_t, alignof(basic_vec<_Tp, _Abi>)>
+ {};
+
+ template <typename _Tp, typename _Up = typename _Tp::value_type>
+ constexpr size_t alignment_v = alignment<_Tp, _Up>::value;
+
+ // [simd.flags] -------------------------------------------------------------
+ struct _LoadStoreTag
+ {};
+
+ /** @internal
+ * <tt>struct convert-flag</tt>
+ *
+ * C++26 [simd.expos] / [simd.flags]
+ */
+ struct __convert_flag
+ : _LoadStoreTag
+ {};
+
+ /** @internal
+ * <tt>struct aligned-flag</tt>
+ *
+ * C++26 [simd.expos] / [simd.flags]
+ */
+ struct __aligned_flag
+ : _LoadStoreTag
+ {
+ template <typename _Tp, typename _Up>
+ [[__gnu__::__always_inline__]]
+ static constexpr _Up*
+ _S_adjust_pointer(_Up* __ptr)
+ {
+ if consteval
+ {
+ return __ptr;
+ }
+ else
+ {
+ return static_cast<_Up*>(__builtin_assume_aligned(__ptr, simd::alignment_v<_Tp, _Up>));
+ }
+ }
+ };
+
+ /** @internal
+ * <tt>template<size_t N> struct overaligned-flag</tt>
+ *
+ * @tparam _Np alignment in bytes
+ *
+ * C++26 [simd.expos] / [simd.flags]
+ */
+ template <size_t _Np>
+ struct __overaligned_flag
+ : _LoadStoreTag
+ {
+ static_assert(__has_single_bit(_Np));
+
+ template <typename, typename _Up>
+ [[__gnu__::__always_inline__]]
+ static constexpr _Up*
+ _S_adjust_pointer(_Up* __ptr)
+ {
+ if consteval
+ {
+ return __ptr;
+ }
+ else
+ {
+ return static_cast<_Up*>(__builtin_assume_aligned(__ptr, _Np));
+ }
+ }
+ };
+
+#if 0
+ template <typename _To>
+ struct __convert_to_flag
+ : _LoadStoreTag
+ { using type = _To; };
+
+ struct __partial_loadstore_flag
+ : _LoadStoreTag
+ {};
+
+ struct __throw_flag
+ : _LoadStoreTag
+ {};
+
+ struct __streaming_flag
+ : _LoadStoreTag
+ {};
+
+ template <int _L1, int _L2 /*, exclusive vs. shared*/>
+ struct __prefetch_flag
+ : _LoadStoreTag
+ {
+ template <typename, typename _Up>
+ [[__gnu__::__always_inline__]]
+ static _Up*
+ _S_adjust_pointer(_Up* __ptr)
+ {
+ // one read: 0, 0
+ // L1: 0, 1
+ // L2: 0, 2
+ // L3: 0, 3
+ // (exclusive cache line) for writing: 1, 0 / 1, 1
+ /* constexpr int __write = 1;
+ constexpr int __level = 0-3;
+ __builtin_prefetch(__ptr, __write, __level)
+ _mm_prefetch(reinterpret_cast<char const*>(__ptr), _MM_HINT_T0);
+ _mm_prefetch(reinterpret_cast<char const*>(__ptr), _MM_HINT_T1);
+ _mm_prefetch(reinterpret_cast<char const*>(__ptr), _MM_HINT_T2);
+ _mm_prefetch(reinterpret_cast<char const*>(__ptr), _MM_HINT_ET0);
+ _mm_prefetch(reinterpret_cast<char const*>(__ptr), _MM_HINT_ET1);
+ _mm_prefetch(reinterpret_cast<char const*>(__ptr), _MM_HINT_NTA);*/
+ return __ptr;
+ }
+ };
+#endif
+
+ template <typename _Tp>
+ concept __loadstore_tag = is_base_of_v<_LoadStoreTag, _Tp>;
+
+ template <typename...>
+ struct flags;
+
+ template <typename... _Traits>
+ requires (__loadstore_tag<_Traits> and ...)
+ struct flags<_Traits...>
+ {
+ consteval bool
+ _M_is_equal(flags) const
+ { return true; }
+
+ template <typename... _Other>
+ consteval bool
+ _M_is_equal(flags<_Other...> __y) const
+ { return same_as<flags<>, decltype(_M_xor(__y))>; }
+
+ template <typename... _Other>
+ consteval bool
+ _M_test(flags<_Other...> __x) const noexcept
+ { return __x._M_is_equal(_M_and(__x)); }
+
+ friend consteval auto
+ operator|(flags, flags<>)
+ { return flags{}; }
+
+ template <typename _T0, typename... _More>
+ friend consteval auto
+ operator|(flags, flags<_T0, _More...>)
+ {
+ if constexpr ((same_as<_Traits, _T0> or ...))
+ return flags<_Traits...>{} | flags<_More...>{};
+ else
+ return flags<_Traits..., _T0>{} | flags<_More...>{};
+ }
+
+ consteval auto
+ _M_and(flags<>) const
+ { return flags<>{}; }
+
+ template <typename _T0, typename... _More>
+ consteval auto
+ _M_and(flags<_T0, _More...>) const
+ {
+ if constexpr ((same_as<_Traits, _T0> or ...))
+ return flags<_T0>{} | (flags{}._M_and(flags<_More...>{}));
+ else
+ return flags{}._M_and(flags<_More...>{});
+ }
+
+ consteval auto
+ _M_xor(flags<>) const
+ { return flags{}; }
+
+ template <typename _T0, typename... _More>
+ consteval auto
+ _M_xor(flags<_T0, _More...>) const
+ {
+ if constexpr ((same_as<_Traits, _T0> or ...))
+ {
+ constexpr auto __removed
+ = (conditional_t<same_as<_Traits, _T0>, flags<>,
+ flags<_Traits>>{} | ...);
+ return __removed._M_xor(flags<_More...>{});
+ }
+ else
+ return (flags{} | flags<_T0>{})._M_xor(flags<_More...>{});
+ }
+
+ template <typename _F0, typename _Tp>
+ static constexpr void
+ _S_apply_adjust_pointer(auto& __ptr)
+ {
+ if constexpr (requires{ _F0::template _S_adjust_pointer<_Tp>(__ptr); })
+ __ptr = _F0::template _S_adjust_pointer<_Tp>(__ptr);
+ }
+
+ template <typename _Tp, typename _Up>
+ static constexpr _Up*
+ _S_adjust_pointer(_Up* __ptr)
+ {
+ (_S_apply_adjust_pointer<_Traits, _Tp>(__ptr), ...);
+ return __ptr;
+ }
+ };
+
+ inline constexpr flags<> flag_default {};
+
+ inline constexpr flags<__convert_flag> flag_convert {};
+
+ inline constexpr flags<__aligned_flag> flag_aligned {};
+
+ template <size_t _Np>
+ requires(__has_single_bit(_Np))
+ inline constexpr flags<__overaligned_flag<_Np>> flag_overaligned {};
+
+#if 0
+ // extensions
+ template <typename _To>
+ inline constexpr flags<__convert_to_flag<_To>> __flag_convert_to {};
+
+ inline constexpr flags<__partial_loadstore_flag> __allow_partial_loadstore {};
+
+ inline constexpr flags<__throw_flag> __flag_throw {};
+
+ inline constexpr flags<__streaming_flag> __flag_streaming {};
+
+ template <int _L1, int _L2>
+ inline constexpr flags<__prefetch_flag<_L1, _L2>> __flag_prefetch {};
+#endif
+}
+
+#endif // C++26
+#endif // _GLIBCXX_SIMD_FLAGS_H