/home/liu/actions-runner/_work/ccv/ccv/lib/3rdparty/sfmt/SFMT-common.h
Line | Count | Source |
1 | | #pragma once |
2 | | /** |
3 | | * @file SFMT-common.h |
4 | | * |
5 | | * @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom |
6 | | * number generator with jump function. This file includes common functions |
7 | | * used in random number generation and jump. |
8 | | * |
9 | | * @author Mutsuo Saito (Hiroshima University) |
10 | | * @author Makoto Matsumoto (The University of Tokyo) |
11 | | * |
12 | | * Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima |
13 | | * University. |
14 | | * Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima |
15 | | * University and The University of Tokyo. |
16 | | * All rights reserved. |
17 | | * |
18 | | * The 3-clause BSD License is applied to this software, see |
19 | | * LICENSE.txt |
20 | | */ |
21 | | #ifndef SFMT_COMMON_H |
22 | | #define SFMT_COMMON_H |
23 | | |
24 | | #if defined(__cplusplus) |
25 | | extern "C" { |
26 | | #endif |
27 | | |
28 | | #include "SFMT.h" |
29 | | |
30 | | inline static void do_recursion(w128_t * r, w128_t * a, w128_t * b, |
31 | | w128_t * c, w128_t * d); |
32 | | |
33 | | inline static void rshift128(w128_t *out, w128_t const *in, int shift); |
34 | | inline static void lshift128(w128_t *out, w128_t const *in, int shift); |
35 | | |
36 | | /** |
37 | | * This function simulates SIMD 128-bit right shift by the standard C. |
38 | | * The 128-bit integer given in in is shifted by (shift * 8) bits. |
39 | | * This function simulates the LITTLE ENDIAN SIMD. |
40 | | * @param out the output of this function |
41 | | * @param in the 128-bit data to be shifted |
42 | | * @param shift the shift value |
43 | | */ |
44 | | #ifdef ONLY64 |
45 | | inline static void rshift128(w128_t *out, w128_t const *in, int shift) { |
46 | | uint64_t th, tl, oh, ol; |
47 | | |
48 | | th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]); |
49 | | tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]); |
50 | | |
51 | | oh = th >> (shift * 8); |
52 | | ol = tl >> (shift * 8); |
53 | | ol |= th << (64 - shift * 8); |
54 | | out->u[0] = (uint32_t)(ol >> 32); |
55 | | out->u[1] = (uint32_t)ol; |
56 | | out->u[2] = (uint32_t)(oh >> 32); |
57 | | out->u[3] = (uint32_t)oh; |
58 | | } |
59 | | #else |
60 | | inline static void rshift128(w128_t *out, w128_t const *in, int shift) |
61 | 0 | { |
62 | 0 | uint64_t th, tl, oh, ol; |
63 | 0 |
|
64 | 0 | th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]); |
65 | 0 | tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]); |
66 | 0 |
|
67 | 0 | oh = th >> (shift * 8); |
68 | 0 | ol = tl >> (shift * 8); |
69 | 0 | ol |= th << (64 - shift * 8); |
70 | 0 | out->u[1] = (uint32_t)(ol >> 32); |
71 | 0 | out->u[0] = (uint32_t)ol; |
72 | 0 | out->u[3] = (uint32_t)(oh >> 32); |
73 | 0 | out->u[2] = (uint32_t)oh; |
74 | 0 | } |
75 | | #endif |
76 | | /** |
77 | | * This function simulates SIMD 128-bit left shift by the standard C. |
78 | | * The 128-bit integer given in in is shifted by (shift * 8) bits. |
79 | | * This function simulates the LITTLE ENDIAN SIMD. |
80 | | * @param out the output of this function |
81 | | * @param in the 128-bit data to be shifted |
82 | | * @param shift the shift value |
83 | | */ |
84 | | #ifdef ONLY64 |
85 | | inline static void lshift128(w128_t *out, w128_t const *in, int shift) { |
86 | | uint64_t th, tl, oh, ol; |
87 | | |
88 | | th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]); |
89 | | tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]); |
90 | | |
91 | | oh = th << (shift * 8); |
92 | | ol = tl << (shift * 8); |
93 | | oh |= tl >> (64 - shift * 8); |
94 | | out->u[0] = (uint32_t)(ol >> 32); |
95 | | out->u[1] = (uint32_t)ol; |
96 | | out->u[2] = (uint32_t)(oh >> 32); |
97 | | out->u[3] = (uint32_t)oh; |
98 | | } |
99 | | #else |
100 | | inline static void lshift128(w128_t *out, w128_t const *in, int shift) |
101 | 0 | { |
102 | 0 | uint64_t th, tl, oh, ol; |
103 | 0 |
|
104 | 0 | th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]); |
105 | 0 | tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]); |
106 | 0 |
|
107 | 0 | oh = th << (shift * 8); |
108 | 0 | ol = tl << (shift * 8); |
109 | 0 | oh |= tl >> (64 - shift * 8); |
110 | 0 | out->u[1] = (uint32_t)(ol >> 32); |
111 | 0 | out->u[0] = (uint32_t)ol; |
112 | 0 | out->u[3] = (uint32_t)(oh >> 32); |
113 | 0 | out->u[2] = (uint32_t)oh; |
114 | 0 | } |
115 | | #endif |
116 | | /** |
117 | | * This function represents the recursion formula. |
118 | | * @param r output |
119 | | * @param a a 128-bit part of the internal state array |
120 | | * @param b a 128-bit part of the internal state array |
121 | | * @param c a 128-bit part of the internal state array |
122 | | * @param d a 128-bit part of the internal state array |
123 | | */ |
124 | | #ifdef ONLY64 |
125 | | inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c, |
126 | | w128_t *d) { |
127 | | w128_t x; |
128 | | w128_t y; |
129 | | |
130 | | lshift128(&x, a, SFMT_SL2); |
131 | | rshift128(&y, c, SFMT_SR2); |
132 | | r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SFMT_SR1) & SFMT_MSK2) ^ y.u[0] |
133 | | ^ (d->u[0] << SFMT_SL1); |
134 | | r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SFMT_SR1) & SFMT_MSK1) ^ y.u[1] |
135 | | ^ (d->u[1] << SFMT_SL1); |
136 | | r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SFMT_SR1) & SFMT_MSK4) ^ y.u[2] |
137 | | ^ (d->u[2] << SFMT_SL1); |
138 | | r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SFMT_SR1) & SFMT_MSK3) ^ y.u[3] |
139 | | ^ (d->u[3] << SFMT_SL1); |
140 | | } |
141 | | #else |
142 | | inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, |
143 | | w128_t *c, w128_t *d) |
144 | 0 | { |
145 | 0 | w128_t x; |
146 | 0 | w128_t y; |
147 | 0 |
|
148 | 0 | lshift128(&x, a, SFMT_SL2); |
149 | 0 | rshift128(&y, c, SFMT_SR2); |
150 | 0 | r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SFMT_SR1) & SFMT_MSK1) |
151 | 0 | ^ y.u[0] ^ (d->u[0] << SFMT_SL1); |
152 | 0 | r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SFMT_SR1) & SFMT_MSK2) |
153 | 0 | ^ y.u[1] ^ (d->u[1] << SFMT_SL1); |
154 | 0 | r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SFMT_SR1) & SFMT_MSK3) |
155 | 0 | ^ y.u[2] ^ (d->u[2] << SFMT_SL1); |
156 | 0 | r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SFMT_SR1) & SFMT_MSK4) |
157 | 0 | ^ y.u[3] ^ (d->u[3] << SFMT_SL1); |
158 | 0 | } |
159 | | #endif |
160 | | #endif |
161 | | |
162 | | #if defined(__cplusplus) |
163 | | } |
164 | | #endif |