File indexing completed on 2026-11-07 10:37:00
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef XSIMD_UTILS_SHIFTS_HPP
0014 #define XSIMD_UTILS_SHIFTS_HPP
0015
0016 #include "../../config/xsimd_macros.hpp"
0017 #include "../../types/xsimd_batch.hpp"
0018 #include "../../types/xsimd_batch_constant.hpp"
0019 #include "../../types/xsimd_traits.hpp"
0020
0021 namespace xsimd
0022 {
0023 namespace kernel
0024 {
0025 namespace utils
0026 {
0027 template <typename I, I offset, I length, I... Vs>
0028 struct select_stride
0029 {
0030 template <typename K>
0031 static constexpr K get(K i, K)
0032 {
0033 constexpr I values_array[] = { Vs... };
0034 return static_cast<K>(values_array[length * i + offset]);
0035 }
0036 };
0037
0038 template <typename I>
0039 constexpr I lsb_mask(I bit_index)
0040 {
0041 if (bit_index == 8 * sizeof(I))
0042 {
0043 return ~I { 0 };
0044 }
0045 return static_cast<I>((I { 1 } << bit_index) - I { 1 });
0046 }
0047
0048 template <class T, class A, T V0, T... Vs>
0049 constexpr bool all_equals(batch_constant<T, A, V0, Vs...> c)
0050 {
0051 return (c == std::integral_constant<T, V0> {}).all();
0052 }
0053
0054 template <class T, class A, T... Vs>
0055 XSIMD_INLINE batch<T, A> bitwise_lshift_as_twice_larger(
0056 batch<T, A> const& self, batch_constant<T, A, Vs...>) noexcept
0057 {
0058 using T2 = widen_t<T>;
0059
0060 const auto self2 = bitwise_cast<T2>(self);
0061
0062
0063 constexpr auto shifts_lo = make_batch_constant<T2, select_stride<T, 0, 2, Vs...>, A>();
0064 constexpr auto mask_lo = lsb_mask<T2>(8 * sizeof(T));
0065 const auto shifted_lo = bitwise_lshift(self2, shifts_lo);
0066 constexpr auto batch_mask_lo = make_batch_constant<T2, mask_lo, A>();
0067 const auto masked_lo = bitwise_and(shifted_lo, batch_mask_lo.as_batch());
0068
0069
0070 constexpr auto shifts_hi = make_batch_constant<T2, select_stride<T, 1, 2, Vs...>, A>();
0071 constexpr auto mask_hi = mask_lo << (8 * sizeof(T));
0072 constexpr auto batch_mask_hi = make_batch_constant<T2, mask_hi, A>();
0073 const auto masked_hi = bitwise_and(self2, batch_mask_hi.as_batch());
0074 const auto shifted_hi = bitwise_lshift(masked_hi, shifts_hi);
0075
0076 return bitwise_cast<T>(bitwise_or(masked_lo, shifted_hi));
0077 }
0078 }
0079 }
0080 }
0081
0082 #endif