32 #ifndef MCKL_RANDOM_INTERNAL_PHILOX_SSE2_2X32_HPP 33 #define MCKL_RANDOM_INTERNAL_PHILOX_SSE2_2X32_HPP 47 template <
typename T,
typename Constants>
50 static_assert(std::numeric_limits<T>::digits == 32,
51 "**Philox2x32GeneratorSSE2Impl** used with T other than a 32-bit " 54 static constexpr std::size_t K = 2;
55 static constexpr std::size_t Rounds = 10;
59 const void *plain,
void *cipher,
const std::array<T, K / 2> &key)
64 template <
typename ResultType>
65 static void eval(std::array<std::uint64_t, 1> &ctr, ResultType *r,
66 const std::array<T, K / 2> &key)
71 template <
typename ResultType>
72 static void eval(std::array<std::uint64_t, 1> &ctr, std::size_t n,
73 ResultType *r,
const std::array<T, K / 2> &key)
75 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
77 const std::size_t n0 =
78 static_cast<std::size_t
>(std::min(static_cast<std::uint64_t>(n),
79 std::numeric_limits<std::uint64_t>::max() - ctr.front()));
81 eval_kernel(ctr, n0, r, key);
91 eval_kernel(ctr, n, r, key);
95 template <
typename ResultType>
96 static void eval_kernel(std::array<std::uint64_t, 1> &ctr, std::size_t n,
97 ResultType *r,
const std::array<T, K / 2> &key)
99 #if MCKL_USE_ASM_LIBRARY 100 constexpr T m0 = Constants::multiplier::value[0];
101 constexpr T w0 = Constants::weyl::value[0];
103 const T mwk[6] = {m0, 0, 0, w0, 0, std::get<0>(key)};
105 #else // MCKL_USE_ASM_LIBRARY 106 constexpr std::size_t
S = 8;
107 constexpr std::size_t N =
sizeof(__m128i) * S / (
sizeof(T) * K);
109 const int k0 =
static_cast<int>(std::get<0>(key));
110 const __m128i xmmk0 = _mm_set_epi32(k0, 0, k0, 0);
113 _mm_set1_epi64x(static_cast<MCKL_INT64>(std::get<0>(ctr)));
116 __m128i *rptr =
reinterpret_cast<__m128i *
>(r);
118 __m128i xmm0 = _mm_add_epi64(xmmc, _mm_set_epi64x(0x02, 0x01));
119 __m128i xmm1 = _mm_add_epi64(xmmc, _mm_set_epi64x(0x04, 0x03));
120 __m128i xmm2 = _mm_add_epi64(xmmc, _mm_set_epi64x(0x06, 0x05));
121 __m128i xmm3 = _mm_add_epi64(xmmc, _mm_set_epi64x(0x08, 0x07));
122 __m128i xmm4 = _mm_add_epi64(xmmc, _mm_set_epi64x(0x0A, 0x09));
123 __m128i xmm5 = _mm_add_epi64(xmmc, _mm_set_epi64x(0x0C, 0x0B));
124 __m128i xmm6 = _mm_add_epi64(xmmc, _mm_set_epi64x(0x0E, 0x0D));
125 __m128i xmm7 = _mm_add_epi64(xmmc, _mm_set_epi64x(0x10, 0x0F));
126 xmmc = _mm_add_epi64(xmmc, _mm_set1_epi64x(0x10));
141 _mm_storeu_si128(rptr++, xmm0);
142 _mm_storeu_si128(rptr++, xmm1);
143 _mm_storeu_si128(rptr++, xmm2);
144 _mm_storeu_si128(rptr++, xmm3);
145 _mm_storeu_si128(rptr++, xmm4);
146 _mm_storeu_si128(rptr++, xmm5);
147 _mm_storeu_si128(rptr++, xmm6);
148 _mm_storeu_si128(rptr++, xmm7);
150 std::array<__m128i, S> s;
151 std::get<0>(s) = xmm0;
152 std::get<1>(s) = xmm1;
153 std::get<2>(s) = xmm2;
154 std::get<3>(s) = xmm3;
155 std::get<4>(s) = xmm4;
156 std::get<5>(s) = xmm5;
157 std::get<6>(s) = xmm6;
158 std::get<7>(s) = xmm7;
159 std::memcpy(rptr, s.data(), n *
sizeof(T) * K);
163 #endif // MCKL_USE_ASM_LIBRARY 173 #endif // MCKL_RANDOM_INTERNAL_PHILOX_SSE2_2X32_HPP static void eval(std::array< std::uint64_t, 1 > &ctr, ResultType *r, const std::array< T, K/2 > &key)
#define MCKL_PUSH_GCC_WARNING(warning)
void mckl_philox2x32_sse2_kernel(uint64_t *, size_t, void *, const void *)
static void eval(const void *plain, void *cipher, const std::array< T, K/2 > &key)
#define MCKL_RANDOM_INTERNAL_PHILOX_SSE2_32_RBOX(K, N, imm8)
#define MCKL_POP_GCC_WARNING
static void eval(std::array< std::uint64_t, 1 > &ctr, std::size_t n, ResultType *r, const std::array< T, K/2 > &key)