libstdc++-v3/ChangeLog:

        * include/bits/simd_bit.h: New file.

Signed-off-by: Matthias Kretz <[email protected]>
---
 libstdc++-v3/include/bits/simd_bit.h | 156 +++++++++++++++++++++++++++
 1 file changed, 156 insertions(+)
 create mode 100644 libstdc++-v3/include/bits/simd_bit.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_bit.h b/libstdc++-v3/include/bits/simd_bit.h
new file mode 100644
index 00000000000..ddc8feb6dbc
--- /dev/null
+++ b/libstdc++-v3/include/bits/simd_bit.h
@@ -0,0 +1,156 @@
+/* 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_BIT_H
+#define _GLIBCXX_SIMD_BIT_H 1
+
+#ifdef _GLIBCXX_SYSHDR
+#pragma GCC system_header
+#endif
+
+#if __cplusplus >= 202400L
+
+#include "simd_vec.h"
+
+// psabi warnings are bogus because the ABI of the internal types never leaks into user code
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpsabi"
+
+// [simd.bit] -----------------------------------------------------------------
+namespace std::simd
+{
+  template<__simd_vec_type _Vp>
+    [[__gnu__::__always_inline__]]
+    constexpr _Vp
+    byteswap(const _Vp& __v) noexcept
+    { return _Vp([&](int __i) { return std::byteswap(__v[__i]); }); }
+
+  template<__simd_vec_type _Vp>
+    [[__gnu__::__always_inline__]]
+    constexpr _Vp
+    bit_ceil(const _Vp& __v)
+    {
+      using _Tp = typename _Vp::value_type;
+      constexpr _Tp __max = _Tp(1) << (sizeof(_Tp) * __CHAR_BIT__ - 1);
+      __glibcxx_simd_precondition(all_of(__v <= __max), "bit_ceil result is not representable");
+      return _Vp([&](int __i) { return std::bit_ceil(__v[__i]); });
+    }
+
+  template<__simd_vec_type _Vp>
+    [[__gnu__::__always_inline__]]
+    constexpr _Vp
+    bit_floor(const _Vp& __v) noexcept
+    { return _Vp([&](int __i) { return std::bit_floor(__v[__i]); }); }
+
+  template<__simd_vec_type _Vp>
+    [[__gnu__::__always_inline__]]
+    constexpr typename _Vp::mask_type
+    has_single_bit(const _Vp& __v) noexcept
+    { return typename _Vp::mask_type([&](int __i) { return std::has_single_bit(__v[__i]); }); }
+
+  template<__simd_vec_type _V0, __simd_vec_type _V1>
+    [[__gnu__::__always_inline__]]
+    constexpr _V0
+    rotl(const _V0& __v, const _V1& __s) noexcept
+    { return _V0([&](int __i) { return std::rotl(__v[__i], __s[__i]); }); }
+
+  template<__simd_vec_type _Vp>
+    [[__gnu__::__always_inline__]]
+    constexpr _Vp
+    rotl(const _Vp& __v, int __s) noexcept
+    { return _Vp([&](int __i) { return std::rotl(__v[__i], __s); }); }
+
+  template<__simd_vec_type _V0, __simd_vec_type _V1>
+    [[__gnu__::__always_inline__]]
+    constexpr _V0
+    rotr(const _V0& __v, const _V1& __s) noexcept
+    { return _V0([&](int __i) { return std::rotr(__v[__i], __s[__i]); }); }
+
+  template<__simd_vec_type _Vp>
+    [[__gnu__::__always_inline__]]
+    constexpr _Vp
+    rotr(const _Vp& __v, int __s) noexcept
+    { return _Vp([&](int __i) { return std::rotr(__v[__i], __s); }); }
+
+  template<__simd_vec_type _Vp>
+    [[__gnu__::__always_inline__]]
+    constexpr rebind_t<make_signed_t<typename _Vp::value_type>, _Vp>
+    bit_width(const _Vp& __v) noexcept
+    {
+      return rebind_t<make_signed_t<typename _Vp::value_type>, _Vp>([&](int __i) {
+               return std::bit_width(__v[__i]);
+             });
+    }
+
+  template<__simd_vec_type _Vp>
+    [[__gnu__::__always_inline__]]
+    constexpr rebind_t<make_signed_t<typename _Vp::value_type>, _Vp>
+    countl_zero(const _Vp& __v) noexcept
+    {
+      return rebind_t<make_signed_t<typename _Vp::value_type>, _Vp>([&](int __i) {
+               return std::countl_zero(__v[__i]);
+             });
+    }
+
+  template<__simd_vec_type _Vp>
+    [[__gnu__::__always_inline__]]
+    constexpr rebind_t<make_signed_t<typename _Vp::value_type>, _Vp>
+    countl_one(const _Vp& __v) noexcept
+    {
+      return rebind_t<make_signed_t<typename _Vp::value_type>, _Vp>([&](int __i) {
+               return std::countl_one(__v[__i]);
+             });
+    }
+
+  template<__simd_vec_type _Vp>
+    [[__gnu__::__always_inline__]]
+    constexpr rebind_t<make_signed_t<typename _Vp::value_type>, _Vp>
+    countr_zero(const _Vp& __v) noexcept
+    {
+      return rebind_t<make_signed_t<typename _Vp::value_type>, _Vp>([&](int __i) {
+               return std::countr_zero(__v[__i]);
+             });
+    }
+
+  template<__simd_vec_type _Vp>
+    [[__gnu__::__always_inline__]]
+    constexpr rebind_t<make_signed_t<typename _Vp::value_type>, _Vp>
+    countr_one(const _Vp& __v) noexcept
+    {
+      return rebind_t<make_signed_t<typename _Vp::value_type>, _Vp>([&](int __i) {
+               return std::countr_one(__v[__i]);
+             });
+    }
+
+  template<__simd_vec_type _Vp>
+    [[__gnu__::__always_inline__]]
+    constexpr rebind_t<make_signed_t<typename _Vp::value_type>, _Vp>
+    popcount(const _Vp& __v) noexcept
+    {
+      return rebind_t<make_signed_t<typename _Vp::value_type>, _Vp>([&](int __i) {
+               return std::popcount(__v[__i]);
+             });
+    }
+}
+
+namespace std
+{
+  using simd::byteswap;
+  using simd::bit_ceil;
+  using simd::bit_floor;
+  using simd::has_single_bit;
+  using simd::rotl;
+  using simd::rotr;
+  using simd::bit_width;
+  using simd::countl_zero;
+  using simd::countl_one;
+  using simd::countr_zero;
+  using simd::countr_one;
+  using simd::popcount;
+}
+
+#pragma GCC diagnostic pop
+#endif // C++26
+#endif // _GLIBCXX_SIMD_BIT_H

Reply via email to