1*1208bc7eSAndroid Build Coastguard Worker /*
2*1208bc7eSAndroid Build Coastguard Worker * This file derives from SFMT 1.3.3
3*1208bc7eSAndroid Build Coastguard Worker * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was
4*1208bc7eSAndroid Build Coastguard Worker * released under the terms of the following license:
5*1208bc7eSAndroid Build Coastguard Worker *
6*1208bc7eSAndroid Build Coastguard Worker * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
7*1208bc7eSAndroid Build Coastguard Worker * University. All rights reserved.
8*1208bc7eSAndroid Build Coastguard Worker *
9*1208bc7eSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
10*1208bc7eSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are
11*1208bc7eSAndroid Build Coastguard Worker * met:
12*1208bc7eSAndroid Build Coastguard Worker *
13*1208bc7eSAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright
14*1208bc7eSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
15*1208bc7eSAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above
16*1208bc7eSAndroid Build Coastguard Worker * copyright notice, this list of conditions and the following
17*1208bc7eSAndroid Build Coastguard Worker * disclaimer in the documentation and/or other materials provided
18*1208bc7eSAndroid Build Coastguard Worker * with the distribution.
19*1208bc7eSAndroid Build Coastguard Worker * * Neither the name of the Hiroshima University nor the names of
20*1208bc7eSAndroid Build Coastguard Worker * its contributors may be used to endorse or promote products
21*1208bc7eSAndroid Build Coastguard Worker * derived from this software without specific prior written
22*1208bc7eSAndroid Build Coastguard Worker * permission.
23*1208bc7eSAndroid Build Coastguard Worker *
24*1208bc7eSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25*1208bc7eSAndroid Build Coastguard Worker * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26*1208bc7eSAndroid Build Coastguard Worker * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27*1208bc7eSAndroid Build Coastguard Worker * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28*1208bc7eSAndroid Build Coastguard Worker * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29*1208bc7eSAndroid Build Coastguard Worker * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30*1208bc7eSAndroid Build Coastguard Worker * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31*1208bc7eSAndroid Build Coastguard Worker * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32*1208bc7eSAndroid Build Coastguard Worker * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33*1208bc7eSAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34*1208bc7eSAndroid Build Coastguard Worker * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*1208bc7eSAndroid Build Coastguard Worker */
36*1208bc7eSAndroid Build Coastguard Worker /**
37*1208bc7eSAndroid Build Coastguard Worker * @file SFMT.c
38*1208bc7eSAndroid Build Coastguard Worker * @brief SIMD oriented Fast Mersenne Twister(SFMT)
39*1208bc7eSAndroid Build Coastguard Worker *
40*1208bc7eSAndroid Build Coastguard Worker * @author Mutsuo Saito (Hiroshima University)
41*1208bc7eSAndroid Build Coastguard Worker * @author Makoto Matsumoto (Hiroshima University)
42*1208bc7eSAndroid Build Coastguard Worker *
43*1208bc7eSAndroid Build Coastguard Worker * Copyright (C) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
44*1208bc7eSAndroid Build Coastguard Worker * University. All rights reserved.
45*1208bc7eSAndroid Build Coastguard Worker *
46*1208bc7eSAndroid Build Coastguard Worker * The new BSD License is applied to this software, see LICENSE.txt
47*1208bc7eSAndroid Build Coastguard Worker */
48*1208bc7eSAndroid Build Coastguard Worker #define SFMT_C_
49*1208bc7eSAndroid Build Coastguard Worker #include "test/jemalloc_test.h"
50*1208bc7eSAndroid Build Coastguard Worker #include "test/SFMT-params.h"
51*1208bc7eSAndroid Build Coastguard Worker
52*1208bc7eSAndroid Build Coastguard Worker #if defined(JEMALLOC_BIG_ENDIAN) && !defined(BIG_ENDIAN64)
53*1208bc7eSAndroid Build Coastguard Worker #define BIG_ENDIAN64 1
54*1208bc7eSAndroid Build Coastguard Worker #endif
55*1208bc7eSAndroid Build Coastguard Worker #if defined(__BIG_ENDIAN__) && !defined(__amd64) && !defined(BIG_ENDIAN64)
56*1208bc7eSAndroid Build Coastguard Worker #define BIG_ENDIAN64 1
57*1208bc7eSAndroid Build Coastguard Worker #endif
58*1208bc7eSAndroid Build Coastguard Worker #if defined(HAVE_ALTIVEC) && !defined(BIG_ENDIAN64)
59*1208bc7eSAndroid Build Coastguard Worker #define BIG_ENDIAN64 1
60*1208bc7eSAndroid Build Coastguard Worker #endif
61*1208bc7eSAndroid Build Coastguard Worker #if defined(ONLY64) && !defined(BIG_ENDIAN64)
62*1208bc7eSAndroid Build Coastguard Worker #if defined(__GNUC__)
63*1208bc7eSAndroid Build Coastguard Worker #error "-DONLY64 must be specified with -DBIG_ENDIAN64"
64*1208bc7eSAndroid Build Coastguard Worker #endif
65*1208bc7eSAndroid Build Coastguard Worker #undef ONLY64
66*1208bc7eSAndroid Build Coastguard Worker #endif
67*1208bc7eSAndroid Build Coastguard Worker /*------------------------------------------------------
68*1208bc7eSAndroid Build Coastguard Worker 128-bit SIMD data type for Altivec, SSE2 or standard C
69*1208bc7eSAndroid Build Coastguard Worker ------------------------------------------------------*/
70*1208bc7eSAndroid Build Coastguard Worker #if defined(HAVE_ALTIVEC)
71*1208bc7eSAndroid Build Coastguard Worker /** 128-bit data structure */
72*1208bc7eSAndroid Build Coastguard Worker union W128_T {
73*1208bc7eSAndroid Build Coastguard Worker vector unsigned int s;
74*1208bc7eSAndroid Build Coastguard Worker uint32_t u[4];
75*1208bc7eSAndroid Build Coastguard Worker };
76*1208bc7eSAndroid Build Coastguard Worker /** 128-bit data type */
77*1208bc7eSAndroid Build Coastguard Worker typedef union W128_T w128_t;
78*1208bc7eSAndroid Build Coastguard Worker
79*1208bc7eSAndroid Build Coastguard Worker #elif defined(HAVE_SSE2)
80*1208bc7eSAndroid Build Coastguard Worker /** 128-bit data structure */
81*1208bc7eSAndroid Build Coastguard Worker union W128_T {
82*1208bc7eSAndroid Build Coastguard Worker __m128i si;
83*1208bc7eSAndroid Build Coastguard Worker uint32_t u[4];
84*1208bc7eSAndroid Build Coastguard Worker };
85*1208bc7eSAndroid Build Coastguard Worker /** 128-bit data type */
86*1208bc7eSAndroid Build Coastguard Worker typedef union W128_T w128_t;
87*1208bc7eSAndroid Build Coastguard Worker
88*1208bc7eSAndroid Build Coastguard Worker #else
89*1208bc7eSAndroid Build Coastguard Worker
90*1208bc7eSAndroid Build Coastguard Worker /** 128-bit data structure */
91*1208bc7eSAndroid Build Coastguard Worker struct W128_T {
92*1208bc7eSAndroid Build Coastguard Worker uint32_t u[4];
93*1208bc7eSAndroid Build Coastguard Worker };
94*1208bc7eSAndroid Build Coastguard Worker /** 128-bit data type */
95*1208bc7eSAndroid Build Coastguard Worker typedef struct W128_T w128_t;
96*1208bc7eSAndroid Build Coastguard Worker
97*1208bc7eSAndroid Build Coastguard Worker #endif
98*1208bc7eSAndroid Build Coastguard Worker
99*1208bc7eSAndroid Build Coastguard Worker struct sfmt_s {
100*1208bc7eSAndroid Build Coastguard Worker /** the 128-bit internal state array */
101*1208bc7eSAndroid Build Coastguard Worker w128_t sfmt[N];
102*1208bc7eSAndroid Build Coastguard Worker /** index counter to the 32-bit internal state array */
103*1208bc7eSAndroid Build Coastguard Worker int idx;
104*1208bc7eSAndroid Build Coastguard Worker /** a flag: it is 0 if and only if the internal state is not yet
105*1208bc7eSAndroid Build Coastguard Worker * initialized. */
106*1208bc7eSAndroid Build Coastguard Worker int initialized;
107*1208bc7eSAndroid Build Coastguard Worker };
108*1208bc7eSAndroid Build Coastguard Worker
109*1208bc7eSAndroid Build Coastguard Worker /*--------------------------------------
110*1208bc7eSAndroid Build Coastguard Worker FILE GLOBAL VARIABLES
111*1208bc7eSAndroid Build Coastguard Worker internal state, index counter and flag
112*1208bc7eSAndroid Build Coastguard Worker --------------------------------------*/
113*1208bc7eSAndroid Build Coastguard Worker
114*1208bc7eSAndroid Build Coastguard Worker /** a parity check vector which certificate the period of 2^{MEXP} */
115*1208bc7eSAndroid Build Coastguard Worker static uint32_t parity[4] = {PARITY1, PARITY2, PARITY3, PARITY4};
116*1208bc7eSAndroid Build Coastguard Worker
117*1208bc7eSAndroid Build Coastguard Worker /*----------------
118*1208bc7eSAndroid Build Coastguard Worker STATIC FUNCTIONS
119*1208bc7eSAndroid Build Coastguard Worker ----------------*/
120*1208bc7eSAndroid Build Coastguard Worker static inline int idxof(int i);
121*1208bc7eSAndroid Build Coastguard Worker #if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
122*1208bc7eSAndroid Build Coastguard Worker static inline void rshift128(w128_t *out, w128_t const *in, int shift);
123*1208bc7eSAndroid Build Coastguard Worker static inline void lshift128(w128_t *out, w128_t const *in, int shift);
124*1208bc7eSAndroid Build Coastguard Worker #endif
125*1208bc7eSAndroid Build Coastguard Worker static inline void gen_rand_all(sfmt_t *ctx);
126*1208bc7eSAndroid Build Coastguard Worker static inline void gen_rand_array(sfmt_t *ctx, w128_t *array, int size);
127*1208bc7eSAndroid Build Coastguard Worker static inline uint32_t func1(uint32_t x);
128*1208bc7eSAndroid Build Coastguard Worker static inline uint32_t func2(uint32_t x);
129*1208bc7eSAndroid Build Coastguard Worker static void period_certification(sfmt_t *ctx);
130*1208bc7eSAndroid Build Coastguard Worker #if defined(BIG_ENDIAN64) && !defined(ONLY64)
131*1208bc7eSAndroid Build Coastguard Worker static inline void swap(w128_t *array, int size);
132*1208bc7eSAndroid Build Coastguard Worker #endif
133*1208bc7eSAndroid Build Coastguard Worker
134*1208bc7eSAndroid Build Coastguard Worker #if defined(HAVE_ALTIVEC)
135*1208bc7eSAndroid Build Coastguard Worker #include "test/SFMT-alti.h"
136*1208bc7eSAndroid Build Coastguard Worker #elif defined(HAVE_SSE2)
137*1208bc7eSAndroid Build Coastguard Worker #include "test/SFMT-sse2.h"
138*1208bc7eSAndroid Build Coastguard Worker #endif
139*1208bc7eSAndroid Build Coastguard Worker
140*1208bc7eSAndroid Build Coastguard Worker /**
141*1208bc7eSAndroid Build Coastguard Worker * This function simulate a 64-bit index of LITTLE ENDIAN
142*1208bc7eSAndroid Build Coastguard Worker * in BIG ENDIAN machine.
143*1208bc7eSAndroid Build Coastguard Worker */
144*1208bc7eSAndroid Build Coastguard Worker #ifdef ONLY64
idxof(int i)145*1208bc7eSAndroid Build Coastguard Worker static inline int idxof(int i) {
146*1208bc7eSAndroid Build Coastguard Worker return i ^ 1;
147*1208bc7eSAndroid Build Coastguard Worker }
148*1208bc7eSAndroid Build Coastguard Worker #else
idxof(int i)149*1208bc7eSAndroid Build Coastguard Worker static inline int idxof(int i) {
150*1208bc7eSAndroid Build Coastguard Worker return i;
151*1208bc7eSAndroid Build Coastguard Worker }
152*1208bc7eSAndroid Build Coastguard Worker #endif
153*1208bc7eSAndroid Build Coastguard Worker /**
154*1208bc7eSAndroid Build Coastguard Worker * This function simulates SIMD 128-bit right shift by the standard C.
155*1208bc7eSAndroid Build Coastguard Worker * The 128-bit integer given in in is shifted by (shift * 8) bits.
156*1208bc7eSAndroid Build Coastguard Worker * This function simulates the LITTLE ENDIAN SIMD.
157*1208bc7eSAndroid Build Coastguard Worker * @param out the output of this function
158*1208bc7eSAndroid Build Coastguard Worker * @param in the 128-bit data to be shifted
159*1208bc7eSAndroid Build Coastguard Worker * @param shift the shift value
160*1208bc7eSAndroid Build Coastguard Worker */
161*1208bc7eSAndroid Build Coastguard Worker #if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
162*1208bc7eSAndroid Build Coastguard Worker #ifdef ONLY64
rshift128(w128_t * out,w128_t const * in,int shift)163*1208bc7eSAndroid Build Coastguard Worker static inline void rshift128(w128_t *out, w128_t const *in, int shift) {
164*1208bc7eSAndroid Build Coastguard Worker uint64_t th, tl, oh, ol;
165*1208bc7eSAndroid Build Coastguard Worker
166*1208bc7eSAndroid Build Coastguard Worker th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
167*1208bc7eSAndroid Build Coastguard Worker tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
168*1208bc7eSAndroid Build Coastguard Worker
169*1208bc7eSAndroid Build Coastguard Worker oh = th >> (shift * 8);
170*1208bc7eSAndroid Build Coastguard Worker ol = tl >> (shift * 8);
171*1208bc7eSAndroid Build Coastguard Worker ol |= th << (64 - shift * 8);
172*1208bc7eSAndroid Build Coastguard Worker out->u[0] = (uint32_t)(ol >> 32);
173*1208bc7eSAndroid Build Coastguard Worker out->u[1] = (uint32_t)ol;
174*1208bc7eSAndroid Build Coastguard Worker out->u[2] = (uint32_t)(oh >> 32);
175*1208bc7eSAndroid Build Coastguard Worker out->u[3] = (uint32_t)oh;
176*1208bc7eSAndroid Build Coastguard Worker }
177*1208bc7eSAndroid Build Coastguard Worker #else
rshift128(w128_t * out,w128_t const * in,int shift)178*1208bc7eSAndroid Build Coastguard Worker static inline void rshift128(w128_t *out, w128_t const *in, int shift) {
179*1208bc7eSAndroid Build Coastguard Worker uint64_t th, tl, oh, ol;
180*1208bc7eSAndroid Build Coastguard Worker
181*1208bc7eSAndroid Build Coastguard Worker th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
182*1208bc7eSAndroid Build Coastguard Worker tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
183*1208bc7eSAndroid Build Coastguard Worker
184*1208bc7eSAndroid Build Coastguard Worker oh = th >> (shift * 8);
185*1208bc7eSAndroid Build Coastguard Worker ol = tl >> (shift * 8);
186*1208bc7eSAndroid Build Coastguard Worker ol |= th << (64 - shift * 8);
187*1208bc7eSAndroid Build Coastguard Worker out->u[1] = (uint32_t)(ol >> 32);
188*1208bc7eSAndroid Build Coastguard Worker out->u[0] = (uint32_t)ol;
189*1208bc7eSAndroid Build Coastguard Worker out->u[3] = (uint32_t)(oh >> 32);
190*1208bc7eSAndroid Build Coastguard Worker out->u[2] = (uint32_t)oh;
191*1208bc7eSAndroid Build Coastguard Worker }
192*1208bc7eSAndroid Build Coastguard Worker #endif
193*1208bc7eSAndroid Build Coastguard Worker /**
194*1208bc7eSAndroid Build Coastguard Worker * This function simulates SIMD 128-bit left shift by the standard C.
195*1208bc7eSAndroid Build Coastguard Worker * The 128-bit integer given in in is shifted by (shift * 8) bits.
196*1208bc7eSAndroid Build Coastguard Worker * This function simulates the LITTLE ENDIAN SIMD.
197*1208bc7eSAndroid Build Coastguard Worker * @param out the output of this function
198*1208bc7eSAndroid Build Coastguard Worker * @param in the 128-bit data to be shifted
199*1208bc7eSAndroid Build Coastguard Worker * @param shift the shift value
200*1208bc7eSAndroid Build Coastguard Worker */
201*1208bc7eSAndroid Build Coastguard Worker #ifdef ONLY64
lshift128(w128_t * out,w128_t const * in,int shift)202*1208bc7eSAndroid Build Coastguard Worker static inline void lshift128(w128_t *out, w128_t const *in, int shift) {
203*1208bc7eSAndroid Build Coastguard Worker uint64_t th, tl, oh, ol;
204*1208bc7eSAndroid Build Coastguard Worker
205*1208bc7eSAndroid Build Coastguard Worker th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
206*1208bc7eSAndroid Build Coastguard Worker tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
207*1208bc7eSAndroid Build Coastguard Worker
208*1208bc7eSAndroid Build Coastguard Worker oh = th << (shift * 8);
209*1208bc7eSAndroid Build Coastguard Worker ol = tl << (shift * 8);
210*1208bc7eSAndroid Build Coastguard Worker oh |= tl >> (64 - shift * 8);
211*1208bc7eSAndroid Build Coastguard Worker out->u[0] = (uint32_t)(ol >> 32);
212*1208bc7eSAndroid Build Coastguard Worker out->u[1] = (uint32_t)ol;
213*1208bc7eSAndroid Build Coastguard Worker out->u[2] = (uint32_t)(oh >> 32);
214*1208bc7eSAndroid Build Coastguard Worker out->u[3] = (uint32_t)oh;
215*1208bc7eSAndroid Build Coastguard Worker }
216*1208bc7eSAndroid Build Coastguard Worker #else
lshift128(w128_t * out,w128_t const * in,int shift)217*1208bc7eSAndroid Build Coastguard Worker static inline void lshift128(w128_t *out, w128_t const *in, int shift) {
218*1208bc7eSAndroid Build Coastguard Worker uint64_t th, tl, oh, ol;
219*1208bc7eSAndroid Build Coastguard Worker
220*1208bc7eSAndroid Build Coastguard Worker th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
221*1208bc7eSAndroid Build Coastguard Worker tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
222*1208bc7eSAndroid Build Coastguard Worker
223*1208bc7eSAndroid Build Coastguard Worker oh = th << (shift * 8);
224*1208bc7eSAndroid Build Coastguard Worker ol = tl << (shift * 8);
225*1208bc7eSAndroid Build Coastguard Worker oh |= tl >> (64 - shift * 8);
226*1208bc7eSAndroid Build Coastguard Worker out->u[1] = (uint32_t)(ol >> 32);
227*1208bc7eSAndroid Build Coastguard Worker out->u[0] = (uint32_t)ol;
228*1208bc7eSAndroid Build Coastguard Worker out->u[3] = (uint32_t)(oh >> 32);
229*1208bc7eSAndroid Build Coastguard Worker out->u[2] = (uint32_t)oh;
230*1208bc7eSAndroid Build Coastguard Worker }
231*1208bc7eSAndroid Build Coastguard Worker #endif
232*1208bc7eSAndroid Build Coastguard Worker #endif
233*1208bc7eSAndroid Build Coastguard Worker
234*1208bc7eSAndroid Build Coastguard Worker /**
235*1208bc7eSAndroid Build Coastguard Worker * This function represents the recursion formula.
236*1208bc7eSAndroid Build Coastguard Worker * @param r output
237*1208bc7eSAndroid Build Coastguard Worker * @param a a 128-bit part of the internal state array
238*1208bc7eSAndroid Build Coastguard Worker * @param b a 128-bit part of the internal state array
239*1208bc7eSAndroid Build Coastguard Worker * @param c a 128-bit part of the internal state array
240*1208bc7eSAndroid Build Coastguard Worker * @param d a 128-bit part of the internal state array
241*1208bc7eSAndroid Build Coastguard Worker */
242*1208bc7eSAndroid Build Coastguard Worker #if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
243*1208bc7eSAndroid Build Coastguard Worker #ifdef ONLY64
do_recursion(w128_t * r,w128_t * a,w128_t * b,w128_t * c,w128_t * d)244*1208bc7eSAndroid Build Coastguard Worker static inline void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
245*1208bc7eSAndroid Build Coastguard Worker w128_t *d) {
246*1208bc7eSAndroid Build Coastguard Worker w128_t x;
247*1208bc7eSAndroid Build Coastguard Worker w128_t y;
248*1208bc7eSAndroid Build Coastguard Worker
249*1208bc7eSAndroid Build Coastguard Worker lshift128(&x, a, SL2);
250*1208bc7eSAndroid Build Coastguard Worker rshift128(&y, c, SR2);
251*1208bc7eSAndroid Build Coastguard Worker r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK2) ^ y.u[0]
252*1208bc7eSAndroid Build Coastguard Worker ^ (d->u[0] << SL1);
253*1208bc7eSAndroid Build Coastguard Worker r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK1) ^ y.u[1]
254*1208bc7eSAndroid Build Coastguard Worker ^ (d->u[1] << SL1);
255*1208bc7eSAndroid Build Coastguard Worker r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK4) ^ y.u[2]
256*1208bc7eSAndroid Build Coastguard Worker ^ (d->u[2] << SL1);
257*1208bc7eSAndroid Build Coastguard Worker r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK3) ^ y.u[3]
258*1208bc7eSAndroid Build Coastguard Worker ^ (d->u[3] << SL1);
259*1208bc7eSAndroid Build Coastguard Worker }
260*1208bc7eSAndroid Build Coastguard Worker #else
do_recursion(w128_t * r,w128_t * a,w128_t * b,w128_t * c,w128_t * d)261*1208bc7eSAndroid Build Coastguard Worker static inline void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
262*1208bc7eSAndroid Build Coastguard Worker w128_t *d) {
263*1208bc7eSAndroid Build Coastguard Worker w128_t x;
264*1208bc7eSAndroid Build Coastguard Worker w128_t y;
265*1208bc7eSAndroid Build Coastguard Worker
266*1208bc7eSAndroid Build Coastguard Worker lshift128(&x, a, SL2);
267*1208bc7eSAndroid Build Coastguard Worker rshift128(&y, c, SR2);
268*1208bc7eSAndroid Build Coastguard Worker r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK1) ^ y.u[0]
269*1208bc7eSAndroid Build Coastguard Worker ^ (d->u[0] << SL1);
270*1208bc7eSAndroid Build Coastguard Worker r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK2) ^ y.u[1]
271*1208bc7eSAndroid Build Coastguard Worker ^ (d->u[1] << SL1);
272*1208bc7eSAndroid Build Coastguard Worker r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK3) ^ y.u[2]
273*1208bc7eSAndroid Build Coastguard Worker ^ (d->u[2] << SL1);
274*1208bc7eSAndroid Build Coastguard Worker r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK4) ^ y.u[3]
275*1208bc7eSAndroid Build Coastguard Worker ^ (d->u[3] << SL1);
276*1208bc7eSAndroid Build Coastguard Worker }
277*1208bc7eSAndroid Build Coastguard Worker #endif
278*1208bc7eSAndroid Build Coastguard Worker #endif
279*1208bc7eSAndroid Build Coastguard Worker
280*1208bc7eSAndroid Build Coastguard Worker #if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2))
281*1208bc7eSAndroid Build Coastguard Worker /**
282*1208bc7eSAndroid Build Coastguard Worker * This function fills the internal state array with pseudorandom
283*1208bc7eSAndroid Build Coastguard Worker * integers.
284*1208bc7eSAndroid Build Coastguard Worker */
gen_rand_all(sfmt_t * ctx)285*1208bc7eSAndroid Build Coastguard Worker static inline void gen_rand_all(sfmt_t *ctx) {
286*1208bc7eSAndroid Build Coastguard Worker int i;
287*1208bc7eSAndroid Build Coastguard Worker w128_t *r1, *r2;
288*1208bc7eSAndroid Build Coastguard Worker
289*1208bc7eSAndroid Build Coastguard Worker r1 = &ctx->sfmt[N - 2];
290*1208bc7eSAndroid Build Coastguard Worker r2 = &ctx->sfmt[N - 1];
291*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < N - POS1; i++) {
292*1208bc7eSAndroid Build Coastguard Worker do_recursion(&ctx->sfmt[i], &ctx->sfmt[i], &ctx->sfmt[i + POS1], r1,
293*1208bc7eSAndroid Build Coastguard Worker r2);
294*1208bc7eSAndroid Build Coastguard Worker r1 = r2;
295*1208bc7eSAndroid Build Coastguard Worker r2 = &ctx->sfmt[i];
296*1208bc7eSAndroid Build Coastguard Worker }
297*1208bc7eSAndroid Build Coastguard Worker for (; i < N; i++) {
298*1208bc7eSAndroid Build Coastguard Worker do_recursion(&ctx->sfmt[i], &ctx->sfmt[i], &ctx->sfmt[i + POS1 - N], r1,
299*1208bc7eSAndroid Build Coastguard Worker r2);
300*1208bc7eSAndroid Build Coastguard Worker r1 = r2;
301*1208bc7eSAndroid Build Coastguard Worker r2 = &ctx->sfmt[i];
302*1208bc7eSAndroid Build Coastguard Worker }
303*1208bc7eSAndroid Build Coastguard Worker }
304*1208bc7eSAndroid Build Coastguard Worker
305*1208bc7eSAndroid Build Coastguard Worker /**
306*1208bc7eSAndroid Build Coastguard Worker * This function fills the user-specified array with pseudorandom
307*1208bc7eSAndroid Build Coastguard Worker * integers.
308*1208bc7eSAndroid Build Coastguard Worker *
309*1208bc7eSAndroid Build Coastguard Worker * @param array an 128-bit array to be filled by pseudorandom numbers.
310*1208bc7eSAndroid Build Coastguard Worker * @param size number of 128-bit pseudorandom numbers to be generated.
311*1208bc7eSAndroid Build Coastguard Worker */
gen_rand_array(sfmt_t * ctx,w128_t * array,int size)312*1208bc7eSAndroid Build Coastguard Worker static inline void gen_rand_array(sfmt_t *ctx, w128_t *array, int size) {
313*1208bc7eSAndroid Build Coastguard Worker int i, j;
314*1208bc7eSAndroid Build Coastguard Worker w128_t *r1, *r2;
315*1208bc7eSAndroid Build Coastguard Worker
316*1208bc7eSAndroid Build Coastguard Worker r1 = &ctx->sfmt[N - 2];
317*1208bc7eSAndroid Build Coastguard Worker r2 = &ctx->sfmt[N - 1];
318*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < N - POS1; i++) {
319*1208bc7eSAndroid Build Coastguard Worker do_recursion(&array[i], &ctx->sfmt[i], &ctx->sfmt[i + POS1], r1, r2);
320*1208bc7eSAndroid Build Coastguard Worker r1 = r2;
321*1208bc7eSAndroid Build Coastguard Worker r2 = &array[i];
322*1208bc7eSAndroid Build Coastguard Worker }
323*1208bc7eSAndroid Build Coastguard Worker for (; i < N; i++) {
324*1208bc7eSAndroid Build Coastguard Worker do_recursion(&array[i], &ctx->sfmt[i], &array[i + POS1 - N], r1, r2);
325*1208bc7eSAndroid Build Coastguard Worker r1 = r2;
326*1208bc7eSAndroid Build Coastguard Worker r2 = &array[i];
327*1208bc7eSAndroid Build Coastguard Worker }
328*1208bc7eSAndroid Build Coastguard Worker for (; i < size - N; i++) {
329*1208bc7eSAndroid Build Coastguard Worker do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
330*1208bc7eSAndroid Build Coastguard Worker r1 = r2;
331*1208bc7eSAndroid Build Coastguard Worker r2 = &array[i];
332*1208bc7eSAndroid Build Coastguard Worker }
333*1208bc7eSAndroid Build Coastguard Worker for (j = 0; j < 2 * N - size; j++) {
334*1208bc7eSAndroid Build Coastguard Worker ctx->sfmt[j] = array[j + size - N];
335*1208bc7eSAndroid Build Coastguard Worker }
336*1208bc7eSAndroid Build Coastguard Worker for (; i < size; i++, j++) {
337*1208bc7eSAndroid Build Coastguard Worker do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2);
338*1208bc7eSAndroid Build Coastguard Worker r1 = r2;
339*1208bc7eSAndroid Build Coastguard Worker r2 = &array[i];
340*1208bc7eSAndroid Build Coastguard Worker ctx->sfmt[j] = array[i];
341*1208bc7eSAndroid Build Coastguard Worker }
342*1208bc7eSAndroid Build Coastguard Worker }
343*1208bc7eSAndroid Build Coastguard Worker #endif
344*1208bc7eSAndroid Build Coastguard Worker
345*1208bc7eSAndroid Build Coastguard Worker #if defined(BIG_ENDIAN64) && !defined(ONLY64) && !defined(HAVE_ALTIVEC)
swap(w128_t * array,int size)346*1208bc7eSAndroid Build Coastguard Worker static inline void swap(w128_t *array, int size) {
347*1208bc7eSAndroid Build Coastguard Worker int i;
348*1208bc7eSAndroid Build Coastguard Worker uint32_t x, y;
349*1208bc7eSAndroid Build Coastguard Worker
350*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < size; i++) {
351*1208bc7eSAndroid Build Coastguard Worker x = array[i].u[0];
352*1208bc7eSAndroid Build Coastguard Worker y = array[i].u[2];
353*1208bc7eSAndroid Build Coastguard Worker array[i].u[0] = array[i].u[1];
354*1208bc7eSAndroid Build Coastguard Worker array[i].u[2] = array[i].u[3];
355*1208bc7eSAndroid Build Coastguard Worker array[i].u[1] = x;
356*1208bc7eSAndroid Build Coastguard Worker array[i].u[3] = y;
357*1208bc7eSAndroid Build Coastguard Worker }
358*1208bc7eSAndroid Build Coastguard Worker }
359*1208bc7eSAndroid Build Coastguard Worker #endif
360*1208bc7eSAndroid Build Coastguard Worker /**
361*1208bc7eSAndroid Build Coastguard Worker * This function represents a function used in the initialization
362*1208bc7eSAndroid Build Coastguard Worker * by init_by_array
363*1208bc7eSAndroid Build Coastguard Worker * @param x 32-bit integer
364*1208bc7eSAndroid Build Coastguard Worker * @return 32-bit integer
365*1208bc7eSAndroid Build Coastguard Worker */
func1(uint32_t x)366*1208bc7eSAndroid Build Coastguard Worker static uint32_t func1(uint32_t x) {
367*1208bc7eSAndroid Build Coastguard Worker return (x ^ (x >> 27)) * (uint32_t)1664525UL;
368*1208bc7eSAndroid Build Coastguard Worker }
369*1208bc7eSAndroid Build Coastguard Worker
370*1208bc7eSAndroid Build Coastguard Worker /**
371*1208bc7eSAndroid Build Coastguard Worker * This function represents a function used in the initialization
372*1208bc7eSAndroid Build Coastguard Worker * by init_by_array
373*1208bc7eSAndroid Build Coastguard Worker * @param x 32-bit integer
374*1208bc7eSAndroid Build Coastguard Worker * @return 32-bit integer
375*1208bc7eSAndroid Build Coastguard Worker */
func2(uint32_t x)376*1208bc7eSAndroid Build Coastguard Worker static uint32_t func2(uint32_t x) {
377*1208bc7eSAndroid Build Coastguard Worker return (x ^ (x >> 27)) * (uint32_t)1566083941UL;
378*1208bc7eSAndroid Build Coastguard Worker }
379*1208bc7eSAndroid Build Coastguard Worker
380*1208bc7eSAndroid Build Coastguard Worker /**
381*1208bc7eSAndroid Build Coastguard Worker * This function certificate the period of 2^{MEXP}
382*1208bc7eSAndroid Build Coastguard Worker */
period_certification(sfmt_t * ctx)383*1208bc7eSAndroid Build Coastguard Worker static void period_certification(sfmt_t *ctx) {
384*1208bc7eSAndroid Build Coastguard Worker int inner = 0;
385*1208bc7eSAndroid Build Coastguard Worker int i, j;
386*1208bc7eSAndroid Build Coastguard Worker uint32_t work;
387*1208bc7eSAndroid Build Coastguard Worker uint32_t *psfmt32 = &ctx->sfmt[0].u[0];
388*1208bc7eSAndroid Build Coastguard Worker
389*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < 4; i++)
390*1208bc7eSAndroid Build Coastguard Worker inner ^= psfmt32[idxof(i)] & parity[i];
391*1208bc7eSAndroid Build Coastguard Worker for (i = 16; i > 0; i >>= 1)
392*1208bc7eSAndroid Build Coastguard Worker inner ^= inner >> i;
393*1208bc7eSAndroid Build Coastguard Worker inner &= 1;
394*1208bc7eSAndroid Build Coastguard Worker /* check OK */
395*1208bc7eSAndroid Build Coastguard Worker if (inner == 1) {
396*1208bc7eSAndroid Build Coastguard Worker return;
397*1208bc7eSAndroid Build Coastguard Worker }
398*1208bc7eSAndroid Build Coastguard Worker /* check NG, and modification */
399*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < 4; i++) {
400*1208bc7eSAndroid Build Coastguard Worker work = 1;
401*1208bc7eSAndroid Build Coastguard Worker for (j = 0; j < 32; j++) {
402*1208bc7eSAndroid Build Coastguard Worker if ((work & parity[i]) != 0) {
403*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof(i)] ^= work;
404*1208bc7eSAndroid Build Coastguard Worker return;
405*1208bc7eSAndroid Build Coastguard Worker }
406*1208bc7eSAndroid Build Coastguard Worker work = work << 1;
407*1208bc7eSAndroid Build Coastguard Worker }
408*1208bc7eSAndroid Build Coastguard Worker }
409*1208bc7eSAndroid Build Coastguard Worker }
410*1208bc7eSAndroid Build Coastguard Worker
411*1208bc7eSAndroid Build Coastguard Worker /*----------------
412*1208bc7eSAndroid Build Coastguard Worker PUBLIC FUNCTIONS
413*1208bc7eSAndroid Build Coastguard Worker ----------------*/
414*1208bc7eSAndroid Build Coastguard Worker /**
415*1208bc7eSAndroid Build Coastguard Worker * This function returns the identification string.
416*1208bc7eSAndroid Build Coastguard Worker * The string shows the word size, the Mersenne exponent,
417*1208bc7eSAndroid Build Coastguard Worker * and all parameters of this generator.
418*1208bc7eSAndroid Build Coastguard Worker */
get_idstring(void)419*1208bc7eSAndroid Build Coastguard Worker const char *get_idstring(void) {
420*1208bc7eSAndroid Build Coastguard Worker return IDSTR;
421*1208bc7eSAndroid Build Coastguard Worker }
422*1208bc7eSAndroid Build Coastguard Worker
423*1208bc7eSAndroid Build Coastguard Worker /**
424*1208bc7eSAndroid Build Coastguard Worker * This function returns the minimum size of array used for \b
425*1208bc7eSAndroid Build Coastguard Worker * fill_array32() function.
426*1208bc7eSAndroid Build Coastguard Worker * @return minimum size of array used for fill_array32() function.
427*1208bc7eSAndroid Build Coastguard Worker */
get_min_array_size32(void)428*1208bc7eSAndroid Build Coastguard Worker int get_min_array_size32(void) {
429*1208bc7eSAndroid Build Coastguard Worker return N32;
430*1208bc7eSAndroid Build Coastguard Worker }
431*1208bc7eSAndroid Build Coastguard Worker
432*1208bc7eSAndroid Build Coastguard Worker /**
433*1208bc7eSAndroid Build Coastguard Worker * This function returns the minimum size of array used for \b
434*1208bc7eSAndroid Build Coastguard Worker * fill_array64() function.
435*1208bc7eSAndroid Build Coastguard Worker * @return minimum size of array used for fill_array64() function.
436*1208bc7eSAndroid Build Coastguard Worker */
get_min_array_size64(void)437*1208bc7eSAndroid Build Coastguard Worker int get_min_array_size64(void) {
438*1208bc7eSAndroid Build Coastguard Worker return N64;
439*1208bc7eSAndroid Build Coastguard Worker }
440*1208bc7eSAndroid Build Coastguard Worker
441*1208bc7eSAndroid Build Coastguard Worker #ifndef ONLY64
442*1208bc7eSAndroid Build Coastguard Worker /**
443*1208bc7eSAndroid Build Coastguard Worker * This function generates and returns 32-bit pseudorandom number.
444*1208bc7eSAndroid Build Coastguard Worker * init_gen_rand or init_by_array must be called before this function.
445*1208bc7eSAndroid Build Coastguard Worker * @return 32-bit pseudorandom number
446*1208bc7eSAndroid Build Coastguard Worker */
gen_rand32(sfmt_t * ctx)447*1208bc7eSAndroid Build Coastguard Worker uint32_t gen_rand32(sfmt_t *ctx) {
448*1208bc7eSAndroid Build Coastguard Worker uint32_t r;
449*1208bc7eSAndroid Build Coastguard Worker uint32_t *psfmt32 = &ctx->sfmt[0].u[0];
450*1208bc7eSAndroid Build Coastguard Worker
451*1208bc7eSAndroid Build Coastguard Worker assert(ctx->initialized);
452*1208bc7eSAndroid Build Coastguard Worker if (ctx->idx >= N32) {
453*1208bc7eSAndroid Build Coastguard Worker gen_rand_all(ctx);
454*1208bc7eSAndroid Build Coastguard Worker ctx->idx = 0;
455*1208bc7eSAndroid Build Coastguard Worker }
456*1208bc7eSAndroid Build Coastguard Worker r = psfmt32[ctx->idx++];
457*1208bc7eSAndroid Build Coastguard Worker return r;
458*1208bc7eSAndroid Build Coastguard Worker }
459*1208bc7eSAndroid Build Coastguard Worker
460*1208bc7eSAndroid Build Coastguard Worker /* Generate a random integer in [0..limit). */
gen_rand32_range(sfmt_t * ctx,uint32_t limit)461*1208bc7eSAndroid Build Coastguard Worker uint32_t gen_rand32_range(sfmt_t *ctx, uint32_t limit) {
462*1208bc7eSAndroid Build Coastguard Worker uint32_t ret, above;
463*1208bc7eSAndroid Build Coastguard Worker
464*1208bc7eSAndroid Build Coastguard Worker above = 0xffffffffU - (0xffffffffU % limit);
465*1208bc7eSAndroid Build Coastguard Worker while (1) {
466*1208bc7eSAndroid Build Coastguard Worker ret = gen_rand32(ctx);
467*1208bc7eSAndroid Build Coastguard Worker if (ret < above) {
468*1208bc7eSAndroid Build Coastguard Worker ret %= limit;
469*1208bc7eSAndroid Build Coastguard Worker break;
470*1208bc7eSAndroid Build Coastguard Worker }
471*1208bc7eSAndroid Build Coastguard Worker }
472*1208bc7eSAndroid Build Coastguard Worker return ret;
473*1208bc7eSAndroid Build Coastguard Worker }
474*1208bc7eSAndroid Build Coastguard Worker #endif
475*1208bc7eSAndroid Build Coastguard Worker /**
476*1208bc7eSAndroid Build Coastguard Worker * This function generates and returns 64-bit pseudorandom number.
477*1208bc7eSAndroid Build Coastguard Worker * init_gen_rand or init_by_array must be called before this function.
478*1208bc7eSAndroid Build Coastguard Worker * The function gen_rand64 should not be called after gen_rand32,
479*1208bc7eSAndroid Build Coastguard Worker * unless an initialization is again executed.
480*1208bc7eSAndroid Build Coastguard Worker * @return 64-bit pseudorandom number
481*1208bc7eSAndroid Build Coastguard Worker */
gen_rand64(sfmt_t * ctx)482*1208bc7eSAndroid Build Coastguard Worker uint64_t gen_rand64(sfmt_t *ctx) {
483*1208bc7eSAndroid Build Coastguard Worker #if defined(BIG_ENDIAN64) && !defined(ONLY64)
484*1208bc7eSAndroid Build Coastguard Worker uint32_t r1, r2;
485*1208bc7eSAndroid Build Coastguard Worker uint32_t *psfmt32 = &ctx->sfmt[0].u[0];
486*1208bc7eSAndroid Build Coastguard Worker #else
487*1208bc7eSAndroid Build Coastguard Worker uint64_t r;
488*1208bc7eSAndroid Build Coastguard Worker uint64_t *psfmt64 = (uint64_t *)&ctx->sfmt[0].u[0];
489*1208bc7eSAndroid Build Coastguard Worker #endif
490*1208bc7eSAndroid Build Coastguard Worker
491*1208bc7eSAndroid Build Coastguard Worker assert(ctx->initialized);
492*1208bc7eSAndroid Build Coastguard Worker assert(ctx->idx % 2 == 0);
493*1208bc7eSAndroid Build Coastguard Worker
494*1208bc7eSAndroid Build Coastguard Worker if (ctx->idx >= N32) {
495*1208bc7eSAndroid Build Coastguard Worker gen_rand_all(ctx);
496*1208bc7eSAndroid Build Coastguard Worker ctx->idx = 0;
497*1208bc7eSAndroid Build Coastguard Worker }
498*1208bc7eSAndroid Build Coastguard Worker #if defined(BIG_ENDIAN64) && !defined(ONLY64)
499*1208bc7eSAndroid Build Coastguard Worker r1 = psfmt32[ctx->idx];
500*1208bc7eSAndroid Build Coastguard Worker r2 = psfmt32[ctx->idx + 1];
501*1208bc7eSAndroid Build Coastguard Worker ctx->idx += 2;
502*1208bc7eSAndroid Build Coastguard Worker return ((uint64_t)r2 << 32) | r1;
503*1208bc7eSAndroid Build Coastguard Worker #else
504*1208bc7eSAndroid Build Coastguard Worker r = psfmt64[ctx->idx / 2];
505*1208bc7eSAndroid Build Coastguard Worker ctx->idx += 2;
506*1208bc7eSAndroid Build Coastguard Worker return r;
507*1208bc7eSAndroid Build Coastguard Worker #endif
508*1208bc7eSAndroid Build Coastguard Worker }
509*1208bc7eSAndroid Build Coastguard Worker
510*1208bc7eSAndroid Build Coastguard Worker /* Generate a random integer in [0..limit). */
gen_rand64_range(sfmt_t * ctx,uint64_t limit)511*1208bc7eSAndroid Build Coastguard Worker uint64_t gen_rand64_range(sfmt_t *ctx, uint64_t limit) {
512*1208bc7eSAndroid Build Coastguard Worker uint64_t ret, above;
513*1208bc7eSAndroid Build Coastguard Worker
514*1208bc7eSAndroid Build Coastguard Worker above = KQU(0xffffffffffffffff) - (KQU(0xffffffffffffffff) % limit);
515*1208bc7eSAndroid Build Coastguard Worker while (1) {
516*1208bc7eSAndroid Build Coastguard Worker ret = gen_rand64(ctx);
517*1208bc7eSAndroid Build Coastguard Worker if (ret < above) {
518*1208bc7eSAndroid Build Coastguard Worker ret %= limit;
519*1208bc7eSAndroid Build Coastguard Worker break;
520*1208bc7eSAndroid Build Coastguard Worker }
521*1208bc7eSAndroid Build Coastguard Worker }
522*1208bc7eSAndroid Build Coastguard Worker return ret;
523*1208bc7eSAndroid Build Coastguard Worker }
524*1208bc7eSAndroid Build Coastguard Worker
525*1208bc7eSAndroid Build Coastguard Worker #ifndef ONLY64
526*1208bc7eSAndroid Build Coastguard Worker /**
527*1208bc7eSAndroid Build Coastguard Worker * This function generates pseudorandom 32-bit integers in the
528*1208bc7eSAndroid Build Coastguard Worker * specified array[] by one call. The number of pseudorandom integers
529*1208bc7eSAndroid Build Coastguard Worker * is specified by the argument size, which must be at least 624 and a
530*1208bc7eSAndroid Build Coastguard Worker * multiple of four. The generation by this function is much faster
531*1208bc7eSAndroid Build Coastguard Worker * than the following gen_rand function.
532*1208bc7eSAndroid Build Coastguard Worker *
533*1208bc7eSAndroid Build Coastguard Worker * For initialization, init_gen_rand or init_by_array must be called
534*1208bc7eSAndroid Build Coastguard Worker * before the first call of this function. This function can not be
535*1208bc7eSAndroid Build Coastguard Worker * used after calling gen_rand function, without initialization.
536*1208bc7eSAndroid Build Coastguard Worker *
537*1208bc7eSAndroid Build Coastguard Worker * @param array an array where pseudorandom 32-bit integers are filled
538*1208bc7eSAndroid Build Coastguard Worker * by this function. The pointer to the array must be \b "aligned"
539*1208bc7eSAndroid Build Coastguard Worker * (namely, must be a multiple of 16) in the SIMD version, since it
540*1208bc7eSAndroid Build Coastguard Worker * refers to the address of a 128-bit integer. In the standard C
541*1208bc7eSAndroid Build Coastguard Worker * version, the pointer is arbitrary.
542*1208bc7eSAndroid Build Coastguard Worker *
543*1208bc7eSAndroid Build Coastguard Worker * @param size the number of 32-bit pseudorandom integers to be
544*1208bc7eSAndroid Build Coastguard Worker * generated. size must be a multiple of 4, and greater than or equal
545*1208bc7eSAndroid Build Coastguard Worker * to (MEXP / 128 + 1) * 4.
546*1208bc7eSAndroid Build Coastguard Worker *
547*1208bc7eSAndroid Build Coastguard Worker * @note \b memalign or \b posix_memalign is available to get aligned
548*1208bc7eSAndroid Build Coastguard Worker * memory. Mac OSX doesn't have these functions, but \b malloc of OSX
549*1208bc7eSAndroid Build Coastguard Worker * returns the pointer to the aligned memory block.
550*1208bc7eSAndroid Build Coastguard Worker */
fill_array32(sfmt_t * ctx,uint32_t * array,int size)551*1208bc7eSAndroid Build Coastguard Worker void fill_array32(sfmt_t *ctx, uint32_t *array, int size) {
552*1208bc7eSAndroid Build Coastguard Worker assert(ctx->initialized);
553*1208bc7eSAndroid Build Coastguard Worker assert(ctx->idx == N32);
554*1208bc7eSAndroid Build Coastguard Worker assert(size % 4 == 0);
555*1208bc7eSAndroid Build Coastguard Worker assert(size >= N32);
556*1208bc7eSAndroid Build Coastguard Worker
557*1208bc7eSAndroid Build Coastguard Worker gen_rand_array(ctx, (w128_t *)array, size / 4);
558*1208bc7eSAndroid Build Coastguard Worker ctx->idx = N32;
559*1208bc7eSAndroid Build Coastguard Worker }
560*1208bc7eSAndroid Build Coastguard Worker #endif
561*1208bc7eSAndroid Build Coastguard Worker
562*1208bc7eSAndroid Build Coastguard Worker /**
563*1208bc7eSAndroid Build Coastguard Worker * This function generates pseudorandom 64-bit integers in the
564*1208bc7eSAndroid Build Coastguard Worker * specified array[] by one call. The number of pseudorandom integers
565*1208bc7eSAndroid Build Coastguard Worker * is specified by the argument size, which must be at least 312 and a
566*1208bc7eSAndroid Build Coastguard Worker * multiple of two. The generation by this function is much faster
567*1208bc7eSAndroid Build Coastguard Worker * than the following gen_rand function.
568*1208bc7eSAndroid Build Coastguard Worker *
569*1208bc7eSAndroid Build Coastguard Worker * For initialization, init_gen_rand or init_by_array must be called
570*1208bc7eSAndroid Build Coastguard Worker * before the first call of this function. This function can not be
571*1208bc7eSAndroid Build Coastguard Worker * used after calling gen_rand function, without initialization.
572*1208bc7eSAndroid Build Coastguard Worker *
573*1208bc7eSAndroid Build Coastguard Worker * @param array an array where pseudorandom 64-bit integers are filled
574*1208bc7eSAndroid Build Coastguard Worker * by this function. The pointer to the array must be "aligned"
575*1208bc7eSAndroid Build Coastguard Worker * (namely, must be a multiple of 16) in the SIMD version, since it
576*1208bc7eSAndroid Build Coastguard Worker * refers to the address of a 128-bit integer. In the standard C
577*1208bc7eSAndroid Build Coastguard Worker * version, the pointer is arbitrary.
578*1208bc7eSAndroid Build Coastguard Worker *
579*1208bc7eSAndroid Build Coastguard Worker * @param size the number of 64-bit pseudorandom integers to be
580*1208bc7eSAndroid Build Coastguard Worker * generated. size must be a multiple of 2, and greater than or equal
581*1208bc7eSAndroid Build Coastguard Worker * to (MEXP / 128 + 1) * 2
582*1208bc7eSAndroid Build Coastguard Worker *
583*1208bc7eSAndroid Build Coastguard Worker * @note \b memalign or \b posix_memalign is available to get aligned
584*1208bc7eSAndroid Build Coastguard Worker * memory. Mac OSX doesn't have these functions, but \b malloc of OSX
585*1208bc7eSAndroid Build Coastguard Worker * returns the pointer to the aligned memory block.
586*1208bc7eSAndroid Build Coastguard Worker */
fill_array64(sfmt_t * ctx,uint64_t * array,int size)587*1208bc7eSAndroid Build Coastguard Worker void fill_array64(sfmt_t *ctx, uint64_t *array, int size) {
588*1208bc7eSAndroid Build Coastguard Worker assert(ctx->initialized);
589*1208bc7eSAndroid Build Coastguard Worker assert(ctx->idx == N32);
590*1208bc7eSAndroid Build Coastguard Worker assert(size % 2 == 0);
591*1208bc7eSAndroid Build Coastguard Worker assert(size >= N64);
592*1208bc7eSAndroid Build Coastguard Worker
593*1208bc7eSAndroid Build Coastguard Worker gen_rand_array(ctx, (w128_t *)array, size / 2);
594*1208bc7eSAndroid Build Coastguard Worker ctx->idx = N32;
595*1208bc7eSAndroid Build Coastguard Worker
596*1208bc7eSAndroid Build Coastguard Worker #if defined(BIG_ENDIAN64) && !defined(ONLY64)
597*1208bc7eSAndroid Build Coastguard Worker swap((w128_t *)array, size /2);
598*1208bc7eSAndroid Build Coastguard Worker #endif
599*1208bc7eSAndroid Build Coastguard Worker }
600*1208bc7eSAndroid Build Coastguard Worker
601*1208bc7eSAndroid Build Coastguard Worker /**
602*1208bc7eSAndroid Build Coastguard Worker * This function initializes the internal state array with a 32-bit
603*1208bc7eSAndroid Build Coastguard Worker * integer seed.
604*1208bc7eSAndroid Build Coastguard Worker *
605*1208bc7eSAndroid Build Coastguard Worker * @param seed a 32-bit integer used as the seed.
606*1208bc7eSAndroid Build Coastguard Worker */
init_gen_rand(uint32_t seed)607*1208bc7eSAndroid Build Coastguard Worker sfmt_t *init_gen_rand(uint32_t seed) {
608*1208bc7eSAndroid Build Coastguard Worker void *p;
609*1208bc7eSAndroid Build Coastguard Worker sfmt_t *ctx;
610*1208bc7eSAndroid Build Coastguard Worker int i;
611*1208bc7eSAndroid Build Coastguard Worker uint32_t *psfmt32;
612*1208bc7eSAndroid Build Coastguard Worker
613*1208bc7eSAndroid Build Coastguard Worker if (posix_memalign(&p, sizeof(w128_t), sizeof(sfmt_t)) != 0) {
614*1208bc7eSAndroid Build Coastguard Worker return NULL;
615*1208bc7eSAndroid Build Coastguard Worker }
616*1208bc7eSAndroid Build Coastguard Worker ctx = (sfmt_t *)p;
617*1208bc7eSAndroid Build Coastguard Worker psfmt32 = &ctx->sfmt[0].u[0];
618*1208bc7eSAndroid Build Coastguard Worker
619*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof(0)] = seed;
620*1208bc7eSAndroid Build Coastguard Worker for (i = 1; i < N32; i++) {
621*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof(i)] = 1812433253UL * (psfmt32[idxof(i - 1)]
622*1208bc7eSAndroid Build Coastguard Worker ^ (psfmt32[idxof(i - 1)] >> 30))
623*1208bc7eSAndroid Build Coastguard Worker + i;
624*1208bc7eSAndroid Build Coastguard Worker }
625*1208bc7eSAndroid Build Coastguard Worker ctx->idx = N32;
626*1208bc7eSAndroid Build Coastguard Worker period_certification(ctx);
627*1208bc7eSAndroid Build Coastguard Worker ctx->initialized = 1;
628*1208bc7eSAndroid Build Coastguard Worker
629*1208bc7eSAndroid Build Coastguard Worker return ctx;
630*1208bc7eSAndroid Build Coastguard Worker }
631*1208bc7eSAndroid Build Coastguard Worker
632*1208bc7eSAndroid Build Coastguard Worker /**
633*1208bc7eSAndroid Build Coastguard Worker * This function initializes the internal state array,
634*1208bc7eSAndroid Build Coastguard Worker * with an array of 32-bit integers used as the seeds
635*1208bc7eSAndroid Build Coastguard Worker * @param init_key the array of 32-bit integers, used as a seed.
636*1208bc7eSAndroid Build Coastguard Worker * @param key_length the length of init_key.
637*1208bc7eSAndroid Build Coastguard Worker */
init_by_array(uint32_t * init_key,int key_length)638*1208bc7eSAndroid Build Coastguard Worker sfmt_t *init_by_array(uint32_t *init_key, int key_length) {
639*1208bc7eSAndroid Build Coastguard Worker void *p;
640*1208bc7eSAndroid Build Coastguard Worker sfmt_t *ctx;
641*1208bc7eSAndroid Build Coastguard Worker int i, j, count;
642*1208bc7eSAndroid Build Coastguard Worker uint32_t r;
643*1208bc7eSAndroid Build Coastguard Worker int lag;
644*1208bc7eSAndroid Build Coastguard Worker int mid;
645*1208bc7eSAndroid Build Coastguard Worker int size = N * 4;
646*1208bc7eSAndroid Build Coastguard Worker uint32_t *psfmt32;
647*1208bc7eSAndroid Build Coastguard Worker
648*1208bc7eSAndroid Build Coastguard Worker if (posix_memalign(&p, sizeof(w128_t), sizeof(sfmt_t)) != 0) {
649*1208bc7eSAndroid Build Coastguard Worker return NULL;
650*1208bc7eSAndroid Build Coastguard Worker }
651*1208bc7eSAndroid Build Coastguard Worker ctx = (sfmt_t *)p;
652*1208bc7eSAndroid Build Coastguard Worker psfmt32 = &ctx->sfmt[0].u[0];
653*1208bc7eSAndroid Build Coastguard Worker
654*1208bc7eSAndroid Build Coastguard Worker if (size >= 623) {
655*1208bc7eSAndroid Build Coastguard Worker lag = 11;
656*1208bc7eSAndroid Build Coastguard Worker } else if (size >= 68) {
657*1208bc7eSAndroid Build Coastguard Worker lag = 7;
658*1208bc7eSAndroid Build Coastguard Worker } else if (size >= 39) {
659*1208bc7eSAndroid Build Coastguard Worker lag = 5;
660*1208bc7eSAndroid Build Coastguard Worker } else {
661*1208bc7eSAndroid Build Coastguard Worker lag = 3;
662*1208bc7eSAndroid Build Coastguard Worker }
663*1208bc7eSAndroid Build Coastguard Worker mid = (size - lag) / 2;
664*1208bc7eSAndroid Build Coastguard Worker
665*1208bc7eSAndroid Build Coastguard Worker memset(ctx->sfmt, 0x8b, sizeof(ctx->sfmt));
666*1208bc7eSAndroid Build Coastguard Worker if (key_length + 1 > N32) {
667*1208bc7eSAndroid Build Coastguard Worker count = key_length + 1;
668*1208bc7eSAndroid Build Coastguard Worker } else {
669*1208bc7eSAndroid Build Coastguard Worker count = N32;
670*1208bc7eSAndroid Build Coastguard Worker }
671*1208bc7eSAndroid Build Coastguard Worker r = func1(psfmt32[idxof(0)] ^ psfmt32[idxof(mid)]
672*1208bc7eSAndroid Build Coastguard Worker ^ psfmt32[idxof(N32 - 1)]);
673*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof(mid)] += r;
674*1208bc7eSAndroid Build Coastguard Worker r += key_length;
675*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof(mid + lag)] += r;
676*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof(0)] = r;
677*1208bc7eSAndroid Build Coastguard Worker
678*1208bc7eSAndroid Build Coastguard Worker count--;
679*1208bc7eSAndroid Build Coastguard Worker for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
680*1208bc7eSAndroid Build Coastguard Worker r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
681*1208bc7eSAndroid Build Coastguard Worker ^ psfmt32[idxof((i + N32 - 1) % N32)]);
682*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof((i + mid) % N32)] += r;
683*1208bc7eSAndroid Build Coastguard Worker r += init_key[j] + i;
684*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof((i + mid + lag) % N32)] += r;
685*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof(i)] = r;
686*1208bc7eSAndroid Build Coastguard Worker i = (i + 1) % N32;
687*1208bc7eSAndroid Build Coastguard Worker }
688*1208bc7eSAndroid Build Coastguard Worker for (; j < count; j++) {
689*1208bc7eSAndroid Build Coastguard Worker r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)]
690*1208bc7eSAndroid Build Coastguard Worker ^ psfmt32[idxof((i + N32 - 1) % N32)]);
691*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof((i + mid) % N32)] += r;
692*1208bc7eSAndroid Build Coastguard Worker r += i;
693*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof((i + mid + lag) % N32)] += r;
694*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof(i)] = r;
695*1208bc7eSAndroid Build Coastguard Worker i = (i + 1) % N32;
696*1208bc7eSAndroid Build Coastguard Worker }
697*1208bc7eSAndroid Build Coastguard Worker for (j = 0; j < N32; j++) {
698*1208bc7eSAndroid Build Coastguard Worker r = func2(psfmt32[idxof(i)] + psfmt32[idxof((i + mid) % N32)]
699*1208bc7eSAndroid Build Coastguard Worker + psfmt32[idxof((i + N32 - 1) % N32)]);
700*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof((i + mid) % N32)] ^= r;
701*1208bc7eSAndroid Build Coastguard Worker r -= i;
702*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof((i + mid + lag) % N32)] ^= r;
703*1208bc7eSAndroid Build Coastguard Worker psfmt32[idxof(i)] = r;
704*1208bc7eSAndroid Build Coastguard Worker i = (i + 1) % N32;
705*1208bc7eSAndroid Build Coastguard Worker }
706*1208bc7eSAndroid Build Coastguard Worker
707*1208bc7eSAndroid Build Coastguard Worker ctx->idx = N32;
708*1208bc7eSAndroid Build Coastguard Worker period_certification(ctx);
709*1208bc7eSAndroid Build Coastguard Worker ctx->initialized = 1;
710*1208bc7eSAndroid Build Coastguard Worker
711*1208bc7eSAndroid Build Coastguard Worker return ctx;
712*1208bc7eSAndroid Build Coastguard Worker }
713*1208bc7eSAndroid Build Coastguard Worker
fini_gen_rand(sfmt_t * ctx)714*1208bc7eSAndroid Build Coastguard Worker void fini_gen_rand(sfmt_t *ctx) {
715*1208bc7eSAndroid Build Coastguard Worker assert(ctx != NULL);
716*1208bc7eSAndroid Build Coastguard Worker
717*1208bc7eSAndroid Build Coastguard Worker ctx->initialized = 0;
718*1208bc7eSAndroid Build Coastguard Worker free(ctx);
719*1208bc7eSAndroid Build Coastguard Worker }
720