xref: /aosp_15_r20/external/jemalloc_new/test/src/SFMT.c (revision 1208bc7e437ced7eb82efac44ba17e3beba411da)
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