32 #ifndef MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_HPP 33 #define MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_HPP 43 #define MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_KBOX(N) \ 44 xmmt0 = _mm_set1_epi64x(static_cast<MCKL_INT64>( \ 45 ThreefryKBox<T, K, N>::template key<0>(par))); \ 46 xmmt1 = _mm_set1_epi64x(static_cast<MCKL_INT64>( \ 47 ThreefryKBox<T, K, N>::template key<1>(par))); \ 48 xmmt2 = _mm_set1_epi64x(static_cast<MCKL_INT64>( \ 49 ThreefryKBox<T, K, N>::template key<2>(par))); \ 50 xmmt3 = _mm_set1_epi64x(static_cast<MCKL_INT64>( \ 51 ThreefryKBox<T, K, N>::template key<3>(par))); \ 52 xmms0 = _mm_add_epi64(xmms0, xmmt0); \ 53 xmms1 = _mm_add_epi64(xmms1, xmmt1); \ 54 xmms2 = _mm_add_epi64(xmms2, xmmt2); \ 55 xmms3 = _mm_add_epi64(xmms3, xmmt3); \ 56 xmms4 = _mm_add_epi64(xmms4, xmmt0); \ 57 xmms5 = _mm_add_epi64(xmms5, xmmt1); \ 58 xmms6 = _mm_add_epi64(xmms6, xmmt2); \ 59 xmms7 = _mm_add_epi64(xmms7, xmmt3); 61 #define MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_RBOX(N) \ 63 constexpr int L0 = Constants::rotate::value[0][(N - 1) % 8]; \ 64 constexpr int L1 = Constants::rotate::value[1][(N - 1) % 8]; \ 65 constexpr int R0 = 64 - L0; \ 66 constexpr int R1 = 64 - L1; \ 67 xmms0 = _mm_add_epi64(xmms0, xmms1); \ 68 xmms2 = _mm_add_epi64(xmms2, xmms3); \ 69 xmms4 = _mm_add_epi64(xmms4, xmms5); \ 70 xmms6 = _mm_add_epi64(xmms6, xmms7); \ 71 xmmt1 = _mm_slli_epi64(xmms1, L0); \ 72 xmmt3 = _mm_slli_epi64(xmms3, L1); \ 73 xmmt5 = _mm_slli_epi64(xmms5, L0); \ 74 xmmt7 = _mm_slli_epi64(xmms7, L1); \ 75 xmms1 = _mm_srli_epi64(xmms1, R0); \ 76 xmms3 = _mm_srli_epi64(xmms3, R1); \ 77 xmms5 = _mm_srli_epi64(xmms5, R0); \ 78 xmms7 = _mm_srli_epi64(xmms7, R1); \ 79 xmmt1 = _mm_or_si128(xmms1, xmmt1); \ 80 xmmt3 = _mm_or_si128(xmms3, xmmt3); \ 81 xmmt5 = _mm_or_si128(xmms5, xmmt5); \ 82 xmmt7 = _mm_or_si128(xmms7, xmmt7); \ 83 xmms1 = _mm_xor_si128(xmms2, xmmt3); \ 84 xmms3 = _mm_xor_si128(xmms0, xmmt1); \ 85 xmms5 = _mm_xor_si128(xmms6, xmmt7); \ 86 xmms7 = _mm_xor_si128(xmms4, xmmt5); \ 89 #define MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_CYCLE_4(N) \ 90 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_RBOX(N * 8 + 1); \ 91 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_RBOX(N * 8 + 2); \ 92 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_RBOX(N * 8 + 3); \ 93 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_RBOX(N * 8 + 4); \ 94 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_KBOX(N * 8 + 4); 96 #define MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_CYCLE_8(N) \ 97 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_RBOX(N * 8 + 1); \ 98 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_RBOX(N * 8 + 2); \ 99 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_RBOX(N * 8 + 3); \ 100 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_RBOX(N * 8 + 4); \ 101 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_KBOX(N * 8 + 4); \ 102 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_RBOX(N * 8 + 5); \ 103 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_RBOX(N * 8 + 6); \ 104 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_RBOX(N * 8 + 7); \ 105 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_RBOX(N * 8 + 8); \ 106 MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_KBOX(N * 8 + 8); 112 template <
typename T>
115 static_assert(std::numeric_limits<T>::digits == 64,
116 "**Threefry4x64GeneratorSSE2Impl** used with T other than a 64-bit " 117 "unsigned integers");
119 static constexpr std::size_t K = 4;
120 static constexpr std::size_t Rounds = 20;
125 const void *plain,
void *cipher,
const std::array<T, K + 4> &par)
130 template <
typename ResultType>
131 static void eval(std::array<std::uint64_t, 4> &ctr, ResultType *r,
132 const std::array<T, K + 4> &par)
137 template <
typename ResultType>
138 static void eval(std::array<std::uint64_t, 4> &ctr, std::size_t n,
139 ResultType *r,
const std::array<T, K + 4> &par)
141 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
143 const std::size_t n0 =
144 static_cast<std::size_t
>(std::min(static_cast<std::uint64_t>(n),
145 std::numeric_limits<std::uint64_t>::max() - ctr.front()));
147 eval_kernel(ctr, n0, r, par);
157 eval_kernel(ctr, n, r, par);
161 template <
typename ResultType>
162 static void eval_kernel(std::array<std::uint64_t, 4> &ctr, std::size_t n,
163 ResultType *r,
const std::array<T, K + 4> &par)
165 constexpr std::size_t
S = 8;
166 constexpr std::size_t N =
sizeof(__m128i) * S / (
sizeof(T) * K);
169 _mm_set_epi64x(static_cast<MCKL_INT64>(std::get<1>(ctr)),
170 static_cast<MCKL_INT64>(std::get<0>(ctr)));
172 _mm_set_epi64x(static_cast<MCKL_INT64>(std::get<3>(ctr)),
173 static_cast<MCKL_INT64>(std::get<2>(ctr)));
176 __m128i *rptr =
reinterpret_cast<__m128i *
>(r);
178 __m128i xmmt0 = _mm_add_epi64(xmmc0, _mm_set_epi64x(0, 1));
179 __m128i xmmt2 = _mm_add_epi64(xmmc0, _mm_set_epi64x(0, 2));
180 __m128i xmmt4 = _mm_add_epi64(xmmc0, _mm_set_epi64x(0, 3));
181 __m128i xmmt6 = _mm_add_epi64(xmmc0, _mm_set_epi64x(0, 4));
184 __m128i xmmt1 = xmmc1;
185 __m128i xmmt3 = xmmc1;
186 __m128i xmmt5 = xmmc1;
187 __m128i xmmt7 = xmmc1;
208 xmms0 = _mm_unpacklo_epi64(xmmt0, xmmt1);
209 xmms1 = _mm_unpackhi_epi64(xmmt0, xmmt1);
210 xmms2 = _mm_unpacklo_epi64(xmmt2, xmmt3);
211 xmms3 = _mm_unpackhi_epi64(xmmt2, xmmt3);
212 xmms4 = _mm_unpacklo_epi64(xmmt4, xmmt5);
213 xmms5 = _mm_unpackhi_epi64(xmmt4, xmmt5);
214 xmms6 = _mm_unpacklo_epi64(xmmt6, xmmt7);
215 xmms7 = _mm_unpackhi_epi64(xmmt6, xmmt7);
222 xmmt0 = _mm_unpacklo_epi64(xmms0, xmms1);
223 xmmt1 = _mm_unpackhi_epi64(xmms0, xmms1);
224 xmmt2 = _mm_unpacklo_epi64(xmms2, xmms3);
225 xmmt3 = _mm_unpackhi_epi64(xmms2, xmms3);
226 xmmt4 = _mm_unpacklo_epi64(xmms4, xmms5);
227 xmmt5 = _mm_unpackhi_epi64(xmms4, xmms5);
228 xmmt6 = _mm_unpacklo_epi64(xmms6, xmms7);
229 xmmt7 = _mm_unpackhi_epi64(xmms6, xmms7);
243 _mm_storeu_si128(rptr++, xmmt0);
244 _mm_storeu_si128(rptr++, xmmt1);
245 _mm_storeu_si128(rptr++, xmmt2);
246 _mm_storeu_si128(rptr++, xmmt3);
247 _mm_storeu_si128(rptr++, xmmt4);
248 _mm_storeu_si128(rptr++, xmmt5);
249 _mm_storeu_si128(rptr++, xmmt6);
250 _mm_storeu_si128(rptr++, xmmt7);
252 std::array<__m128i, S> s;
253 std::get<0>(s) = xmmt0;
254 std::get<1>(s) = xmmt1;
255 std::get<2>(s) = xmmt2;
256 std::get<3>(s) = xmmt3;
257 std::get<4>(s) = xmmt4;
258 std::get<5>(s) = xmmt5;
259 std::get<6>(s) = xmmt6;
260 std::get<7>(s) = xmmt7;
261 std::memcpy(rptr, s.data(), n *
sizeof(T) * K);
268 template <
typename T>
271 static_assert(std::numeric_limits<T>::digits == 64,
272 "**Threefish256GeneratorSSE2Impl** used with T other than a 64-bit " 273 "unsigned integers");
275 static constexpr std::size_t K = 4;
276 static constexpr std::size_t Rounds = 72;
281 const void *plain,
void *cipher,
const std::array<T, K + 4> &par)
286 template <
typename ResultType>
287 static void eval(std::array<std::uint64_t, 4> &ctr, ResultType *r,
288 const std::array<T, K + 4> &par)
293 template <
typename ResultType>
294 static void eval(std::array<std::uint64_t, 4> &ctr, std::size_t n,
295 ResultType *r,
const std::array<T, K + 4> &par)
297 constexpr std::size_t R =
sizeof(T) * K /
sizeof(ResultType);
299 const std::size_t n0 =
300 static_cast<std::size_t
>(std::min(static_cast<std::uint64_t>(n),
301 std::numeric_limits<std::uint64_t>::max() - ctr.front()));
303 eval_kernel(ctr, n0, r, par);
313 eval_kernel(ctr, n, r, par);
317 template <
typename ResultType>
318 static void eval_kernel(std::array<std::uint64_t, 4> &ctr, std::size_t n,
319 ResultType *r,
const std::array<T, K + 4> &par)
321 constexpr std::size_t
S = 8;
322 constexpr std::size_t N =
sizeof(__m128i) * S / (
sizeof(T) * K);
325 _mm_set_epi64x(static_cast<MCKL_INT64>(std::get<1>(ctr)),
326 static_cast<MCKL_INT64>(std::get<0>(ctr)));
328 _mm_set_epi64x(static_cast<MCKL_INT64>(std::get<3>(ctr)),
329 static_cast<MCKL_INT64>(std::get<2>(ctr)));
332 __m128i *rptr =
reinterpret_cast<__m128i *
>(r);
334 __m128i xmmt0 = _mm_add_epi64(xmmc0, _mm_set_epi64x(0, 1));
335 __m128i xmmt2 = _mm_add_epi64(xmmc0, _mm_set_epi64x(0, 2));
336 __m128i xmmt4 = _mm_add_epi64(xmmc0, _mm_set_epi64x(0, 3));
337 __m128i xmmt6 = _mm_add_epi64(xmmc0, _mm_set_epi64x(0, 4));
340 __m128i xmmt1 = xmmc1;
341 __m128i xmmt3 = xmmc1;
342 __m128i xmmt5 = xmmc1;
343 __m128i xmmt7 = xmmc1;
364 xmms0 = _mm_unpacklo_epi64(xmmt0, xmmt1);
365 xmms1 = _mm_unpackhi_epi64(xmmt0, xmmt1);
366 xmms2 = _mm_unpacklo_epi64(xmmt2, xmmt3);
367 xmms3 = _mm_unpackhi_epi64(xmmt2, xmmt3);
368 xmms4 = _mm_unpacklo_epi64(xmmt4, xmmt5);
369 xmms5 = _mm_unpackhi_epi64(xmmt4, xmmt5);
370 xmms6 = _mm_unpacklo_epi64(xmmt6, xmmt7);
371 xmms7 = _mm_unpackhi_epi64(xmmt6, xmmt7);
384 xmmt0 = _mm_unpacklo_epi64(xmms0, xmms1);
385 xmmt1 = _mm_unpackhi_epi64(xmms0, xmms1);
386 xmmt2 = _mm_unpacklo_epi64(xmms2, xmms3);
387 xmmt3 = _mm_unpackhi_epi64(xmms2, xmms3);
388 xmmt4 = _mm_unpacklo_epi64(xmms4, xmms5);
389 xmmt5 = _mm_unpackhi_epi64(xmms4, xmms5);
390 xmmt6 = _mm_unpacklo_epi64(xmms6, xmms7);
391 xmmt7 = _mm_unpackhi_epi64(xmms6, xmms7);
405 _mm_storeu_si128(rptr++, xmmt0);
406 _mm_storeu_si128(rptr++, xmmt1);
407 _mm_storeu_si128(rptr++, xmmt2);
408 _mm_storeu_si128(rptr++, xmmt3);
409 _mm_storeu_si128(rptr++, xmmt4);
410 _mm_storeu_si128(rptr++, xmmt5);
411 _mm_storeu_si128(rptr++, xmmt6);
412 _mm_storeu_si128(rptr++, xmmt7);
414 std::array<__m128i, S> s;
415 std::get<0>(s) = xmmt0;
416 std::get<1>(s) = xmmt1;
417 std::get<2>(s) = xmmt2;
418 std::get<3>(s) = xmmt3;
419 std::get<4>(s) = xmmt4;
420 std::get<5>(s) = xmmt5;
421 std::get<6>(s) = xmmt6;
422 std::get<7>(s) = xmmt7;
423 std::memcpy(rptr, s.data(), n *
sizeof(T) * K);
436 #endif // MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_HPP #define MCKL_PUSH_GCC_WARNING(warning)
#define MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_CYCLE_8(N)
#define MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_CYCLE_4(N)
static void eval(const void *plain, void *cipher, const std::array< T, K+4 > &par)
static void eval(const void *plain, void *cipher, const std::array< T, K+4 > &par)
static void eval(const void *plain, void *cipher, const std::array< T, K+4 > &par)
static void eval(std::array< std::uint64_t, 4 > &ctr, ResultType *r, const std::array< T, K+4 > &par)
static void eval(std::array< std::uint64_t, 4 > &ctr, std::size_t n, ResultType *r, const std::array< T, K+4 > &par)
static void eval(std::array< std::uint64_t, 4 > &ctr, std::size_t n, ResultType *r, const std::array< T, K+4 > &par)
Default Threefry constants.
#define MCKL_RANDOM_INTERNAL_THREEFRY_SSE2_4X64_KBOX(N)
static void eval(std::array< std::uint64_t, 4 > &ctr, ResultType *r, const std::array< T, K+4 > &par)
static void eval(const void *plain, void *cipher, const std::array< T, K+4 > &par)
#define MCKL_POP_GCC_WARNING