xref: /freebsd/sys/contrib/pcg-c/include/pcg_variants.h (revision 9119bafbaf52e5d86e5879e54b38c5aba3efa2e9)
1*9119bafbSConrad Meyer /*
2*9119bafbSConrad Meyer  * PCG Random Number Generation for C.
3*9119bafbSConrad Meyer  *
4*9119bafbSConrad Meyer  * Copyright 2014-2019 Melissa O'Neill <oneill@pcg-random.org>,
5*9119bafbSConrad Meyer  *                     and the PCG Project contributors.
6*9119bafbSConrad Meyer  *
7*9119bafbSConrad Meyer  * SPDX-License-Identifier: (Apache-2.0 OR MIT)
8*9119bafbSConrad Meyer  *
9*9119bafbSConrad Meyer  * Licensed under the Apache License, Version 2.0 (provided in
10*9119bafbSConrad Meyer  * LICENSE-APACHE.txt and at http://www.apache.org/licenses/LICENSE-2.0)
11*9119bafbSConrad Meyer  * or under the MIT license (provided in LICENSE-MIT.txt and at
12*9119bafbSConrad Meyer  * http://opensource.org/licenses/MIT), at your option. This file may not
13*9119bafbSConrad Meyer  * be copied, modified, or distributed except according to those terms.
14*9119bafbSConrad Meyer  *
15*9119bafbSConrad Meyer  * Distributed on an "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, either
16*9119bafbSConrad Meyer  * express or implied.  See your chosen license for details.
17*9119bafbSConrad Meyer  *
18*9119bafbSConrad Meyer  * For additional information about the PCG random number generation scheme,
19*9119bafbSConrad Meyer  * visit http://www.pcg-random.org/.
20*9119bafbSConrad Meyer  */
21*9119bafbSConrad Meyer 
22*9119bafbSConrad Meyer /*
23*9119bafbSConrad Meyer  * This code is derived from the canonical C++ PCG implementation, which
24*9119bafbSConrad Meyer  * has many additional features and is preferable if you can use C++ in
25*9119bafbSConrad Meyer  * your project.
26*9119bafbSConrad Meyer  *
27*9119bafbSConrad Meyer  * Much of the derivation was performed mechanically.  In particular, the
28*9119bafbSConrad Meyer  * output functions were generated by compiling the C++ output functions
29*9119bafbSConrad Meyer  * into LLVM bitcode and then transforming that using the LLVM C backend
30*9119bafbSConrad Meyer  * (from https://github.com/draperlaboratory/llvm-cbe), and then
31*9119bafbSConrad Meyer  * postprocessing and hand editing the output.
32*9119bafbSConrad Meyer  *
33*9119bafbSConrad Meyer  * Much of the remaining code was generated by C-preprocessor metaprogramming.
34*9119bafbSConrad Meyer  */
35*9119bafbSConrad Meyer 
36*9119bafbSConrad Meyer #ifndef PCG_VARIANTS_H_INCLUDED
37*9119bafbSConrad Meyer #define PCG_VARIANTS_H_INCLUDED 1
38*9119bafbSConrad Meyer 
39*9119bafbSConrad Meyer #include <inttypes.h>
40*9119bafbSConrad Meyer 
41*9119bafbSConrad Meyer #if __SIZEOF_INT128__
42*9119bafbSConrad Meyer     typedef __uint128_t pcg128_t;
43*9119bafbSConrad Meyer     #define PCG_128BIT_CONSTANT(high,low) \
44*9119bafbSConrad Meyer             ((((pcg128_t)high) << 64) + low)
45*9119bafbSConrad Meyer     #define PCG_HAS_128BIT_OPS 1
46*9119bafbSConrad Meyer #endif
47*9119bafbSConrad Meyer 
48*9119bafbSConrad Meyer #if __GNUC_GNU_INLINE__  &&  !defined(__cplusplus)
49*9119bafbSConrad Meyer     #error Nonstandard GNU inlining semantics. Compile with -std=c99 or better.
50*9119bafbSConrad Meyer     /* We could instead use macros PCG_INLINE and PCG_EXTERN_INLINE
51*9119bafbSConrad Meyer        but better to just reject ancient C code. */
52*9119bafbSConrad Meyer #endif
53*9119bafbSConrad Meyer 
54*9119bafbSConrad Meyer #if __cplusplus
55*9119bafbSConrad Meyer extern "C" {
56*9119bafbSConrad Meyer #endif
57*9119bafbSConrad Meyer 
58*9119bafbSConrad Meyer /*
59*9119bafbSConrad Meyer  * Rotate helper functions.
60*9119bafbSConrad Meyer  */
61*9119bafbSConrad Meyer 
62*9119bafbSConrad Meyer inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot)
63*9119bafbSConrad Meyer {
64*9119bafbSConrad Meyer /* Unfortunately, clang is kinda pathetic when it comes to properly
65*9119bafbSConrad Meyer  * recognizing idiomatic rotate code, so for clang we actually provide
66*9119bafbSConrad Meyer  * assembler directives (enabled with PCG_USE_INLINE_ASM).  Boo, hiss.
67*9119bafbSConrad Meyer  */
68*9119bafbSConrad Meyer #if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__  || __i386__)
69*9119bafbSConrad Meyer     asm ("rorb   %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
70*9119bafbSConrad Meyer     return value;
71*9119bafbSConrad Meyer #else
72*9119bafbSConrad Meyer     return (value >> rot) | (value << ((- rot) & 7));
73*9119bafbSConrad Meyer #endif
74*9119bafbSConrad Meyer }
75*9119bafbSConrad Meyer 
76*9119bafbSConrad Meyer inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot)
77*9119bafbSConrad Meyer {
78*9119bafbSConrad Meyer #if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__  || __i386__)
79*9119bafbSConrad Meyer     asm ("rorw   %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
80*9119bafbSConrad Meyer     return value;
81*9119bafbSConrad Meyer #else
82*9119bafbSConrad Meyer     return (value >> rot) | (value << ((- rot) & 15));
83*9119bafbSConrad Meyer #endif
84*9119bafbSConrad Meyer }
85*9119bafbSConrad Meyer 
86*9119bafbSConrad Meyer inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot)
87*9119bafbSConrad Meyer {
88*9119bafbSConrad Meyer #if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__  || __i386__)
89*9119bafbSConrad Meyer     asm ("rorl   %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
90*9119bafbSConrad Meyer     return value;
91*9119bafbSConrad Meyer #else
92*9119bafbSConrad Meyer     return (value >> rot) | (value << ((- rot) & 31));
93*9119bafbSConrad Meyer #endif
94*9119bafbSConrad Meyer }
95*9119bafbSConrad Meyer 
96*9119bafbSConrad Meyer inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot)
97*9119bafbSConrad Meyer {
98*9119bafbSConrad Meyer #if 0 && PCG_USE_INLINE_ASM && __clang__ && __x86_64__
99*9119bafbSConrad Meyer     /* For whatever reason, clang actually *does* generate rotq by
100*9119bafbSConrad Meyer        itself, so we don't need this code. */
101*9119bafbSConrad Meyer     asm ("rorq   %%cl, %0" : "=r" (value) : "0" (value), "c" (rot));
102*9119bafbSConrad Meyer     return value;
103*9119bafbSConrad Meyer #else
104*9119bafbSConrad Meyer     return (value >> rot) | (value << ((- rot) & 63));
105*9119bafbSConrad Meyer #endif
106*9119bafbSConrad Meyer }
107*9119bafbSConrad Meyer 
108*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
109*9119bafbSConrad Meyer inline pcg128_t pcg_rotr_128(pcg128_t value, unsigned int rot)
110*9119bafbSConrad Meyer {
111*9119bafbSConrad Meyer     return (value >> rot) | (value << ((- rot) & 127));
112*9119bafbSConrad Meyer }
113*9119bafbSConrad Meyer #endif
114*9119bafbSConrad Meyer 
115*9119bafbSConrad Meyer /*
116*9119bafbSConrad Meyer  * Output functions.  These are the core of the PCG generation scheme.
117*9119bafbSConrad Meyer  */
118*9119bafbSConrad Meyer 
119*9119bafbSConrad Meyer /* XSH RS */
120*9119bafbSConrad Meyer 
121*9119bafbSConrad Meyer inline uint8_t pcg_output_xsh_rs_16_8(uint16_t state)
122*9119bafbSConrad Meyer {
123*9119bafbSConrad Meyer     return (uint8_t)(((state >> 7u) ^ state) >> ((state >> 14u) + 3u));
124*9119bafbSConrad Meyer }
125*9119bafbSConrad Meyer 
126*9119bafbSConrad Meyer inline uint16_t pcg_output_xsh_rs_32_16(uint32_t state)
127*9119bafbSConrad Meyer {
128*9119bafbSConrad Meyer     return (uint16_t)(((state >> 11u) ^ state) >> ((state >> 30u) + 11u));
129*9119bafbSConrad Meyer }
130*9119bafbSConrad Meyer 
131*9119bafbSConrad Meyer inline uint32_t pcg_output_xsh_rs_64_32(uint64_t state)
132*9119bafbSConrad Meyer {
133*9119bafbSConrad Meyer 
134*9119bafbSConrad Meyer     return (uint32_t)(((state >> 22u) ^ state) >> ((state >> 61u) + 22u));
135*9119bafbSConrad Meyer }
136*9119bafbSConrad Meyer 
137*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
138*9119bafbSConrad Meyer inline uint64_t pcg_output_xsh_rs_128_64(pcg128_t state)
139*9119bafbSConrad Meyer {
140*9119bafbSConrad Meyer     return (uint64_t)(((state >> 43u) ^ state) >> ((state >> 124u) + 45u));
141*9119bafbSConrad Meyer }
142*9119bafbSConrad Meyer #endif
143*9119bafbSConrad Meyer 
144*9119bafbSConrad Meyer /* XSH RR */
145*9119bafbSConrad Meyer 
146*9119bafbSConrad Meyer inline uint8_t pcg_output_xsh_rr_16_8(uint16_t state)
147*9119bafbSConrad Meyer {
148*9119bafbSConrad Meyer     return pcg_rotr_8(((state >> 5u) ^ state) >> 5u, state >> 13u);
149*9119bafbSConrad Meyer }
150*9119bafbSConrad Meyer 
151*9119bafbSConrad Meyer inline uint16_t pcg_output_xsh_rr_32_16(uint32_t state)
152*9119bafbSConrad Meyer {
153*9119bafbSConrad Meyer     return pcg_rotr_16(((state >> 10u) ^ state) >> 12u, state >> 28u);
154*9119bafbSConrad Meyer }
155*9119bafbSConrad Meyer 
156*9119bafbSConrad Meyer inline uint32_t pcg_output_xsh_rr_64_32(uint64_t state)
157*9119bafbSConrad Meyer {
158*9119bafbSConrad Meyer     return pcg_rotr_32(((state >> 18u) ^ state) >> 27u, state >> 59u);
159*9119bafbSConrad Meyer }
160*9119bafbSConrad Meyer 
161*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
162*9119bafbSConrad Meyer inline uint64_t pcg_output_xsh_rr_128_64(pcg128_t state)
163*9119bafbSConrad Meyer {
164*9119bafbSConrad Meyer     return pcg_rotr_64(((state >> 35u) ^ state) >> 58u, state >> 122u);
165*9119bafbSConrad Meyer }
166*9119bafbSConrad Meyer #endif
167*9119bafbSConrad Meyer 
168*9119bafbSConrad Meyer /* RXS M XS */
169*9119bafbSConrad Meyer 
170*9119bafbSConrad Meyer inline uint8_t pcg_output_rxs_m_xs_8_8(uint8_t state)
171*9119bafbSConrad Meyer {
172*9119bafbSConrad Meyer     uint8_t word = ((state >> ((state >> 6u) + 2u)) ^ state) * 217u;
173*9119bafbSConrad Meyer     return (word >> 6u) ^ word;
174*9119bafbSConrad Meyer }
175*9119bafbSConrad Meyer 
176*9119bafbSConrad Meyer inline uint16_t pcg_output_rxs_m_xs_16_16(uint16_t state)
177*9119bafbSConrad Meyer {
178*9119bafbSConrad Meyer     uint16_t word = ((state >> ((state >> 13u) + 3u)) ^ state) * 62169u;
179*9119bafbSConrad Meyer     return (word >> 11u) ^ word;
180*9119bafbSConrad Meyer }
181*9119bafbSConrad Meyer 
182*9119bafbSConrad Meyer inline uint32_t pcg_output_rxs_m_xs_32_32(uint32_t state)
183*9119bafbSConrad Meyer {
184*9119bafbSConrad Meyer     uint32_t word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
185*9119bafbSConrad Meyer     return (word >> 22u) ^ word;
186*9119bafbSConrad Meyer }
187*9119bafbSConrad Meyer 
188*9119bafbSConrad Meyer inline uint64_t pcg_output_rxs_m_xs_64_64(uint64_t state)
189*9119bafbSConrad Meyer {
190*9119bafbSConrad Meyer     uint64_t word = ((state >> ((state >> 59u) + 5u)) ^ state)
191*9119bafbSConrad Meyer                     * 12605985483714917081ull;
192*9119bafbSConrad Meyer     return (word >> 43u) ^ word;
193*9119bafbSConrad Meyer }
194*9119bafbSConrad Meyer 
195*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
196*9119bafbSConrad Meyer inline pcg128_t pcg_output_rxs_m_xs_128_128(pcg128_t state)
197*9119bafbSConrad Meyer {
198*9119bafbSConrad Meyer     pcg128_t word = ((state >> ((state >> 122u) + 6u)) ^ state)
199*9119bafbSConrad Meyer                        * (PCG_128BIT_CONSTANT(17766728186571221404ULL,
200*9119bafbSConrad Meyer                                               12605985483714917081ULL));
201*9119bafbSConrad Meyer     /* 327738287884841127335028083622016905945 */
202*9119bafbSConrad Meyer     return (word >> 86u) ^ word;
203*9119bafbSConrad Meyer }
204*9119bafbSConrad Meyer #endif
205*9119bafbSConrad Meyer 
206*9119bafbSConrad Meyer /* RXS M */
207*9119bafbSConrad Meyer 
208*9119bafbSConrad Meyer inline uint8_t pcg_output_rxs_m_16_8(uint16_t state)
209*9119bafbSConrad Meyer {
210*9119bafbSConrad Meyer     return (((state >> ((state >> 13u) + 3u)) ^ state) * 62169u) >> 8u;
211*9119bafbSConrad Meyer }
212*9119bafbSConrad Meyer 
213*9119bafbSConrad Meyer inline uint16_t pcg_output_rxs_m_32_16(uint32_t state)
214*9119bafbSConrad Meyer {
215*9119bafbSConrad Meyer     return (((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u) >> 16u;
216*9119bafbSConrad Meyer }
217*9119bafbSConrad Meyer 
218*9119bafbSConrad Meyer inline uint32_t pcg_output_rxs_m_64_32(uint64_t state)
219*9119bafbSConrad Meyer {
220*9119bafbSConrad Meyer     return (((state >> ((state >> 59u) + 5u)) ^ state)
221*9119bafbSConrad Meyer                * 12605985483714917081ull) >> 32u;
222*9119bafbSConrad Meyer }
223*9119bafbSConrad Meyer 
224*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
225*9119bafbSConrad Meyer inline uint64_t pcg_output_rxs_m_128_64(pcg128_t state)
226*9119bafbSConrad Meyer {
227*9119bafbSConrad Meyer     return (((state >> ((state >> 122u) + 6u)) ^ state)
228*9119bafbSConrad Meyer                * (PCG_128BIT_CONSTANT(17766728186571221404ULL,
229*9119bafbSConrad Meyer                                       12605985483714917081ULL))) >> 64u;
230*9119bafbSConrad Meyer     /* 327738287884841127335028083622016905945 */
231*9119bafbSConrad Meyer }
232*9119bafbSConrad Meyer #endif
233*9119bafbSConrad Meyer 
234*9119bafbSConrad Meyer /* XSL RR (only defined for >= 64 bits) */
235*9119bafbSConrad Meyer 
236*9119bafbSConrad Meyer inline uint32_t pcg_output_xsl_rr_64_32(uint64_t state)
237*9119bafbSConrad Meyer {
238*9119bafbSConrad Meyer     return pcg_rotr_32(((uint32_t)(state >> 32u)) ^ (uint32_t)state,
239*9119bafbSConrad Meyer                        state >> 59u);
240*9119bafbSConrad Meyer }
241*9119bafbSConrad Meyer 
242*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
243*9119bafbSConrad Meyer inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state)
244*9119bafbSConrad Meyer {
245*9119bafbSConrad Meyer     return pcg_rotr_64(((uint64_t)(state >> 64u)) ^ (uint64_t)state,
246*9119bafbSConrad Meyer                        state >> 122u);
247*9119bafbSConrad Meyer }
248*9119bafbSConrad Meyer #endif
249*9119bafbSConrad Meyer 
250*9119bafbSConrad Meyer /* XSL RR RR (only defined for >= 64 bits) */
251*9119bafbSConrad Meyer 
252*9119bafbSConrad Meyer inline uint64_t pcg_output_xsl_rr_rr_64_64(uint64_t state)
253*9119bafbSConrad Meyer {
254*9119bafbSConrad Meyer     uint32_t rot1 = (uint32_t)(state >> 59u);
255*9119bafbSConrad Meyer     uint32_t high = (uint32_t)(state >> 32u);
256*9119bafbSConrad Meyer     uint32_t low  = (uint32_t)state;
257*9119bafbSConrad Meyer     uint32_t xored = high ^ low;
258*9119bafbSConrad Meyer     uint32_t newlow  = pcg_rotr_32(xored, rot1);
259*9119bafbSConrad Meyer     uint32_t newhigh = pcg_rotr_32(high, newlow & 31u);
260*9119bafbSConrad Meyer     return (((uint64_t)newhigh) << 32u) | newlow;
261*9119bafbSConrad Meyer }
262*9119bafbSConrad Meyer 
263*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
264*9119bafbSConrad Meyer inline pcg128_t pcg_output_xsl_rr_rr_128_128(pcg128_t state)
265*9119bafbSConrad Meyer {
266*9119bafbSConrad Meyer     uint32_t rot1 = (uint32_t)(state >> 122u);
267*9119bafbSConrad Meyer     uint64_t high = (uint64_t)(state >> 64u);
268*9119bafbSConrad Meyer     uint64_t low  = (uint64_t)state;
269*9119bafbSConrad Meyer     uint64_t xored = high ^ low;
270*9119bafbSConrad Meyer     uint64_t newlow  = pcg_rotr_64(xored, rot1);
271*9119bafbSConrad Meyer     uint64_t newhigh = pcg_rotr_64(high, newlow & 63u);
272*9119bafbSConrad Meyer     return (((pcg128_t)newhigh) << 64u) | newlow;
273*9119bafbSConrad Meyer }
274*9119bafbSConrad Meyer #endif
275*9119bafbSConrad Meyer 
276*9119bafbSConrad Meyer #define PCG_DEFAULT_MULTIPLIER_8   141U
277*9119bafbSConrad Meyer #define PCG_DEFAULT_MULTIPLIER_16  12829U
278*9119bafbSConrad Meyer #define PCG_DEFAULT_MULTIPLIER_32  747796405U
279*9119bafbSConrad Meyer #define PCG_DEFAULT_MULTIPLIER_64  6364136223846793005ULL
280*9119bafbSConrad Meyer 
281*9119bafbSConrad Meyer #define PCG_DEFAULT_INCREMENT_8    77U
282*9119bafbSConrad Meyer #define PCG_DEFAULT_INCREMENT_16   47989U
283*9119bafbSConrad Meyer #define PCG_DEFAULT_INCREMENT_32   2891336453U
284*9119bafbSConrad Meyer #define PCG_DEFAULT_INCREMENT_64   1442695040888963407ULL
285*9119bafbSConrad Meyer 
286*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
287*9119bafbSConrad Meyer #define PCG_DEFAULT_MULTIPLIER_128 \
288*9119bafbSConrad Meyer         PCG_128BIT_CONSTANT(2549297995355413924ULL,4865540595714422341ULL)
289*9119bafbSConrad Meyer #define PCG_DEFAULT_INCREMENT_128  \
290*9119bafbSConrad Meyer         PCG_128BIT_CONSTANT(6364136223846793005ULL,1442695040888963407ULL)
291*9119bafbSConrad Meyer #endif
292*9119bafbSConrad Meyer 
293*9119bafbSConrad Meyer /*
294*9119bafbSConrad Meyer  * Static initialization constants (if you can't call srandom for some
295*9119bafbSConrad Meyer  * bizarre reason).
296*9119bafbSConrad Meyer  */
297*9119bafbSConrad Meyer 
298*9119bafbSConrad Meyer #define PCG_STATE_ONESEQ_8_INITIALIZER      { 0xd7U }
299*9119bafbSConrad Meyer #define PCG_STATE_ONESEQ_16_INITIALIZER     { 0x20dfU }
300*9119bafbSConrad Meyer #define PCG_STATE_ONESEQ_32_INITIALIZER     { 0x46b56677U }
301*9119bafbSConrad Meyer #define PCG_STATE_ONESEQ_64_INITIALIZER     { 0x4d595df4d0f33173ULL }
302*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
303*9119bafbSConrad Meyer #define PCG_STATE_ONESEQ_128_INITIALIZER                                       \
304*9119bafbSConrad Meyer     { PCG_128BIT_CONSTANT(0xb8dc10e158a92392ULL, 0x98046df007ec0a53ULL) }
305*9119bafbSConrad Meyer #endif
306*9119bafbSConrad Meyer 
307*9119bafbSConrad Meyer #define PCG_STATE_UNIQUE_8_INITIALIZER      PCG_STATE_ONESEQ_8_INITIALIZER
308*9119bafbSConrad Meyer #define PCG_STATE_UNIQUE_16_INITIALIZER     PCG_STATE_ONESEQ_16_INITIALIZER
309*9119bafbSConrad Meyer #define PCG_STATE_UNIQUE_32_INITIALIZER     PCG_STATE_ONESEQ_32_INITIALIZER
310*9119bafbSConrad Meyer #define PCG_STATE_UNIQUE_64_INITIALIZER     PCG_STATE_ONESEQ_64_INITIALIZER
311*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
312*9119bafbSConrad Meyer #define PCG_STATE_UNIQUE_128_INITIALIZER    PCG_STATE_ONESEQ_128_INITIALIZER
313*9119bafbSConrad Meyer #endif
314*9119bafbSConrad Meyer 
315*9119bafbSConrad Meyer #define PCG_STATE_MCG_8_INITIALIZER         { 0xe5U }
316*9119bafbSConrad Meyer #define PCG_STATE_MCG_16_INITIALIZER        { 0xa5e5U }
317*9119bafbSConrad Meyer #define PCG_STATE_MCG_32_INITIALIZER        { 0xd15ea5e5U }
318*9119bafbSConrad Meyer #define PCG_STATE_MCG_64_INITIALIZER        { 0xcafef00dd15ea5e5ULL }
319*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
320*9119bafbSConrad Meyer #define PCG_STATE_MCG_128_INITIALIZER                                          \
321*9119bafbSConrad Meyer     { PCG_128BIT_CONSTANT(0x0000000000000000ULL, 0xcafef00dd15ea5e5ULL) }
322*9119bafbSConrad Meyer #endif
323*9119bafbSConrad Meyer 
324*9119bafbSConrad Meyer #define PCG_STATE_SETSEQ_8_INITIALIZER      { 0x9bU, 0xdbU }
325*9119bafbSConrad Meyer #define PCG_STATE_SETSEQ_16_INITIALIZER     { 0xe39bU, 0x5bdbU }
326*9119bafbSConrad Meyer #define PCG_STATE_SETSEQ_32_INITIALIZER     { 0xec02d89bU, 0x94b95bdbU }
327*9119bafbSConrad Meyer #define PCG_STATE_SETSEQ_64_INITIALIZER                                        \
328*9119bafbSConrad Meyer     { 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL }
329*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
330*9119bafbSConrad Meyer #define PCG_STATE_SETSEQ_128_INITIALIZER                                       \
331*9119bafbSConrad Meyer     { PCG_128BIT_CONSTANT(0x979c9a98d8462005ULL, 0x7d3e9cb6cfe0549bULL),       \
332*9119bafbSConrad Meyer       PCG_128BIT_CONSTANT(0x0000000000000001ULL, 0xda3e39cb94b95bdbULL) }
333*9119bafbSConrad Meyer #endif
334*9119bafbSConrad Meyer 
335*9119bafbSConrad Meyer /* Representations for the oneseq, mcg, and unique variants */
336*9119bafbSConrad Meyer 
337*9119bafbSConrad Meyer struct pcg_state_8 {
338*9119bafbSConrad Meyer     uint8_t state;
339*9119bafbSConrad Meyer };
340*9119bafbSConrad Meyer 
341*9119bafbSConrad Meyer struct pcg_state_16 {
342*9119bafbSConrad Meyer     uint16_t state;
343*9119bafbSConrad Meyer };
344*9119bafbSConrad Meyer 
345*9119bafbSConrad Meyer struct pcg_state_32 {
346*9119bafbSConrad Meyer     uint32_t state;
347*9119bafbSConrad Meyer };
348*9119bafbSConrad Meyer 
349*9119bafbSConrad Meyer struct pcg_state_64 {
350*9119bafbSConrad Meyer     uint64_t state;
351*9119bafbSConrad Meyer };
352*9119bafbSConrad Meyer 
353*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
354*9119bafbSConrad Meyer struct pcg_state_128 {
355*9119bafbSConrad Meyer     pcg128_t state;
356*9119bafbSConrad Meyer };
357*9119bafbSConrad Meyer #endif
358*9119bafbSConrad Meyer 
359*9119bafbSConrad Meyer /* Representations setseq variants */
360*9119bafbSConrad Meyer 
361*9119bafbSConrad Meyer struct pcg_state_setseq_8 {
362*9119bafbSConrad Meyer     uint8_t state;
363*9119bafbSConrad Meyer     uint8_t inc;
364*9119bafbSConrad Meyer };
365*9119bafbSConrad Meyer 
366*9119bafbSConrad Meyer struct pcg_state_setseq_16 {
367*9119bafbSConrad Meyer     uint16_t state;
368*9119bafbSConrad Meyer     uint16_t inc;
369*9119bafbSConrad Meyer };
370*9119bafbSConrad Meyer 
371*9119bafbSConrad Meyer struct pcg_state_setseq_32 {
372*9119bafbSConrad Meyer     uint32_t state;
373*9119bafbSConrad Meyer     uint32_t inc;
374*9119bafbSConrad Meyer };
375*9119bafbSConrad Meyer 
376*9119bafbSConrad Meyer struct pcg_state_setseq_64 {
377*9119bafbSConrad Meyer     uint64_t state;
378*9119bafbSConrad Meyer     uint64_t inc;
379*9119bafbSConrad Meyer };
380*9119bafbSConrad Meyer 
381*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
382*9119bafbSConrad Meyer struct pcg_state_setseq_128 {
383*9119bafbSConrad Meyer     pcg128_t state;
384*9119bafbSConrad Meyer     pcg128_t inc;
385*9119bafbSConrad Meyer };
386*9119bafbSConrad Meyer #endif
387*9119bafbSConrad Meyer 
388*9119bafbSConrad Meyer /* Multi-step advance functions (jump-ahead, jump-back) */
389*9119bafbSConrad Meyer 
390*9119bafbSConrad Meyer extern uint8_t pcg_advance_lcg_8(uint8_t state, uint8_t delta, uint8_t cur_mult,
391*9119bafbSConrad Meyer                                  uint8_t cur_plus);
392*9119bafbSConrad Meyer extern uint16_t pcg_advance_lcg_16(uint16_t state, uint16_t delta,
393*9119bafbSConrad Meyer                                    uint16_t cur_mult, uint16_t cur_plus);
394*9119bafbSConrad Meyer extern uint32_t pcg_advance_lcg_32(uint32_t state, uint32_t delta,
395*9119bafbSConrad Meyer                                    uint32_t cur_mult, uint32_t cur_plus);
396*9119bafbSConrad Meyer extern uint64_t pcg_advance_lcg_64(uint64_t state, uint64_t delta,
397*9119bafbSConrad Meyer                                    uint64_t cur_mult, uint64_t cur_plus);
398*9119bafbSConrad Meyer 
399*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
400*9119bafbSConrad Meyer extern pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta,
401*9119bafbSConrad Meyer                                     pcg128_t cur_mult, pcg128_t cur_plus);
402*9119bafbSConrad Meyer #endif
403*9119bafbSConrad Meyer 
404*9119bafbSConrad Meyer /* Functions to advance the underlying LCG, one version for each size and
405*9119bafbSConrad Meyer  * each style.  These functions are considered semi-private.  There is rarely
406*9119bafbSConrad Meyer  * a good reason to call them directly.
407*9119bafbSConrad Meyer  */
408*9119bafbSConrad Meyer 
409*9119bafbSConrad Meyer inline void pcg_oneseq_8_step_r(struct pcg_state_8* rng)
410*9119bafbSConrad Meyer {
411*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8
412*9119bafbSConrad Meyer                  + PCG_DEFAULT_INCREMENT_8;
413*9119bafbSConrad Meyer }
414*9119bafbSConrad Meyer 
415*9119bafbSConrad Meyer inline void pcg_oneseq_8_advance_r(struct pcg_state_8* rng, uint8_t delta)
416*9119bafbSConrad Meyer {
417*9119bafbSConrad Meyer     rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8,
418*9119bafbSConrad Meyer                                    PCG_DEFAULT_INCREMENT_8);
419*9119bafbSConrad Meyer }
420*9119bafbSConrad Meyer 
421*9119bafbSConrad Meyer inline void pcg_mcg_8_step_r(struct pcg_state_8* rng)
422*9119bafbSConrad Meyer {
423*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8;
424*9119bafbSConrad Meyer }
425*9119bafbSConrad Meyer 
426*9119bafbSConrad Meyer inline void pcg_mcg_8_advance_r(struct pcg_state_8* rng, uint8_t delta)
427*9119bafbSConrad Meyer {
428*9119bafbSConrad Meyer     rng->state
429*9119bafbSConrad Meyer         = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8, 0u);
430*9119bafbSConrad Meyer }
431*9119bafbSConrad Meyer 
432*9119bafbSConrad Meyer inline void pcg_unique_8_step_r(struct pcg_state_8* rng)
433*9119bafbSConrad Meyer {
434*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8
435*9119bafbSConrad Meyer                  + (uint8_t)(((intptr_t)rng) | 1u);
436*9119bafbSConrad Meyer }
437*9119bafbSConrad Meyer 
438*9119bafbSConrad Meyer inline void pcg_unique_8_advance_r(struct pcg_state_8* rng, uint8_t delta)
439*9119bafbSConrad Meyer {
440*9119bafbSConrad Meyer     rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8,
441*9119bafbSConrad Meyer                                    (uint8_t)(((intptr_t)rng) | 1u));
442*9119bafbSConrad Meyer }
443*9119bafbSConrad Meyer 
444*9119bafbSConrad Meyer inline void pcg_setseq_8_step_r(struct pcg_state_setseq_8* rng)
445*9119bafbSConrad Meyer {
446*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_8 + rng->inc;
447*9119bafbSConrad Meyer }
448*9119bafbSConrad Meyer 
449*9119bafbSConrad Meyer inline void pcg_setseq_8_advance_r(struct pcg_state_setseq_8* rng,
450*9119bafbSConrad Meyer                                    uint8_t delta)
451*9119bafbSConrad Meyer {
452*9119bafbSConrad Meyer     rng->state = pcg_advance_lcg_8(rng->state, delta, PCG_DEFAULT_MULTIPLIER_8,
453*9119bafbSConrad Meyer                                    rng->inc);
454*9119bafbSConrad Meyer }
455*9119bafbSConrad Meyer 
456*9119bafbSConrad Meyer inline void pcg_oneseq_16_step_r(struct pcg_state_16* rng)
457*9119bafbSConrad Meyer {
458*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16
459*9119bafbSConrad Meyer                  + PCG_DEFAULT_INCREMENT_16;
460*9119bafbSConrad Meyer }
461*9119bafbSConrad Meyer 
462*9119bafbSConrad Meyer inline void pcg_oneseq_16_advance_r(struct pcg_state_16* rng, uint16_t delta)
463*9119bafbSConrad Meyer {
464*9119bafbSConrad Meyer     rng->state = pcg_advance_lcg_16(
465*9119bafbSConrad Meyer         rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, PCG_DEFAULT_INCREMENT_16);
466*9119bafbSConrad Meyer }
467*9119bafbSConrad Meyer 
468*9119bafbSConrad Meyer inline void pcg_mcg_16_step_r(struct pcg_state_16* rng)
469*9119bafbSConrad Meyer {
470*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16;
471*9119bafbSConrad Meyer }
472*9119bafbSConrad Meyer 
473*9119bafbSConrad Meyer inline void pcg_mcg_16_advance_r(struct pcg_state_16* rng, uint16_t delta)
474*9119bafbSConrad Meyer {
475*9119bafbSConrad Meyer     rng->state
476*9119bafbSConrad Meyer         = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16, 0u);
477*9119bafbSConrad Meyer }
478*9119bafbSConrad Meyer 
479*9119bafbSConrad Meyer inline void pcg_unique_16_step_r(struct pcg_state_16* rng)
480*9119bafbSConrad Meyer {
481*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16
482*9119bafbSConrad Meyer                  + (uint16_t)(((intptr_t)rng) | 1u);
483*9119bafbSConrad Meyer }
484*9119bafbSConrad Meyer 
485*9119bafbSConrad Meyer inline void pcg_unique_16_advance_r(struct pcg_state_16* rng, uint16_t delta)
486*9119bafbSConrad Meyer {
487*9119bafbSConrad Meyer     rng->state
488*9119bafbSConrad Meyer         = pcg_advance_lcg_16(rng->state, delta, PCG_DEFAULT_MULTIPLIER_16,
489*9119bafbSConrad Meyer                              (uint16_t)(((intptr_t)rng) | 1u));
490*9119bafbSConrad Meyer }
491*9119bafbSConrad Meyer 
492*9119bafbSConrad Meyer inline void pcg_setseq_16_step_r(struct pcg_state_setseq_16* rng)
493*9119bafbSConrad Meyer {
494*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_16 + rng->inc;
495*9119bafbSConrad Meyer }
496*9119bafbSConrad Meyer 
497*9119bafbSConrad Meyer inline void pcg_setseq_16_advance_r(struct pcg_state_setseq_16* rng,
498*9119bafbSConrad Meyer                                     uint16_t delta)
499*9119bafbSConrad Meyer {
500*9119bafbSConrad Meyer     rng->state = pcg_advance_lcg_16(rng->state, delta,
501*9119bafbSConrad Meyer                                     PCG_DEFAULT_MULTIPLIER_16, rng->inc);
502*9119bafbSConrad Meyer }
503*9119bafbSConrad Meyer 
504*9119bafbSConrad Meyer inline void pcg_oneseq_32_step_r(struct pcg_state_32* rng)
505*9119bafbSConrad Meyer {
506*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32
507*9119bafbSConrad Meyer                  + PCG_DEFAULT_INCREMENT_32;
508*9119bafbSConrad Meyer }
509*9119bafbSConrad Meyer 
510*9119bafbSConrad Meyer inline void pcg_oneseq_32_advance_r(struct pcg_state_32* rng, uint32_t delta)
511*9119bafbSConrad Meyer {
512*9119bafbSConrad Meyer     rng->state = pcg_advance_lcg_32(
513*9119bafbSConrad Meyer         rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, PCG_DEFAULT_INCREMENT_32);
514*9119bafbSConrad Meyer }
515*9119bafbSConrad Meyer 
516*9119bafbSConrad Meyer inline void pcg_mcg_32_step_r(struct pcg_state_32* rng)
517*9119bafbSConrad Meyer {
518*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32;
519*9119bafbSConrad Meyer }
520*9119bafbSConrad Meyer 
521*9119bafbSConrad Meyer inline void pcg_mcg_32_advance_r(struct pcg_state_32* rng, uint32_t delta)
522*9119bafbSConrad Meyer {
523*9119bafbSConrad Meyer     rng->state
524*9119bafbSConrad Meyer         = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32, 0u);
525*9119bafbSConrad Meyer }
526*9119bafbSConrad Meyer 
527*9119bafbSConrad Meyer inline void pcg_unique_32_step_r(struct pcg_state_32* rng)
528*9119bafbSConrad Meyer {
529*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32
530*9119bafbSConrad Meyer                  + (uint32_t)(((intptr_t)rng) | 1u);
531*9119bafbSConrad Meyer }
532*9119bafbSConrad Meyer 
533*9119bafbSConrad Meyer inline void pcg_unique_32_advance_r(struct pcg_state_32* rng, uint32_t delta)
534*9119bafbSConrad Meyer {
535*9119bafbSConrad Meyer     rng->state
536*9119bafbSConrad Meyer         = pcg_advance_lcg_32(rng->state, delta, PCG_DEFAULT_MULTIPLIER_32,
537*9119bafbSConrad Meyer                              (uint32_t)(((intptr_t)rng) | 1u));
538*9119bafbSConrad Meyer }
539*9119bafbSConrad Meyer 
540*9119bafbSConrad Meyer inline void pcg_setseq_32_step_r(struct pcg_state_setseq_32* rng)
541*9119bafbSConrad Meyer {
542*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_32 + rng->inc;
543*9119bafbSConrad Meyer }
544*9119bafbSConrad Meyer 
545*9119bafbSConrad Meyer inline void pcg_setseq_32_advance_r(struct pcg_state_setseq_32* rng,
546*9119bafbSConrad Meyer                                     uint32_t delta)
547*9119bafbSConrad Meyer {
548*9119bafbSConrad Meyer     rng->state = pcg_advance_lcg_32(rng->state, delta,
549*9119bafbSConrad Meyer                                     PCG_DEFAULT_MULTIPLIER_32, rng->inc);
550*9119bafbSConrad Meyer }
551*9119bafbSConrad Meyer 
552*9119bafbSConrad Meyer inline void pcg_oneseq_64_step_r(struct pcg_state_64* rng)
553*9119bafbSConrad Meyer {
554*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64
555*9119bafbSConrad Meyer                  + PCG_DEFAULT_INCREMENT_64;
556*9119bafbSConrad Meyer }
557*9119bafbSConrad Meyer 
558*9119bafbSConrad Meyer inline void pcg_oneseq_64_advance_r(struct pcg_state_64* rng, uint64_t delta)
559*9119bafbSConrad Meyer {
560*9119bafbSConrad Meyer     rng->state = pcg_advance_lcg_64(
561*9119bafbSConrad Meyer         rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, PCG_DEFAULT_INCREMENT_64);
562*9119bafbSConrad Meyer }
563*9119bafbSConrad Meyer 
564*9119bafbSConrad Meyer inline void pcg_mcg_64_step_r(struct pcg_state_64* rng)
565*9119bafbSConrad Meyer {
566*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64;
567*9119bafbSConrad Meyer }
568*9119bafbSConrad Meyer 
569*9119bafbSConrad Meyer inline void pcg_mcg_64_advance_r(struct pcg_state_64* rng, uint64_t delta)
570*9119bafbSConrad Meyer {
571*9119bafbSConrad Meyer     rng->state
572*9119bafbSConrad Meyer         = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64, 0u);
573*9119bafbSConrad Meyer }
574*9119bafbSConrad Meyer 
575*9119bafbSConrad Meyer inline void pcg_unique_64_step_r(struct pcg_state_64* rng)
576*9119bafbSConrad Meyer {
577*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64
578*9119bafbSConrad Meyer                  + (uint64_t)(((intptr_t)rng) | 1u);
579*9119bafbSConrad Meyer }
580*9119bafbSConrad Meyer 
581*9119bafbSConrad Meyer inline void pcg_unique_64_advance_r(struct pcg_state_64* rng, uint64_t delta)
582*9119bafbSConrad Meyer {
583*9119bafbSConrad Meyer     rng->state
584*9119bafbSConrad Meyer         = pcg_advance_lcg_64(rng->state, delta, PCG_DEFAULT_MULTIPLIER_64,
585*9119bafbSConrad Meyer                              (uint64_t)(((intptr_t)rng) | 1u));
586*9119bafbSConrad Meyer }
587*9119bafbSConrad Meyer 
588*9119bafbSConrad Meyer inline void pcg_setseq_64_step_r(struct pcg_state_setseq_64* rng)
589*9119bafbSConrad Meyer {
590*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_64 + rng->inc;
591*9119bafbSConrad Meyer }
592*9119bafbSConrad Meyer 
593*9119bafbSConrad Meyer inline void pcg_setseq_64_advance_r(struct pcg_state_setseq_64* rng,
594*9119bafbSConrad Meyer                                     uint64_t delta)
595*9119bafbSConrad Meyer {
596*9119bafbSConrad Meyer     rng->state = pcg_advance_lcg_64(rng->state, delta,
597*9119bafbSConrad Meyer                                     PCG_DEFAULT_MULTIPLIER_64, rng->inc);
598*9119bafbSConrad Meyer }
599*9119bafbSConrad Meyer 
600*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
601*9119bafbSConrad Meyer inline void pcg_oneseq_128_step_r(struct pcg_state_128* rng)
602*9119bafbSConrad Meyer {
603*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128
604*9119bafbSConrad Meyer                  + PCG_DEFAULT_INCREMENT_128;
605*9119bafbSConrad Meyer }
606*9119bafbSConrad Meyer #endif
607*9119bafbSConrad Meyer 
608*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
609*9119bafbSConrad Meyer inline void pcg_oneseq_128_advance_r(struct pcg_state_128* rng, pcg128_t delta)
610*9119bafbSConrad Meyer {
611*9119bafbSConrad Meyer     rng->state
612*9119bafbSConrad Meyer         = pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128,
613*9119bafbSConrad Meyer                               PCG_DEFAULT_INCREMENT_128);
614*9119bafbSConrad Meyer }
615*9119bafbSConrad Meyer #endif
616*9119bafbSConrad Meyer 
617*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
618*9119bafbSConrad Meyer inline void pcg_mcg_128_step_r(struct pcg_state_128* rng)
619*9119bafbSConrad Meyer {
620*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128;
621*9119bafbSConrad Meyer }
622*9119bafbSConrad Meyer #endif
623*9119bafbSConrad Meyer 
624*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
625*9119bafbSConrad Meyer inline void pcg_mcg_128_advance_r(struct pcg_state_128* rng, pcg128_t delta)
626*9119bafbSConrad Meyer {
627*9119bafbSConrad Meyer     rng->state = pcg_advance_lcg_128(rng->state, delta,
628*9119bafbSConrad Meyer                                      PCG_DEFAULT_MULTIPLIER_128, 0u);
629*9119bafbSConrad Meyer }
630*9119bafbSConrad Meyer #endif
631*9119bafbSConrad Meyer 
632*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
633*9119bafbSConrad Meyer inline void pcg_unique_128_step_r(struct pcg_state_128* rng)
634*9119bafbSConrad Meyer {
635*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128
636*9119bafbSConrad Meyer                  + (pcg128_t)(((intptr_t)rng) | 1u);
637*9119bafbSConrad Meyer }
638*9119bafbSConrad Meyer #endif
639*9119bafbSConrad Meyer 
640*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
641*9119bafbSConrad Meyer inline void pcg_unique_128_advance_r(struct pcg_state_128* rng, pcg128_t delta)
642*9119bafbSConrad Meyer {
643*9119bafbSConrad Meyer     rng->state
644*9119bafbSConrad Meyer         = pcg_advance_lcg_128(rng->state, delta, PCG_DEFAULT_MULTIPLIER_128,
645*9119bafbSConrad Meyer                               (pcg128_t)(((intptr_t)rng) | 1u));
646*9119bafbSConrad Meyer }
647*9119bafbSConrad Meyer #endif
648*9119bafbSConrad Meyer 
649*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
650*9119bafbSConrad Meyer inline void pcg_setseq_128_step_r(struct pcg_state_setseq_128* rng)
651*9119bafbSConrad Meyer {
652*9119bafbSConrad Meyer     rng->state = rng->state * PCG_DEFAULT_MULTIPLIER_128 + rng->inc;
653*9119bafbSConrad Meyer }
654*9119bafbSConrad Meyer #endif
655*9119bafbSConrad Meyer 
656*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
657*9119bafbSConrad Meyer inline void pcg_setseq_128_advance_r(struct pcg_state_setseq_128* rng,
658*9119bafbSConrad Meyer                                      pcg128_t delta)
659*9119bafbSConrad Meyer {
660*9119bafbSConrad Meyer     rng->state = pcg_advance_lcg_128(rng->state, delta,
661*9119bafbSConrad Meyer                                      PCG_DEFAULT_MULTIPLIER_128, rng->inc);
662*9119bafbSConrad Meyer }
663*9119bafbSConrad Meyer #endif
664*9119bafbSConrad Meyer 
665*9119bafbSConrad Meyer /* Functions to seed the RNG state, one version for each size and each
666*9119bafbSConrad Meyer  * style.  Unlike the step functions, regular users can and should call
667*9119bafbSConrad Meyer  * these functions.
668*9119bafbSConrad Meyer  */
669*9119bafbSConrad Meyer 
670*9119bafbSConrad Meyer inline void pcg_oneseq_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate)
671*9119bafbSConrad Meyer {
672*9119bafbSConrad Meyer     rng->state = 0U;
673*9119bafbSConrad Meyer     pcg_oneseq_8_step_r(rng);
674*9119bafbSConrad Meyer     rng->state += initstate;
675*9119bafbSConrad Meyer     pcg_oneseq_8_step_r(rng);
676*9119bafbSConrad Meyer }
677*9119bafbSConrad Meyer 
678*9119bafbSConrad Meyer inline void pcg_mcg_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate)
679*9119bafbSConrad Meyer {
680*9119bafbSConrad Meyer     rng->state = initstate | 1u;
681*9119bafbSConrad Meyer }
682*9119bafbSConrad Meyer 
683*9119bafbSConrad Meyer inline void pcg_unique_8_srandom_r(struct pcg_state_8* rng, uint8_t initstate)
684*9119bafbSConrad Meyer {
685*9119bafbSConrad Meyer     rng->state = 0U;
686*9119bafbSConrad Meyer     pcg_unique_8_step_r(rng);
687*9119bafbSConrad Meyer     rng->state += initstate;
688*9119bafbSConrad Meyer     pcg_unique_8_step_r(rng);
689*9119bafbSConrad Meyer }
690*9119bafbSConrad Meyer 
691*9119bafbSConrad Meyer inline void pcg_setseq_8_srandom_r(struct pcg_state_setseq_8* rng,
692*9119bafbSConrad Meyer                                    uint8_t initstate, uint8_t initseq)
693*9119bafbSConrad Meyer {
694*9119bafbSConrad Meyer     rng->state = 0U;
695*9119bafbSConrad Meyer     rng->inc = (initseq << 1u) | 1u;
696*9119bafbSConrad Meyer     pcg_setseq_8_step_r(rng);
697*9119bafbSConrad Meyer     rng->state += initstate;
698*9119bafbSConrad Meyer     pcg_setseq_8_step_r(rng);
699*9119bafbSConrad Meyer }
700*9119bafbSConrad Meyer 
701*9119bafbSConrad Meyer inline void pcg_oneseq_16_srandom_r(struct pcg_state_16* rng,
702*9119bafbSConrad Meyer                                     uint16_t initstate)
703*9119bafbSConrad Meyer {
704*9119bafbSConrad Meyer     rng->state = 0U;
705*9119bafbSConrad Meyer     pcg_oneseq_16_step_r(rng);
706*9119bafbSConrad Meyer     rng->state += initstate;
707*9119bafbSConrad Meyer     pcg_oneseq_16_step_r(rng);
708*9119bafbSConrad Meyer }
709*9119bafbSConrad Meyer 
710*9119bafbSConrad Meyer inline void pcg_mcg_16_srandom_r(struct pcg_state_16* rng, uint16_t initstate)
711*9119bafbSConrad Meyer {
712*9119bafbSConrad Meyer     rng->state = initstate | 1u;
713*9119bafbSConrad Meyer }
714*9119bafbSConrad Meyer 
715*9119bafbSConrad Meyer inline void pcg_unique_16_srandom_r(struct pcg_state_16* rng,
716*9119bafbSConrad Meyer                                     uint16_t initstate)
717*9119bafbSConrad Meyer {
718*9119bafbSConrad Meyer     rng->state = 0U;
719*9119bafbSConrad Meyer     pcg_unique_16_step_r(rng);
720*9119bafbSConrad Meyer     rng->state += initstate;
721*9119bafbSConrad Meyer     pcg_unique_16_step_r(rng);
722*9119bafbSConrad Meyer }
723*9119bafbSConrad Meyer 
724*9119bafbSConrad Meyer inline void pcg_setseq_16_srandom_r(struct pcg_state_setseq_16* rng,
725*9119bafbSConrad Meyer                                     uint16_t initstate, uint16_t initseq)
726*9119bafbSConrad Meyer {
727*9119bafbSConrad Meyer     rng->state = 0U;
728*9119bafbSConrad Meyer     rng->inc = (initseq << 1u) | 1u;
729*9119bafbSConrad Meyer     pcg_setseq_16_step_r(rng);
730*9119bafbSConrad Meyer     rng->state += initstate;
731*9119bafbSConrad Meyer     pcg_setseq_16_step_r(rng);
732*9119bafbSConrad Meyer }
733*9119bafbSConrad Meyer 
734*9119bafbSConrad Meyer inline void pcg_oneseq_32_srandom_r(struct pcg_state_32* rng,
735*9119bafbSConrad Meyer                                     uint32_t initstate)
736*9119bafbSConrad Meyer {
737*9119bafbSConrad Meyer     rng->state = 0U;
738*9119bafbSConrad Meyer     pcg_oneseq_32_step_r(rng);
739*9119bafbSConrad Meyer     rng->state += initstate;
740*9119bafbSConrad Meyer     pcg_oneseq_32_step_r(rng);
741*9119bafbSConrad Meyer }
742*9119bafbSConrad Meyer 
743*9119bafbSConrad Meyer inline void pcg_mcg_32_srandom_r(struct pcg_state_32* rng, uint32_t initstate)
744*9119bafbSConrad Meyer {
745*9119bafbSConrad Meyer     rng->state = initstate | 1u;
746*9119bafbSConrad Meyer }
747*9119bafbSConrad Meyer 
748*9119bafbSConrad Meyer inline void pcg_unique_32_srandom_r(struct pcg_state_32* rng,
749*9119bafbSConrad Meyer                                     uint32_t initstate)
750*9119bafbSConrad Meyer {
751*9119bafbSConrad Meyer     rng->state = 0U;
752*9119bafbSConrad Meyer     pcg_unique_32_step_r(rng);
753*9119bafbSConrad Meyer     rng->state += initstate;
754*9119bafbSConrad Meyer     pcg_unique_32_step_r(rng);
755*9119bafbSConrad Meyer }
756*9119bafbSConrad Meyer 
757*9119bafbSConrad Meyer inline void pcg_setseq_32_srandom_r(struct pcg_state_setseq_32* rng,
758*9119bafbSConrad Meyer                                     uint32_t initstate, uint32_t initseq)
759*9119bafbSConrad Meyer {
760*9119bafbSConrad Meyer     rng->state = 0U;
761*9119bafbSConrad Meyer     rng->inc = (initseq << 1u) | 1u;
762*9119bafbSConrad Meyer     pcg_setseq_32_step_r(rng);
763*9119bafbSConrad Meyer     rng->state += initstate;
764*9119bafbSConrad Meyer     pcg_setseq_32_step_r(rng);
765*9119bafbSConrad Meyer }
766*9119bafbSConrad Meyer 
767*9119bafbSConrad Meyer inline void pcg_oneseq_64_srandom_r(struct pcg_state_64* rng,
768*9119bafbSConrad Meyer                                     uint64_t initstate)
769*9119bafbSConrad Meyer {
770*9119bafbSConrad Meyer     rng->state = 0U;
771*9119bafbSConrad Meyer     pcg_oneseq_64_step_r(rng);
772*9119bafbSConrad Meyer     rng->state += initstate;
773*9119bafbSConrad Meyer     pcg_oneseq_64_step_r(rng);
774*9119bafbSConrad Meyer }
775*9119bafbSConrad Meyer 
776*9119bafbSConrad Meyer inline void pcg_mcg_64_srandom_r(struct pcg_state_64* rng, uint64_t initstate)
777*9119bafbSConrad Meyer {
778*9119bafbSConrad Meyer     rng->state = initstate | 1u;
779*9119bafbSConrad Meyer }
780*9119bafbSConrad Meyer 
781*9119bafbSConrad Meyer inline void pcg_unique_64_srandom_r(struct pcg_state_64* rng,
782*9119bafbSConrad Meyer                                     uint64_t initstate)
783*9119bafbSConrad Meyer {
784*9119bafbSConrad Meyer     rng->state = 0U;
785*9119bafbSConrad Meyer     pcg_unique_64_step_r(rng);
786*9119bafbSConrad Meyer     rng->state += initstate;
787*9119bafbSConrad Meyer     pcg_unique_64_step_r(rng);
788*9119bafbSConrad Meyer }
789*9119bafbSConrad Meyer 
790*9119bafbSConrad Meyer inline void pcg_setseq_64_srandom_r(struct pcg_state_setseq_64* rng,
791*9119bafbSConrad Meyer                                     uint64_t initstate, uint64_t initseq)
792*9119bafbSConrad Meyer {
793*9119bafbSConrad Meyer     rng->state = 0U;
794*9119bafbSConrad Meyer     rng->inc = (initseq << 1u) | 1u;
795*9119bafbSConrad Meyer     pcg_setseq_64_step_r(rng);
796*9119bafbSConrad Meyer     rng->state += initstate;
797*9119bafbSConrad Meyer     pcg_setseq_64_step_r(rng);
798*9119bafbSConrad Meyer }
799*9119bafbSConrad Meyer 
800*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
801*9119bafbSConrad Meyer inline void pcg_oneseq_128_srandom_r(struct pcg_state_128* rng,
802*9119bafbSConrad Meyer                                      pcg128_t initstate)
803*9119bafbSConrad Meyer {
804*9119bafbSConrad Meyer     rng->state = 0U;
805*9119bafbSConrad Meyer     pcg_oneseq_128_step_r(rng);
806*9119bafbSConrad Meyer     rng->state += initstate;
807*9119bafbSConrad Meyer     pcg_oneseq_128_step_r(rng);
808*9119bafbSConrad Meyer }
809*9119bafbSConrad Meyer #endif
810*9119bafbSConrad Meyer 
811*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
812*9119bafbSConrad Meyer inline void pcg_mcg_128_srandom_r(struct pcg_state_128* rng, pcg128_t initstate)
813*9119bafbSConrad Meyer {
814*9119bafbSConrad Meyer     rng->state = initstate | 1u;
815*9119bafbSConrad Meyer }
816*9119bafbSConrad Meyer #endif
817*9119bafbSConrad Meyer 
818*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
819*9119bafbSConrad Meyer inline void pcg_unique_128_srandom_r(struct pcg_state_128* rng,
820*9119bafbSConrad Meyer                                      pcg128_t initstate)
821*9119bafbSConrad Meyer {
822*9119bafbSConrad Meyer     rng->state = 0U;
823*9119bafbSConrad Meyer     pcg_unique_128_step_r(rng);
824*9119bafbSConrad Meyer     rng->state += initstate;
825*9119bafbSConrad Meyer     pcg_unique_128_step_r(rng);
826*9119bafbSConrad Meyer }
827*9119bafbSConrad Meyer #endif
828*9119bafbSConrad Meyer 
829*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
830*9119bafbSConrad Meyer inline void pcg_setseq_128_srandom_r(struct pcg_state_setseq_128* rng,
831*9119bafbSConrad Meyer                                      pcg128_t initstate, pcg128_t initseq)
832*9119bafbSConrad Meyer {
833*9119bafbSConrad Meyer     rng->state = 0U;
834*9119bafbSConrad Meyer     rng->inc = (initseq << 1u) | 1u;
835*9119bafbSConrad Meyer     pcg_setseq_128_step_r(rng);
836*9119bafbSConrad Meyer     rng->state += initstate;
837*9119bafbSConrad Meyer     pcg_setseq_128_step_r(rng);
838*9119bafbSConrad Meyer }
839*9119bafbSConrad Meyer #endif
840*9119bafbSConrad Meyer 
841*9119bafbSConrad Meyer /* Now, finally we create each of the individual generators. We provide
842*9119bafbSConrad Meyer  * a random_r function that provides a random number of the appropriate
843*9119bafbSConrad Meyer  * type (using the full range of the type) and a boundedrand_r version
844*9119bafbSConrad Meyer  * that provides
845*9119bafbSConrad Meyer  *
846*9119bafbSConrad Meyer  * Implementation notes for boundedrand_r:
847*9119bafbSConrad Meyer  *
848*9119bafbSConrad Meyer  *     To avoid bias, we need to make the range of the RNG a multiple of
849*9119bafbSConrad Meyer  *     bound, which we do by dropping output less than a threshold.
850*9119bafbSConrad Meyer  *     Let's consider a 32-bit case...  A naive scheme to calculate the
851*9119bafbSConrad Meyer  *     threshold would be to do
852*9119bafbSConrad Meyer  *
853*9119bafbSConrad Meyer  *         uint32_t threshold = 0x100000000ull % bound;
854*9119bafbSConrad Meyer  *
855*9119bafbSConrad Meyer  *     but 64-bit div/mod is slower than 32-bit div/mod (especially on
856*9119bafbSConrad Meyer  *     32-bit platforms).  In essence, we do
857*9119bafbSConrad Meyer  *
858*9119bafbSConrad Meyer  *         uint32_t threshold = (0x100000000ull-bound) % bound;
859*9119bafbSConrad Meyer  *
860*9119bafbSConrad Meyer  *     because this version will calculate the same modulus, but the LHS
861*9119bafbSConrad Meyer  *     value is less than 2^32.
862*9119bafbSConrad Meyer  *
863*9119bafbSConrad Meyer  *     (Note that using modulo is only wise for good RNGs, poorer RNGs
864*9119bafbSConrad Meyer  *     such as raw LCGs do better using a technique based on division.)
865*9119bafbSConrad Meyer  *     Empricical tests show that division is preferable to modulus for
866*9119bafbSConrad Meyer  *     reducting the range of an RNG.  It's faster, and sometimes it can
867*9119bafbSConrad Meyer  *     even be statistically prefereable.
868*9119bafbSConrad Meyer  */
869*9119bafbSConrad Meyer 
870*9119bafbSConrad Meyer /* Generation functions for XSH RS */
871*9119bafbSConrad Meyer 
872*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_16_xsh_rs_8_random_r(struct pcg_state_16* rng)
873*9119bafbSConrad Meyer {
874*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
875*9119bafbSConrad Meyer     pcg_oneseq_16_step_r(rng);
876*9119bafbSConrad Meyer     return pcg_output_xsh_rs_16_8(oldstate);
877*9119bafbSConrad Meyer }
878*9119bafbSConrad Meyer 
879*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng,
880*9119bafbSConrad Meyer                                                     uint8_t bound)
881*9119bafbSConrad Meyer {
882*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
883*9119bafbSConrad Meyer     for (;;) {
884*9119bafbSConrad Meyer         uint8_t r = pcg_oneseq_16_xsh_rs_8_random_r(rng);
885*9119bafbSConrad Meyer         if (r >= threshold)
886*9119bafbSConrad Meyer             return r % bound;
887*9119bafbSConrad Meyer     }
888*9119bafbSConrad Meyer }
889*9119bafbSConrad Meyer 
890*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_32_xsh_rs_16_random_r(struct pcg_state_32* rng)
891*9119bafbSConrad Meyer {
892*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
893*9119bafbSConrad Meyer     pcg_oneseq_32_step_r(rng);
894*9119bafbSConrad Meyer     return pcg_output_xsh_rs_32_16(oldstate);
895*9119bafbSConrad Meyer }
896*9119bafbSConrad Meyer 
897*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng,
898*9119bafbSConrad Meyer                                                       uint16_t bound)
899*9119bafbSConrad Meyer {
900*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
901*9119bafbSConrad Meyer     for (;;) {
902*9119bafbSConrad Meyer         uint16_t r = pcg_oneseq_32_xsh_rs_16_random_r(rng);
903*9119bafbSConrad Meyer         if (r >= threshold)
904*9119bafbSConrad Meyer             return r % bound;
905*9119bafbSConrad Meyer     }
906*9119bafbSConrad Meyer }
907*9119bafbSConrad Meyer 
908*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_xsh_rs_32_random_r(struct pcg_state_64* rng)
909*9119bafbSConrad Meyer {
910*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
911*9119bafbSConrad Meyer     pcg_oneseq_64_step_r(rng);
912*9119bafbSConrad Meyer     return pcg_output_xsh_rs_64_32(oldstate);
913*9119bafbSConrad Meyer }
914*9119bafbSConrad Meyer 
915*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng,
916*9119bafbSConrad Meyer                                                       uint32_t bound)
917*9119bafbSConrad Meyer {
918*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
919*9119bafbSConrad Meyer     for (;;) {
920*9119bafbSConrad Meyer         uint32_t r = pcg_oneseq_64_xsh_rs_32_random_r(rng);
921*9119bafbSConrad Meyer         if (r >= threshold)
922*9119bafbSConrad Meyer             return r % bound;
923*9119bafbSConrad Meyer     }
924*9119bafbSConrad Meyer }
925*9119bafbSConrad Meyer 
926*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
927*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_128_xsh_rs_64_random_r(struct pcg_state_128* rng)
928*9119bafbSConrad Meyer {
929*9119bafbSConrad Meyer     pcg_oneseq_128_step_r(rng);
930*9119bafbSConrad Meyer     return pcg_output_xsh_rs_128_64(rng->state);
931*9119bafbSConrad Meyer }
932*9119bafbSConrad Meyer #endif
933*9119bafbSConrad Meyer 
934*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
935*9119bafbSConrad Meyer inline uint64_t
936*9119bafbSConrad Meyer pcg_oneseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
937*9119bafbSConrad Meyer                                        uint64_t bound)
938*9119bafbSConrad Meyer {
939*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
940*9119bafbSConrad Meyer     for (;;) {
941*9119bafbSConrad Meyer         uint64_t r = pcg_oneseq_128_xsh_rs_64_random_r(rng);
942*9119bafbSConrad Meyer         if (r >= threshold)
943*9119bafbSConrad Meyer             return r % bound;
944*9119bafbSConrad Meyer     }
945*9119bafbSConrad Meyer }
946*9119bafbSConrad Meyer #endif
947*9119bafbSConrad Meyer 
948*9119bafbSConrad Meyer inline uint8_t pcg_unique_16_xsh_rs_8_random_r(struct pcg_state_16* rng)
949*9119bafbSConrad Meyer {
950*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
951*9119bafbSConrad Meyer     pcg_unique_16_step_r(rng);
952*9119bafbSConrad Meyer     return pcg_output_xsh_rs_16_8(oldstate);
953*9119bafbSConrad Meyer }
954*9119bafbSConrad Meyer 
955*9119bafbSConrad Meyer inline uint8_t pcg_unique_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng,
956*9119bafbSConrad Meyer                                                     uint8_t bound)
957*9119bafbSConrad Meyer {
958*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
959*9119bafbSConrad Meyer     for (;;) {
960*9119bafbSConrad Meyer         uint8_t r = pcg_unique_16_xsh_rs_8_random_r(rng);
961*9119bafbSConrad Meyer         if (r >= threshold)
962*9119bafbSConrad Meyer             return r % bound;
963*9119bafbSConrad Meyer     }
964*9119bafbSConrad Meyer }
965*9119bafbSConrad Meyer 
966*9119bafbSConrad Meyer inline uint16_t pcg_unique_32_xsh_rs_16_random_r(struct pcg_state_32* rng)
967*9119bafbSConrad Meyer {
968*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
969*9119bafbSConrad Meyer     pcg_unique_32_step_r(rng);
970*9119bafbSConrad Meyer     return pcg_output_xsh_rs_32_16(oldstate);
971*9119bafbSConrad Meyer }
972*9119bafbSConrad Meyer 
973*9119bafbSConrad Meyer inline uint16_t pcg_unique_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng,
974*9119bafbSConrad Meyer                                                       uint16_t bound)
975*9119bafbSConrad Meyer {
976*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
977*9119bafbSConrad Meyer     for (;;) {
978*9119bafbSConrad Meyer         uint16_t r = pcg_unique_32_xsh_rs_16_random_r(rng);
979*9119bafbSConrad Meyer         if (r >= threshold)
980*9119bafbSConrad Meyer             return r % bound;
981*9119bafbSConrad Meyer     }
982*9119bafbSConrad Meyer }
983*9119bafbSConrad Meyer 
984*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_xsh_rs_32_random_r(struct pcg_state_64* rng)
985*9119bafbSConrad Meyer {
986*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
987*9119bafbSConrad Meyer     pcg_unique_64_step_r(rng);
988*9119bafbSConrad Meyer     return pcg_output_xsh_rs_64_32(oldstate);
989*9119bafbSConrad Meyer }
990*9119bafbSConrad Meyer 
991*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng,
992*9119bafbSConrad Meyer                                                       uint32_t bound)
993*9119bafbSConrad Meyer {
994*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
995*9119bafbSConrad Meyer     for (;;) {
996*9119bafbSConrad Meyer         uint32_t r = pcg_unique_64_xsh_rs_32_random_r(rng);
997*9119bafbSConrad Meyer         if (r >= threshold)
998*9119bafbSConrad Meyer             return r % bound;
999*9119bafbSConrad Meyer     }
1000*9119bafbSConrad Meyer }
1001*9119bafbSConrad Meyer 
1002*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1003*9119bafbSConrad Meyer inline uint64_t pcg_unique_128_xsh_rs_64_random_r(struct pcg_state_128* rng)
1004*9119bafbSConrad Meyer {
1005*9119bafbSConrad Meyer     pcg_unique_128_step_r(rng);
1006*9119bafbSConrad Meyer     return pcg_output_xsh_rs_128_64(rng->state);
1007*9119bafbSConrad Meyer }
1008*9119bafbSConrad Meyer #endif
1009*9119bafbSConrad Meyer 
1010*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1011*9119bafbSConrad Meyer inline uint64_t
1012*9119bafbSConrad Meyer pcg_unique_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
1013*9119bafbSConrad Meyer                                        uint64_t bound)
1014*9119bafbSConrad Meyer {
1015*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
1016*9119bafbSConrad Meyer     for (;;) {
1017*9119bafbSConrad Meyer         uint64_t r = pcg_unique_128_xsh_rs_64_random_r(rng);
1018*9119bafbSConrad Meyer         if (r >= threshold)
1019*9119bafbSConrad Meyer             return r % bound;
1020*9119bafbSConrad Meyer     }
1021*9119bafbSConrad Meyer }
1022*9119bafbSConrad Meyer #endif
1023*9119bafbSConrad Meyer 
1024*9119bafbSConrad Meyer inline uint8_t pcg_setseq_16_xsh_rs_8_random_r(struct pcg_state_setseq_16* rng)
1025*9119bafbSConrad Meyer {
1026*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
1027*9119bafbSConrad Meyer     pcg_setseq_16_step_r(rng);
1028*9119bafbSConrad Meyer     return pcg_output_xsh_rs_16_8(oldstate);
1029*9119bafbSConrad Meyer }
1030*9119bafbSConrad Meyer 
1031*9119bafbSConrad Meyer inline uint8_t
1032*9119bafbSConrad Meyer pcg_setseq_16_xsh_rs_8_boundedrand_r(struct pcg_state_setseq_16* rng,
1033*9119bafbSConrad Meyer                                      uint8_t bound)
1034*9119bafbSConrad Meyer {
1035*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
1036*9119bafbSConrad Meyer     for (;;) {
1037*9119bafbSConrad Meyer         uint8_t r = pcg_setseq_16_xsh_rs_8_random_r(rng);
1038*9119bafbSConrad Meyer         if (r >= threshold)
1039*9119bafbSConrad Meyer             return r % bound;
1040*9119bafbSConrad Meyer     }
1041*9119bafbSConrad Meyer }
1042*9119bafbSConrad Meyer 
1043*9119bafbSConrad Meyer inline uint16_t
1044*9119bafbSConrad Meyer pcg_setseq_32_xsh_rs_16_random_r(struct pcg_state_setseq_32* rng)
1045*9119bafbSConrad Meyer {
1046*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
1047*9119bafbSConrad Meyer     pcg_setseq_32_step_r(rng);
1048*9119bafbSConrad Meyer     return pcg_output_xsh_rs_32_16(oldstate);
1049*9119bafbSConrad Meyer }
1050*9119bafbSConrad Meyer 
1051*9119bafbSConrad Meyer inline uint16_t
1052*9119bafbSConrad Meyer pcg_setseq_32_xsh_rs_16_boundedrand_r(struct pcg_state_setseq_32* rng,
1053*9119bafbSConrad Meyer                                       uint16_t bound)
1054*9119bafbSConrad Meyer {
1055*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
1056*9119bafbSConrad Meyer     for (;;) {
1057*9119bafbSConrad Meyer         uint16_t r = pcg_setseq_32_xsh_rs_16_random_r(rng);
1058*9119bafbSConrad Meyer         if (r >= threshold)
1059*9119bafbSConrad Meyer             return r % bound;
1060*9119bafbSConrad Meyer     }
1061*9119bafbSConrad Meyer }
1062*9119bafbSConrad Meyer 
1063*9119bafbSConrad Meyer inline uint32_t
1064*9119bafbSConrad Meyer pcg_setseq_64_xsh_rs_32_random_r(struct pcg_state_setseq_64* rng)
1065*9119bafbSConrad Meyer {
1066*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
1067*9119bafbSConrad Meyer     pcg_setseq_64_step_r(rng);
1068*9119bafbSConrad Meyer     return pcg_output_xsh_rs_64_32(oldstate);
1069*9119bafbSConrad Meyer }
1070*9119bafbSConrad Meyer 
1071*9119bafbSConrad Meyer inline uint32_t
1072*9119bafbSConrad Meyer pcg_setseq_64_xsh_rs_32_boundedrand_r(struct pcg_state_setseq_64* rng,
1073*9119bafbSConrad Meyer                                       uint32_t bound)
1074*9119bafbSConrad Meyer {
1075*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
1076*9119bafbSConrad Meyer     for (;;) {
1077*9119bafbSConrad Meyer         uint32_t r = pcg_setseq_64_xsh_rs_32_random_r(rng);
1078*9119bafbSConrad Meyer         if (r >= threshold)
1079*9119bafbSConrad Meyer             return r % bound;
1080*9119bafbSConrad Meyer     }
1081*9119bafbSConrad Meyer }
1082*9119bafbSConrad Meyer 
1083*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1084*9119bafbSConrad Meyer inline uint64_t
1085*9119bafbSConrad Meyer pcg_setseq_128_xsh_rs_64_random_r(struct pcg_state_setseq_128* rng)
1086*9119bafbSConrad Meyer {
1087*9119bafbSConrad Meyer     pcg_setseq_128_step_r(rng);
1088*9119bafbSConrad Meyer     return pcg_output_xsh_rs_128_64(rng->state);
1089*9119bafbSConrad Meyer }
1090*9119bafbSConrad Meyer #endif
1091*9119bafbSConrad Meyer 
1092*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1093*9119bafbSConrad Meyer inline uint64_t
1094*9119bafbSConrad Meyer pcg_setseq_128_xsh_rs_64_boundedrand_r(struct pcg_state_setseq_128* rng,
1095*9119bafbSConrad Meyer                                        uint64_t bound)
1096*9119bafbSConrad Meyer {
1097*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
1098*9119bafbSConrad Meyer     for (;;) {
1099*9119bafbSConrad Meyer         uint64_t r = pcg_setseq_128_xsh_rs_64_random_r(rng);
1100*9119bafbSConrad Meyer         if (r >= threshold)
1101*9119bafbSConrad Meyer             return r % bound;
1102*9119bafbSConrad Meyer     }
1103*9119bafbSConrad Meyer }
1104*9119bafbSConrad Meyer #endif
1105*9119bafbSConrad Meyer 
1106*9119bafbSConrad Meyer inline uint8_t pcg_mcg_16_xsh_rs_8_random_r(struct pcg_state_16* rng)
1107*9119bafbSConrad Meyer {
1108*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
1109*9119bafbSConrad Meyer     pcg_mcg_16_step_r(rng);
1110*9119bafbSConrad Meyer     return pcg_output_xsh_rs_16_8(oldstate);
1111*9119bafbSConrad Meyer }
1112*9119bafbSConrad Meyer 
1113*9119bafbSConrad Meyer inline uint8_t pcg_mcg_16_xsh_rs_8_boundedrand_r(struct pcg_state_16* rng,
1114*9119bafbSConrad Meyer                                                  uint8_t bound)
1115*9119bafbSConrad Meyer {
1116*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
1117*9119bafbSConrad Meyer     for (;;) {
1118*9119bafbSConrad Meyer         uint8_t r = pcg_mcg_16_xsh_rs_8_random_r(rng);
1119*9119bafbSConrad Meyer         if (r >= threshold)
1120*9119bafbSConrad Meyer             return r % bound;
1121*9119bafbSConrad Meyer     }
1122*9119bafbSConrad Meyer }
1123*9119bafbSConrad Meyer 
1124*9119bafbSConrad Meyer inline uint16_t pcg_mcg_32_xsh_rs_16_random_r(struct pcg_state_32* rng)
1125*9119bafbSConrad Meyer {
1126*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
1127*9119bafbSConrad Meyer     pcg_mcg_32_step_r(rng);
1128*9119bafbSConrad Meyer     return pcg_output_xsh_rs_32_16(oldstate);
1129*9119bafbSConrad Meyer }
1130*9119bafbSConrad Meyer 
1131*9119bafbSConrad Meyer inline uint16_t pcg_mcg_32_xsh_rs_16_boundedrand_r(struct pcg_state_32* rng,
1132*9119bafbSConrad Meyer                                                    uint16_t bound)
1133*9119bafbSConrad Meyer {
1134*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
1135*9119bafbSConrad Meyer     for (;;) {
1136*9119bafbSConrad Meyer         uint16_t r = pcg_mcg_32_xsh_rs_16_random_r(rng);
1137*9119bafbSConrad Meyer         if (r >= threshold)
1138*9119bafbSConrad Meyer             return r % bound;
1139*9119bafbSConrad Meyer     }
1140*9119bafbSConrad Meyer }
1141*9119bafbSConrad Meyer 
1142*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_xsh_rs_32_random_r(struct pcg_state_64* rng)
1143*9119bafbSConrad Meyer {
1144*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
1145*9119bafbSConrad Meyer     pcg_mcg_64_step_r(rng);
1146*9119bafbSConrad Meyer     return pcg_output_xsh_rs_64_32(oldstate);
1147*9119bafbSConrad Meyer }
1148*9119bafbSConrad Meyer 
1149*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_xsh_rs_32_boundedrand_r(struct pcg_state_64* rng,
1150*9119bafbSConrad Meyer                                                    uint32_t bound)
1151*9119bafbSConrad Meyer {
1152*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
1153*9119bafbSConrad Meyer     for (;;) {
1154*9119bafbSConrad Meyer         uint32_t r = pcg_mcg_64_xsh_rs_32_random_r(rng);
1155*9119bafbSConrad Meyer         if (r >= threshold)
1156*9119bafbSConrad Meyer             return r % bound;
1157*9119bafbSConrad Meyer     }
1158*9119bafbSConrad Meyer }
1159*9119bafbSConrad Meyer 
1160*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1161*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_xsh_rs_64_random_r(struct pcg_state_128* rng)
1162*9119bafbSConrad Meyer {
1163*9119bafbSConrad Meyer     pcg_mcg_128_step_r(rng);
1164*9119bafbSConrad Meyer     return pcg_output_xsh_rs_128_64(rng->state);
1165*9119bafbSConrad Meyer }
1166*9119bafbSConrad Meyer #endif
1167*9119bafbSConrad Meyer 
1168*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1169*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_xsh_rs_64_boundedrand_r(struct pcg_state_128* rng,
1170*9119bafbSConrad Meyer                                                     uint64_t bound)
1171*9119bafbSConrad Meyer {
1172*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
1173*9119bafbSConrad Meyer     for (;;) {
1174*9119bafbSConrad Meyer         uint64_t r = pcg_mcg_128_xsh_rs_64_random_r(rng);
1175*9119bafbSConrad Meyer         if (r >= threshold)
1176*9119bafbSConrad Meyer             return r % bound;
1177*9119bafbSConrad Meyer     }
1178*9119bafbSConrad Meyer }
1179*9119bafbSConrad Meyer #endif
1180*9119bafbSConrad Meyer 
1181*9119bafbSConrad Meyer /* Generation functions for XSH RR */
1182*9119bafbSConrad Meyer 
1183*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_16_xsh_rr_8_random_r(struct pcg_state_16* rng)
1184*9119bafbSConrad Meyer {
1185*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
1186*9119bafbSConrad Meyer     pcg_oneseq_16_step_r(rng);
1187*9119bafbSConrad Meyer     return pcg_output_xsh_rr_16_8(oldstate);
1188*9119bafbSConrad Meyer }
1189*9119bafbSConrad Meyer 
1190*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng,
1191*9119bafbSConrad Meyer                                                     uint8_t bound)
1192*9119bafbSConrad Meyer {
1193*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
1194*9119bafbSConrad Meyer     for (;;) {
1195*9119bafbSConrad Meyer         uint8_t r = pcg_oneseq_16_xsh_rr_8_random_r(rng);
1196*9119bafbSConrad Meyer         if (r >= threshold)
1197*9119bafbSConrad Meyer             return r % bound;
1198*9119bafbSConrad Meyer     }
1199*9119bafbSConrad Meyer }
1200*9119bafbSConrad Meyer 
1201*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_32_xsh_rr_16_random_r(struct pcg_state_32* rng)
1202*9119bafbSConrad Meyer {
1203*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
1204*9119bafbSConrad Meyer     pcg_oneseq_32_step_r(rng);
1205*9119bafbSConrad Meyer     return pcg_output_xsh_rr_32_16(oldstate);
1206*9119bafbSConrad Meyer }
1207*9119bafbSConrad Meyer 
1208*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng,
1209*9119bafbSConrad Meyer                                                       uint16_t bound)
1210*9119bafbSConrad Meyer {
1211*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
1212*9119bafbSConrad Meyer     for (;;) {
1213*9119bafbSConrad Meyer         uint16_t r = pcg_oneseq_32_xsh_rr_16_random_r(rng);
1214*9119bafbSConrad Meyer         if (r >= threshold)
1215*9119bafbSConrad Meyer             return r % bound;
1216*9119bafbSConrad Meyer     }
1217*9119bafbSConrad Meyer }
1218*9119bafbSConrad Meyer 
1219*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_xsh_rr_32_random_r(struct pcg_state_64* rng)
1220*9119bafbSConrad Meyer {
1221*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
1222*9119bafbSConrad Meyer     pcg_oneseq_64_step_r(rng);
1223*9119bafbSConrad Meyer     return pcg_output_xsh_rr_64_32(oldstate);
1224*9119bafbSConrad Meyer }
1225*9119bafbSConrad Meyer 
1226*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng,
1227*9119bafbSConrad Meyer                                                       uint32_t bound)
1228*9119bafbSConrad Meyer {
1229*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
1230*9119bafbSConrad Meyer     for (;;) {
1231*9119bafbSConrad Meyer         uint32_t r = pcg_oneseq_64_xsh_rr_32_random_r(rng);
1232*9119bafbSConrad Meyer         if (r >= threshold)
1233*9119bafbSConrad Meyer             return r % bound;
1234*9119bafbSConrad Meyer     }
1235*9119bafbSConrad Meyer }
1236*9119bafbSConrad Meyer 
1237*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1238*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_128_xsh_rr_64_random_r(struct pcg_state_128* rng)
1239*9119bafbSConrad Meyer {
1240*9119bafbSConrad Meyer     pcg_oneseq_128_step_r(rng);
1241*9119bafbSConrad Meyer     return pcg_output_xsh_rr_128_64(rng->state);
1242*9119bafbSConrad Meyer }
1243*9119bafbSConrad Meyer #endif
1244*9119bafbSConrad Meyer 
1245*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1246*9119bafbSConrad Meyer inline uint64_t
1247*9119bafbSConrad Meyer pcg_oneseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
1248*9119bafbSConrad Meyer                                        uint64_t bound)
1249*9119bafbSConrad Meyer {
1250*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
1251*9119bafbSConrad Meyer     for (;;) {
1252*9119bafbSConrad Meyer         uint64_t r = pcg_oneseq_128_xsh_rr_64_random_r(rng);
1253*9119bafbSConrad Meyer         if (r >= threshold)
1254*9119bafbSConrad Meyer             return r % bound;
1255*9119bafbSConrad Meyer     }
1256*9119bafbSConrad Meyer }
1257*9119bafbSConrad Meyer #endif
1258*9119bafbSConrad Meyer 
1259*9119bafbSConrad Meyer inline uint8_t pcg_unique_16_xsh_rr_8_random_r(struct pcg_state_16* rng)
1260*9119bafbSConrad Meyer {
1261*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
1262*9119bafbSConrad Meyer     pcg_unique_16_step_r(rng);
1263*9119bafbSConrad Meyer     return pcg_output_xsh_rr_16_8(oldstate);
1264*9119bafbSConrad Meyer }
1265*9119bafbSConrad Meyer 
1266*9119bafbSConrad Meyer inline uint8_t pcg_unique_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng,
1267*9119bafbSConrad Meyer                                                     uint8_t bound)
1268*9119bafbSConrad Meyer {
1269*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
1270*9119bafbSConrad Meyer     for (;;) {
1271*9119bafbSConrad Meyer         uint8_t r = pcg_unique_16_xsh_rr_8_random_r(rng);
1272*9119bafbSConrad Meyer         if (r >= threshold)
1273*9119bafbSConrad Meyer             return r % bound;
1274*9119bafbSConrad Meyer     }
1275*9119bafbSConrad Meyer }
1276*9119bafbSConrad Meyer 
1277*9119bafbSConrad Meyer inline uint16_t pcg_unique_32_xsh_rr_16_random_r(struct pcg_state_32* rng)
1278*9119bafbSConrad Meyer {
1279*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
1280*9119bafbSConrad Meyer     pcg_unique_32_step_r(rng);
1281*9119bafbSConrad Meyer     return pcg_output_xsh_rr_32_16(oldstate);
1282*9119bafbSConrad Meyer }
1283*9119bafbSConrad Meyer 
1284*9119bafbSConrad Meyer inline uint16_t pcg_unique_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng,
1285*9119bafbSConrad Meyer                                                       uint16_t bound)
1286*9119bafbSConrad Meyer {
1287*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
1288*9119bafbSConrad Meyer     for (;;) {
1289*9119bafbSConrad Meyer         uint16_t r = pcg_unique_32_xsh_rr_16_random_r(rng);
1290*9119bafbSConrad Meyer         if (r >= threshold)
1291*9119bafbSConrad Meyer             return r % bound;
1292*9119bafbSConrad Meyer     }
1293*9119bafbSConrad Meyer }
1294*9119bafbSConrad Meyer 
1295*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_xsh_rr_32_random_r(struct pcg_state_64* rng)
1296*9119bafbSConrad Meyer {
1297*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
1298*9119bafbSConrad Meyer     pcg_unique_64_step_r(rng);
1299*9119bafbSConrad Meyer     return pcg_output_xsh_rr_64_32(oldstate);
1300*9119bafbSConrad Meyer }
1301*9119bafbSConrad Meyer 
1302*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng,
1303*9119bafbSConrad Meyer                                                       uint32_t bound)
1304*9119bafbSConrad Meyer {
1305*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
1306*9119bafbSConrad Meyer     for (;;) {
1307*9119bafbSConrad Meyer         uint32_t r = pcg_unique_64_xsh_rr_32_random_r(rng);
1308*9119bafbSConrad Meyer         if (r >= threshold)
1309*9119bafbSConrad Meyer             return r % bound;
1310*9119bafbSConrad Meyer     }
1311*9119bafbSConrad Meyer }
1312*9119bafbSConrad Meyer 
1313*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1314*9119bafbSConrad Meyer inline uint64_t pcg_unique_128_xsh_rr_64_random_r(struct pcg_state_128* rng)
1315*9119bafbSConrad Meyer {
1316*9119bafbSConrad Meyer     pcg_unique_128_step_r(rng);
1317*9119bafbSConrad Meyer     return pcg_output_xsh_rr_128_64(rng->state);
1318*9119bafbSConrad Meyer }
1319*9119bafbSConrad Meyer #endif
1320*9119bafbSConrad Meyer 
1321*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1322*9119bafbSConrad Meyer inline uint64_t
1323*9119bafbSConrad Meyer pcg_unique_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
1324*9119bafbSConrad Meyer                                        uint64_t bound)
1325*9119bafbSConrad Meyer {
1326*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
1327*9119bafbSConrad Meyer     for (;;) {
1328*9119bafbSConrad Meyer         uint64_t r = pcg_unique_128_xsh_rr_64_random_r(rng);
1329*9119bafbSConrad Meyer         if (r >= threshold)
1330*9119bafbSConrad Meyer             return r % bound;
1331*9119bafbSConrad Meyer     }
1332*9119bafbSConrad Meyer }
1333*9119bafbSConrad Meyer #endif
1334*9119bafbSConrad Meyer 
1335*9119bafbSConrad Meyer inline uint8_t pcg_setseq_16_xsh_rr_8_random_r(struct pcg_state_setseq_16* rng)
1336*9119bafbSConrad Meyer {
1337*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
1338*9119bafbSConrad Meyer     pcg_setseq_16_step_r(rng);
1339*9119bafbSConrad Meyer     return pcg_output_xsh_rr_16_8(oldstate);
1340*9119bafbSConrad Meyer }
1341*9119bafbSConrad Meyer 
1342*9119bafbSConrad Meyer inline uint8_t
1343*9119bafbSConrad Meyer pcg_setseq_16_xsh_rr_8_boundedrand_r(struct pcg_state_setseq_16* rng,
1344*9119bafbSConrad Meyer                                      uint8_t bound)
1345*9119bafbSConrad Meyer {
1346*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
1347*9119bafbSConrad Meyer     for (;;) {
1348*9119bafbSConrad Meyer         uint8_t r = pcg_setseq_16_xsh_rr_8_random_r(rng);
1349*9119bafbSConrad Meyer         if (r >= threshold)
1350*9119bafbSConrad Meyer             return r % bound;
1351*9119bafbSConrad Meyer     }
1352*9119bafbSConrad Meyer }
1353*9119bafbSConrad Meyer 
1354*9119bafbSConrad Meyer inline uint16_t
1355*9119bafbSConrad Meyer pcg_setseq_32_xsh_rr_16_random_r(struct pcg_state_setseq_32* rng)
1356*9119bafbSConrad Meyer {
1357*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
1358*9119bafbSConrad Meyer     pcg_setseq_32_step_r(rng);
1359*9119bafbSConrad Meyer     return pcg_output_xsh_rr_32_16(oldstate);
1360*9119bafbSConrad Meyer }
1361*9119bafbSConrad Meyer 
1362*9119bafbSConrad Meyer inline uint16_t
1363*9119bafbSConrad Meyer pcg_setseq_32_xsh_rr_16_boundedrand_r(struct pcg_state_setseq_32* rng,
1364*9119bafbSConrad Meyer                                       uint16_t bound)
1365*9119bafbSConrad Meyer {
1366*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
1367*9119bafbSConrad Meyer     for (;;) {
1368*9119bafbSConrad Meyer         uint16_t r = pcg_setseq_32_xsh_rr_16_random_r(rng);
1369*9119bafbSConrad Meyer         if (r >= threshold)
1370*9119bafbSConrad Meyer             return r % bound;
1371*9119bafbSConrad Meyer     }
1372*9119bafbSConrad Meyer }
1373*9119bafbSConrad Meyer 
1374*9119bafbSConrad Meyer inline uint32_t
1375*9119bafbSConrad Meyer pcg_setseq_64_xsh_rr_32_random_r(struct pcg_state_setseq_64* rng)
1376*9119bafbSConrad Meyer {
1377*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
1378*9119bafbSConrad Meyer     pcg_setseq_64_step_r(rng);
1379*9119bafbSConrad Meyer     return pcg_output_xsh_rr_64_32(oldstate);
1380*9119bafbSConrad Meyer }
1381*9119bafbSConrad Meyer 
1382*9119bafbSConrad Meyer inline uint32_t
1383*9119bafbSConrad Meyer pcg_setseq_64_xsh_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,
1384*9119bafbSConrad Meyer                                       uint32_t bound)
1385*9119bafbSConrad Meyer {
1386*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
1387*9119bafbSConrad Meyer     for (;;) {
1388*9119bafbSConrad Meyer         uint32_t r = pcg_setseq_64_xsh_rr_32_random_r(rng);
1389*9119bafbSConrad Meyer         if (r >= threshold)
1390*9119bafbSConrad Meyer             return r % bound;
1391*9119bafbSConrad Meyer     }
1392*9119bafbSConrad Meyer }
1393*9119bafbSConrad Meyer 
1394*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1395*9119bafbSConrad Meyer inline uint64_t
1396*9119bafbSConrad Meyer pcg_setseq_128_xsh_rr_64_random_r(struct pcg_state_setseq_128* rng)
1397*9119bafbSConrad Meyer {
1398*9119bafbSConrad Meyer     pcg_setseq_128_step_r(rng);
1399*9119bafbSConrad Meyer     return pcg_output_xsh_rr_128_64(rng->state);
1400*9119bafbSConrad Meyer }
1401*9119bafbSConrad Meyer #endif
1402*9119bafbSConrad Meyer 
1403*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1404*9119bafbSConrad Meyer inline uint64_t
1405*9119bafbSConrad Meyer pcg_setseq_128_xsh_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,
1406*9119bafbSConrad Meyer                                        uint64_t bound)
1407*9119bafbSConrad Meyer {
1408*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
1409*9119bafbSConrad Meyer     for (;;) {
1410*9119bafbSConrad Meyer         uint64_t r = pcg_setseq_128_xsh_rr_64_random_r(rng);
1411*9119bafbSConrad Meyer         if (r >= threshold)
1412*9119bafbSConrad Meyer             return r % bound;
1413*9119bafbSConrad Meyer     }
1414*9119bafbSConrad Meyer }
1415*9119bafbSConrad Meyer #endif
1416*9119bafbSConrad Meyer 
1417*9119bafbSConrad Meyer inline uint8_t pcg_mcg_16_xsh_rr_8_random_r(struct pcg_state_16* rng)
1418*9119bafbSConrad Meyer {
1419*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
1420*9119bafbSConrad Meyer     pcg_mcg_16_step_r(rng);
1421*9119bafbSConrad Meyer     return pcg_output_xsh_rr_16_8(oldstate);
1422*9119bafbSConrad Meyer }
1423*9119bafbSConrad Meyer 
1424*9119bafbSConrad Meyer inline uint8_t pcg_mcg_16_xsh_rr_8_boundedrand_r(struct pcg_state_16* rng,
1425*9119bafbSConrad Meyer                                                  uint8_t bound)
1426*9119bafbSConrad Meyer {
1427*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
1428*9119bafbSConrad Meyer     for (;;) {
1429*9119bafbSConrad Meyer         uint8_t r = pcg_mcg_16_xsh_rr_8_random_r(rng);
1430*9119bafbSConrad Meyer         if (r >= threshold)
1431*9119bafbSConrad Meyer             return r % bound;
1432*9119bafbSConrad Meyer     }
1433*9119bafbSConrad Meyer }
1434*9119bafbSConrad Meyer 
1435*9119bafbSConrad Meyer inline uint16_t pcg_mcg_32_xsh_rr_16_random_r(struct pcg_state_32* rng)
1436*9119bafbSConrad Meyer {
1437*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
1438*9119bafbSConrad Meyer     pcg_mcg_32_step_r(rng);
1439*9119bafbSConrad Meyer     return pcg_output_xsh_rr_32_16(oldstate);
1440*9119bafbSConrad Meyer }
1441*9119bafbSConrad Meyer 
1442*9119bafbSConrad Meyer inline uint16_t pcg_mcg_32_xsh_rr_16_boundedrand_r(struct pcg_state_32* rng,
1443*9119bafbSConrad Meyer                                                    uint16_t bound)
1444*9119bafbSConrad Meyer {
1445*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
1446*9119bafbSConrad Meyer     for (;;) {
1447*9119bafbSConrad Meyer         uint16_t r = pcg_mcg_32_xsh_rr_16_random_r(rng);
1448*9119bafbSConrad Meyer         if (r >= threshold)
1449*9119bafbSConrad Meyer             return r % bound;
1450*9119bafbSConrad Meyer     }
1451*9119bafbSConrad Meyer }
1452*9119bafbSConrad Meyer 
1453*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_xsh_rr_32_random_r(struct pcg_state_64* rng)
1454*9119bafbSConrad Meyer {
1455*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
1456*9119bafbSConrad Meyer     pcg_mcg_64_step_r(rng);
1457*9119bafbSConrad Meyer     return pcg_output_xsh_rr_64_32(oldstate);
1458*9119bafbSConrad Meyer }
1459*9119bafbSConrad Meyer 
1460*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_xsh_rr_32_boundedrand_r(struct pcg_state_64* rng,
1461*9119bafbSConrad Meyer                                                    uint32_t bound)
1462*9119bafbSConrad Meyer {
1463*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
1464*9119bafbSConrad Meyer     for (;;) {
1465*9119bafbSConrad Meyer         uint32_t r = pcg_mcg_64_xsh_rr_32_random_r(rng);
1466*9119bafbSConrad Meyer         if (r >= threshold)
1467*9119bafbSConrad Meyer             return r % bound;
1468*9119bafbSConrad Meyer     }
1469*9119bafbSConrad Meyer }
1470*9119bafbSConrad Meyer 
1471*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1472*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_xsh_rr_64_random_r(struct pcg_state_128* rng)
1473*9119bafbSConrad Meyer {
1474*9119bafbSConrad Meyer     pcg_mcg_128_step_r(rng);
1475*9119bafbSConrad Meyer     return pcg_output_xsh_rr_128_64(rng->state);
1476*9119bafbSConrad Meyer }
1477*9119bafbSConrad Meyer #endif
1478*9119bafbSConrad Meyer 
1479*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1480*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_xsh_rr_64_boundedrand_r(struct pcg_state_128* rng,
1481*9119bafbSConrad Meyer                                                     uint64_t bound)
1482*9119bafbSConrad Meyer {
1483*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
1484*9119bafbSConrad Meyer     for (;;) {
1485*9119bafbSConrad Meyer         uint64_t r = pcg_mcg_128_xsh_rr_64_random_r(rng);
1486*9119bafbSConrad Meyer         if (r >= threshold)
1487*9119bafbSConrad Meyer             return r % bound;
1488*9119bafbSConrad Meyer     }
1489*9119bafbSConrad Meyer }
1490*9119bafbSConrad Meyer #endif
1491*9119bafbSConrad Meyer 
1492*9119bafbSConrad Meyer /* Generation functions for RXS M XS (no MCG versions because they
1493*9119bafbSConrad Meyer  * don't make sense when you want to use the entire state)
1494*9119bafbSConrad Meyer  */
1495*9119bafbSConrad Meyer 
1496*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_8_rxs_m_xs_8_random_r(struct pcg_state_8* rng)
1497*9119bafbSConrad Meyer {
1498*9119bafbSConrad Meyer     uint8_t oldstate = rng->state;
1499*9119bafbSConrad Meyer     pcg_oneseq_8_step_r(rng);
1500*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_8_8(oldstate);
1501*9119bafbSConrad Meyer }
1502*9119bafbSConrad Meyer 
1503*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_8* rng,
1504*9119bafbSConrad Meyer                                                      uint8_t bound)
1505*9119bafbSConrad Meyer {
1506*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
1507*9119bafbSConrad Meyer     for (;;) {
1508*9119bafbSConrad Meyer         uint8_t r = pcg_oneseq_8_rxs_m_xs_8_random_r(rng);
1509*9119bafbSConrad Meyer         if (r >= threshold)
1510*9119bafbSConrad Meyer             return r % bound;
1511*9119bafbSConrad Meyer     }
1512*9119bafbSConrad Meyer }
1513*9119bafbSConrad Meyer 
1514*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng)
1515*9119bafbSConrad Meyer {
1516*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
1517*9119bafbSConrad Meyer     pcg_oneseq_16_step_r(rng);
1518*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_16_16(oldstate);
1519*9119bafbSConrad Meyer }
1520*9119bafbSConrad Meyer 
1521*9119bafbSConrad Meyer inline uint16_t
1522*9119bafbSConrad Meyer pcg_oneseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng,
1523*9119bafbSConrad Meyer                                         uint16_t bound)
1524*9119bafbSConrad Meyer {
1525*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
1526*9119bafbSConrad Meyer     for (;;) {
1527*9119bafbSConrad Meyer         uint16_t r = pcg_oneseq_16_rxs_m_xs_16_random_r(rng);
1528*9119bafbSConrad Meyer         if (r >= threshold)
1529*9119bafbSConrad Meyer             return r % bound;
1530*9119bafbSConrad Meyer     }
1531*9119bafbSConrad Meyer }
1532*9119bafbSConrad Meyer 
1533*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng)
1534*9119bafbSConrad Meyer {
1535*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
1536*9119bafbSConrad Meyer     pcg_oneseq_32_step_r(rng);
1537*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_32_32(oldstate);
1538*9119bafbSConrad Meyer }
1539*9119bafbSConrad Meyer 
1540*9119bafbSConrad Meyer inline uint32_t
1541*9119bafbSConrad Meyer pcg_oneseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng,
1542*9119bafbSConrad Meyer                                         uint32_t bound)
1543*9119bafbSConrad Meyer {
1544*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
1545*9119bafbSConrad Meyer     for (;;) {
1546*9119bafbSConrad Meyer         uint32_t r = pcg_oneseq_32_rxs_m_xs_32_random_r(rng);
1547*9119bafbSConrad Meyer         if (r >= threshold)
1548*9119bafbSConrad Meyer             return r % bound;
1549*9119bafbSConrad Meyer     }
1550*9119bafbSConrad Meyer }
1551*9119bafbSConrad Meyer 
1552*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng)
1553*9119bafbSConrad Meyer {
1554*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
1555*9119bafbSConrad Meyer     pcg_oneseq_64_step_r(rng);
1556*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_64_64(oldstate);
1557*9119bafbSConrad Meyer }
1558*9119bafbSConrad Meyer 
1559*9119bafbSConrad Meyer inline uint64_t
1560*9119bafbSConrad Meyer pcg_oneseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,
1561*9119bafbSConrad Meyer                                         uint64_t bound)
1562*9119bafbSConrad Meyer {
1563*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
1564*9119bafbSConrad Meyer     for (;;) {
1565*9119bafbSConrad Meyer         uint64_t r = pcg_oneseq_64_rxs_m_xs_64_random_r(rng);
1566*9119bafbSConrad Meyer         if (r >= threshold)
1567*9119bafbSConrad Meyer             return r % bound;
1568*9119bafbSConrad Meyer     }
1569*9119bafbSConrad Meyer }
1570*9119bafbSConrad Meyer 
1571*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1572*9119bafbSConrad Meyer inline pcg128_t pcg_oneseq_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng)
1573*9119bafbSConrad Meyer {
1574*9119bafbSConrad Meyer     pcg_oneseq_128_step_r(rng);
1575*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_128_128(rng->state);
1576*9119bafbSConrad Meyer }
1577*9119bafbSConrad Meyer #endif
1578*9119bafbSConrad Meyer 
1579*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1580*9119bafbSConrad Meyer inline pcg128_t
1581*9119bafbSConrad Meyer pcg_oneseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,
1582*9119bafbSConrad Meyer                                           pcg128_t bound)
1583*9119bafbSConrad Meyer {
1584*9119bafbSConrad Meyer     pcg128_t threshold = -bound % bound;
1585*9119bafbSConrad Meyer     for (;;) {
1586*9119bafbSConrad Meyer         pcg128_t r = pcg_oneseq_128_rxs_m_xs_128_random_r(rng);
1587*9119bafbSConrad Meyer         if (r >= threshold)
1588*9119bafbSConrad Meyer             return r % bound;
1589*9119bafbSConrad Meyer     }
1590*9119bafbSConrad Meyer }
1591*9119bafbSConrad Meyer #endif
1592*9119bafbSConrad Meyer 
1593*9119bafbSConrad Meyer inline uint16_t pcg_unique_16_rxs_m_xs_16_random_r(struct pcg_state_16* rng)
1594*9119bafbSConrad Meyer {
1595*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
1596*9119bafbSConrad Meyer     pcg_unique_16_step_r(rng);
1597*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_16_16(oldstate);
1598*9119bafbSConrad Meyer }
1599*9119bafbSConrad Meyer 
1600*9119bafbSConrad Meyer inline uint16_t
1601*9119bafbSConrad Meyer pcg_unique_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_16* rng,
1602*9119bafbSConrad Meyer                                         uint16_t bound)
1603*9119bafbSConrad Meyer {
1604*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
1605*9119bafbSConrad Meyer     for (;;) {
1606*9119bafbSConrad Meyer         uint16_t r = pcg_unique_16_rxs_m_xs_16_random_r(rng);
1607*9119bafbSConrad Meyer         if (r >= threshold)
1608*9119bafbSConrad Meyer             return r % bound;
1609*9119bafbSConrad Meyer     }
1610*9119bafbSConrad Meyer }
1611*9119bafbSConrad Meyer 
1612*9119bafbSConrad Meyer inline uint32_t pcg_unique_32_rxs_m_xs_32_random_r(struct pcg_state_32* rng)
1613*9119bafbSConrad Meyer {
1614*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
1615*9119bafbSConrad Meyer     pcg_unique_32_step_r(rng);
1616*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_32_32(oldstate);
1617*9119bafbSConrad Meyer }
1618*9119bafbSConrad Meyer 
1619*9119bafbSConrad Meyer inline uint32_t
1620*9119bafbSConrad Meyer pcg_unique_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_32* rng,
1621*9119bafbSConrad Meyer                                         uint32_t bound)
1622*9119bafbSConrad Meyer {
1623*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
1624*9119bafbSConrad Meyer     for (;;) {
1625*9119bafbSConrad Meyer         uint32_t r = pcg_unique_32_rxs_m_xs_32_random_r(rng);
1626*9119bafbSConrad Meyer         if (r >= threshold)
1627*9119bafbSConrad Meyer             return r % bound;
1628*9119bafbSConrad Meyer     }
1629*9119bafbSConrad Meyer }
1630*9119bafbSConrad Meyer 
1631*9119bafbSConrad Meyer inline uint64_t pcg_unique_64_rxs_m_xs_64_random_r(struct pcg_state_64* rng)
1632*9119bafbSConrad Meyer {
1633*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
1634*9119bafbSConrad Meyer     pcg_unique_64_step_r(rng);
1635*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_64_64(oldstate);
1636*9119bafbSConrad Meyer }
1637*9119bafbSConrad Meyer 
1638*9119bafbSConrad Meyer inline uint64_t
1639*9119bafbSConrad Meyer pcg_unique_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_64* rng,
1640*9119bafbSConrad Meyer                                         uint64_t bound)
1641*9119bafbSConrad Meyer {
1642*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
1643*9119bafbSConrad Meyer     for (;;) {
1644*9119bafbSConrad Meyer         uint64_t r = pcg_unique_64_rxs_m_xs_64_random_r(rng);
1645*9119bafbSConrad Meyer         if (r >= threshold)
1646*9119bafbSConrad Meyer             return r % bound;
1647*9119bafbSConrad Meyer     }
1648*9119bafbSConrad Meyer }
1649*9119bafbSConrad Meyer 
1650*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1651*9119bafbSConrad Meyer inline pcg128_t pcg_unique_128_rxs_m_xs_128_random_r(struct pcg_state_128* rng)
1652*9119bafbSConrad Meyer {
1653*9119bafbSConrad Meyer     pcg_unique_128_step_r(rng);
1654*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_128_128(rng->state);
1655*9119bafbSConrad Meyer }
1656*9119bafbSConrad Meyer #endif
1657*9119bafbSConrad Meyer 
1658*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1659*9119bafbSConrad Meyer inline pcg128_t
1660*9119bafbSConrad Meyer pcg_unique_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_128* rng,
1661*9119bafbSConrad Meyer                                           pcg128_t bound)
1662*9119bafbSConrad Meyer {
1663*9119bafbSConrad Meyer     pcg128_t threshold = -bound % bound;
1664*9119bafbSConrad Meyer     for (;;) {
1665*9119bafbSConrad Meyer         pcg128_t r = pcg_unique_128_rxs_m_xs_128_random_r(rng);
1666*9119bafbSConrad Meyer         if (r >= threshold)
1667*9119bafbSConrad Meyer             return r % bound;
1668*9119bafbSConrad Meyer     }
1669*9119bafbSConrad Meyer }
1670*9119bafbSConrad Meyer #endif
1671*9119bafbSConrad Meyer 
1672*9119bafbSConrad Meyer inline uint8_t pcg_setseq_8_rxs_m_xs_8_random_r(struct pcg_state_setseq_8* rng)
1673*9119bafbSConrad Meyer {
1674*9119bafbSConrad Meyer     uint8_t oldstate = rng->state;
1675*9119bafbSConrad Meyer     pcg_setseq_8_step_r(rng);
1676*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_8_8(oldstate);
1677*9119bafbSConrad Meyer }
1678*9119bafbSConrad Meyer 
1679*9119bafbSConrad Meyer inline uint8_t
1680*9119bafbSConrad Meyer pcg_setseq_8_rxs_m_xs_8_boundedrand_r(struct pcg_state_setseq_8* rng,
1681*9119bafbSConrad Meyer                                       uint8_t bound)
1682*9119bafbSConrad Meyer {
1683*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
1684*9119bafbSConrad Meyer     for (;;) {
1685*9119bafbSConrad Meyer         uint8_t r = pcg_setseq_8_rxs_m_xs_8_random_r(rng);
1686*9119bafbSConrad Meyer         if (r >= threshold)
1687*9119bafbSConrad Meyer             return r % bound;
1688*9119bafbSConrad Meyer     }
1689*9119bafbSConrad Meyer }
1690*9119bafbSConrad Meyer 
1691*9119bafbSConrad Meyer inline uint16_t
1692*9119bafbSConrad Meyer pcg_setseq_16_rxs_m_xs_16_random_r(struct pcg_state_setseq_16* rng)
1693*9119bafbSConrad Meyer {
1694*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
1695*9119bafbSConrad Meyer     pcg_setseq_16_step_r(rng);
1696*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_16_16(oldstate);
1697*9119bafbSConrad Meyer }
1698*9119bafbSConrad Meyer 
1699*9119bafbSConrad Meyer inline uint16_t
1700*9119bafbSConrad Meyer pcg_setseq_16_rxs_m_xs_16_boundedrand_r(struct pcg_state_setseq_16* rng,
1701*9119bafbSConrad Meyer                                         uint16_t bound)
1702*9119bafbSConrad Meyer {
1703*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
1704*9119bafbSConrad Meyer     for (;;) {
1705*9119bafbSConrad Meyer         uint16_t r = pcg_setseq_16_rxs_m_xs_16_random_r(rng);
1706*9119bafbSConrad Meyer         if (r >= threshold)
1707*9119bafbSConrad Meyer             return r % bound;
1708*9119bafbSConrad Meyer     }
1709*9119bafbSConrad Meyer }
1710*9119bafbSConrad Meyer 
1711*9119bafbSConrad Meyer inline uint32_t
1712*9119bafbSConrad Meyer pcg_setseq_32_rxs_m_xs_32_random_r(struct pcg_state_setseq_32* rng)
1713*9119bafbSConrad Meyer {
1714*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
1715*9119bafbSConrad Meyer     pcg_setseq_32_step_r(rng);
1716*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_32_32(oldstate);
1717*9119bafbSConrad Meyer }
1718*9119bafbSConrad Meyer 
1719*9119bafbSConrad Meyer inline uint32_t
1720*9119bafbSConrad Meyer pcg_setseq_32_rxs_m_xs_32_boundedrand_r(struct pcg_state_setseq_32* rng,
1721*9119bafbSConrad Meyer                                         uint32_t bound)
1722*9119bafbSConrad Meyer {
1723*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
1724*9119bafbSConrad Meyer     for (;;) {
1725*9119bafbSConrad Meyer         uint32_t r = pcg_setseq_32_rxs_m_xs_32_random_r(rng);
1726*9119bafbSConrad Meyer         if (r >= threshold)
1727*9119bafbSConrad Meyer             return r % bound;
1728*9119bafbSConrad Meyer     }
1729*9119bafbSConrad Meyer }
1730*9119bafbSConrad Meyer 
1731*9119bafbSConrad Meyer inline uint64_t
1732*9119bafbSConrad Meyer pcg_setseq_64_rxs_m_xs_64_random_r(struct pcg_state_setseq_64* rng)
1733*9119bafbSConrad Meyer {
1734*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
1735*9119bafbSConrad Meyer     pcg_setseq_64_step_r(rng);
1736*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_64_64(oldstate);
1737*9119bafbSConrad Meyer }
1738*9119bafbSConrad Meyer 
1739*9119bafbSConrad Meyer inline uint64_t
1740*9119bafbSConrad Meyer pcg_setseq_64_rxs_m_xs_64_boundedrand_r(struct pcg_state_setseq_64* rng,
1741*9119bafbSConrad Meyer                                         uint64_t bound)
1742*9119bafbSConrad Meyer {
1743*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
1744*9119bafbSConrad Meyer     for (;;) {
1745*9119bafbSConrad Meyer         uint64_t r = pcg_setseq_64_rxs_m_xs_64_random_r(rng);
1746*9119bafbSConrad Meyer         if (r >= threshold)
1747*9119bafbSConrad Meyer             return r % bound;
1748*9119bafbSConrad Meyer     }
1749*9119bafbSConrad Meyer }
1750*9119bafbSConrad Meyer 
1751*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1752*9119bafbSConrad Meyer inline pcg128_t
1753*9119bafbSConrad Meyer pcg_setseq_128_rxs_m_xs_128_random_r(struct pcg_state_setseq_128* rng)
1754*9119bafbSConrad Meyer {
1755*9119bafbSConrad Meyer     pcg_setseq_128_step_r(rng);
1756*9119bafbSConrad Meyer     return pcg_output_rxs_m_xs_128_128(rng->state);
1757*9119bafbSConrad Meyer }
1758*9119bafbSConrad Meyer #endif
1759*9119bafbSConrad Meyer 
1760*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1761*9119bafbSConrad Meyer inline pcg128_t
1762*9119bafbSConrad Meyer pcg_setseq_128_rxs_m_xs_128_boundedrand_r(struct pcg_state_setseq_128* rng,
1763*9119bafbSConrad Meyer                                           pcg128_t bound)
1764*9119bafbSConrad Meyer {
1765*9119bafbSConrad Meyer     pcg128_t threshold = -bound % bound;
1766*9119bafbSConrad Meyer     for (;;) {
1767*9119bafbSConrad Meyer         pcg128_t r = pcg_setseq_128_rxs_m_xs_128_random_r(rng);
1768*9119bafbSConrad Meyer         if (r >= threshold)
1769*9119bafbSConrad Meyer             return r % bound;
1770*9119bafbSConrad Meyer     }
1771*9119bafbSConrad Meyer }
1772*9119bafbSConrad Meyer #endif
1773*9119bafbSConrad Meyer 
1774*9119bafbSConrad Meyer /* Generation functions for RXS M */
1775*9119bafbSConrad Meyer 
1776*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_16_rxs_m_8_random_r(struct pcg_state_16* rng)
1777*9119bafbSConrad Meyer {
1778*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
1779*9119bafbSConrad Meyer     pcg_oneseq_16_step_r(rng);
1780*9119bafbSConrad Meyer     return pcg_output_rxs_m_16_8(oldstate);
1781*9119bafbSConrad Meyer }
1782*9119bafbSConrad Meyer 
1783*9119bafbSConrad Meyer inline uint8_t pcg_oneseq_16_rxs_m_8_boundedrand_r(struct pcg_state_16* rng,
1784*9119bafbSConrad Meyer                                                    uint8_t bound)
1785*9119bafbSConrad Meyer {
1786*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
1787*9119bafbSConrad Meyer     for (;;) {
1788*9119bafbSConrad Meyer         uint8_t r = pcg_oneseq_16_rxs_m_8_random_r(rng);
1789*9119bafbSConrad Meyer         if (r >= threshold)
1790*9119bafbSConrad Meyer             return r % bound;
1791*9119bafbSConrad Meyer     }
1792*9119bafbSConrad Meyer }
1793*9119bafbSConrad Meyer 
1794*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_32_rxs_m_16_random_r(struct pcg_state_32* rng)
1795*9119bafbSConrad Meyer {
1796*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
1797*9119bafbSConrad Meyer     pcg_oneseq_32_step_r(rng);
1798*9119bafbSConrad Meyer     return pcg_output_rxs_m_32_16(oldstate);
1799*9119bafbSConrad Meyer }
1800*9119bafbSConrad Meyer 
1801*9119bafbSConrad Meyer inline uint16_t pcg_oneseq_32_rxs_m_16_boundedrand_r(struct pcg_state_32* rng,
1802*9119bafbSConrad Meyer                                                      uint16_t bound)
1803*9119bafbSConrad Meyer {
1804*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
1805*9119bafbSConrad Meyer     for (;;) {
1806*9119bafbSConrad Meyer         uint16_t r = pcg_oneseq_32_rxs_m_16_random_r(rng);
1807*9119bafbSConrad Meyer         if (r >= threshold)
1808*9119bafbSConrad Meyer             return r % bound;
1809*9119bafbSConrad Meyer     }
1810*9119bafbSConrad Meyer }
1811*9119bafbSConrad Meyer 
1812*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_rxs_m_32_random_r(struct pcg_state_64* rng)
1813*9119bafbSConrad Meyer {
1814*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
1815*9119bafbSConrad Meyer     pcg_oneseq_64_step_r(rng);
1816*9119bafbSConrad Meyer     return pcg_output_rxs_m_64_32(oldstate);
1817*9119bafbSConrad Meyer }
1818*9119bafbSConrad Meyer 
1819*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_rxs_m_32_boundedrand_r(struct pcg_state_64* rng,
1820*9119bafbSConrad Meyer                                                      uint32_t bound)
1821*9119bafbSConrad Meyer {
1822*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
1823*9119bafbSConrad Meyer     for (;;) {
1824*9119bafbSConrad Meyer         uint32_t r = pcg_oneseq_64_rxs_m_32_random_r(rng);
1825*9119bafbSConrad Meyer         if (r >= threshold)
1826*9119bafbSConrad Meyer             return r % bound;
1827*9119bafbSConrad Meyer     }
1828*9119bafbSConrad Meyer }
1829*9119bafbSConrad Meyer 
1830*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1831*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_128_rxs_m_64_random_r(struct pcg_state_128* rng)
1832*9119bafbSConrad Meyer {
1833*9119bafbSConrad Meyer     pcg_oneseq_128_step_r(rng);
1834*9119bafbSConrad Meyer     return pcg_output_rxs_m_128_64(rng->state);
1835*9119bafbSConrad Meyer }
1836*9119bafbSConrad Meyer #endif
1837*9119bafbSConrad Meyer 
1838*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1839*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_128_rxs_m_64_boundedrand_r(struct pcg_state_128* rng,
1840*9119bafbSConrad Meyer                                                       uint64_t bound)
1841*9119bafbSConrad Meyer {
1842*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
1843*9119bafbSConrad Meyer     for (;;) {
1844*9119bafbSConrad Meyer         uint64_t r = pcg_oneseq_128_rxs_m_64_random_r(rng);
1845*9119bafbSConrad Meyer         if (r >= threshold)
1846*9119bafbSConrad Meyer             return r % bound;
1847*9119bafbSConrad Meyer     }
1848*9119bafbSConrad Meyer }
1849*9119bafbSConrad Meyer #endif
1850*9119bafbSConrad Meyer 
1851*9119bafbSConrad Meyer inline uint8_t pcg_unique_16_rxs_m_8_random_r(struct pcg_state_16* rng)
1852*9119bafbSConrad Meyer {
1853*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
1854*9119bafbSConrad Meyer     pcg_unique_16_step_r(rng);
1855*9119bafbSConrad Meyer     return pcg_output_rxs_m_16_8(oldstate);
1856*9119bafbSConrad Meyer }
1857*9119bafbSConrad Meyer 
1858*9119bafbSConrad Meyer inline uint8_t pcg_unique_16_rxs_m_8_boundedrand_r(struct pcg_state_16* rng,
1859*9119bafbSConrad Meyer                                                    uint8_t bound)
1860*9119bafbSConrad Meyer {
1861*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
1862*9119bafbSConrad Meyer     for (;;) {
1863*9119bafbSConrad Meyer         uint8_t r = pcg_unique_16_rxs_m_8_random_r(rng);
1864*9119bafbSConrad Meyer         if (r >= threshold)
1865*9119bafbSConrad Meyer             return r % bound;
1866*9119bafbSConrad Meyer     }
1867*9119bafbSConrad Meyer }
1868*9119bafbSConrad Meyer 
1869*9119bafbSConrad Meyer inline uint16_t pcg_unique_32_rxs_m_16_random_r(struct pcg_state_32* rng)
1870*9119bafbSConrad Meyer {
1871*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
1872*9119bafbSConrad Meyer     pcg_unique_32_step_r(rng);
1873*9119bafbSConrad Meyer     return pcg_output_rxs_m_32_16(oldstate);
1874*9119bafbSConrad Meyer }
1875*9119bafbSConrad Meyer 
1876*9119bafbSConrad Meyer inline uint16_t pcg_unique_32_rxs_m_16_boundedrand_r(struct pcg_state_32* rng,
1877*9119bafbSConrad Meyer                                                      uint16_t bound)
1878*9119bafbSConrad Meyer {
1879*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
1880*9119bafbSConrad Meyer     for (;;) {
1881*9119bafbSConrad Meyer         uint16_t r = pcg_unique_32_rxs_m_16_random_r(rng);
1882*9119bafbSConrad Meyer         if (r >= threshold)
1883*9119bafbSConrad Meyer             return r % bound;
1884*9119bafbSConrad Meyer     }
1885*9119bafbSConrad Meyer }
1886*9119bafbSConrad Meyer 
1887*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_rxs_m_32_random_r(struct pcg_state_64* rng)
1888*9119bafbSConrad Meyer {
1889*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
1890*9119bafbSConrad Meyer     pcg_unique_64_step_r(rng);
1891*9119bafbSConrad Meyer     return pcg_output_rxs_m_64_32(oldstate);
1892*9119bafbSConrad Meyer }
1893*9119bafbSConrad Meyer 
1894*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_rxs_m_32_boundedrand_r(struct pcg_state_64* rng,
1895*9119bafbSConrad Meyer                                                      uint32_t bound)
1896*9119bafbSConrad Meyer {
1897*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
1898*9119bafbSConrad Meyer     for (;;) {
1899*9119bafbSConrad Meyer         uint32_t r = pcg_unique_64_rxs_m_32_random_r(rng);
1900*9119bafbSConrad Meyer         if (r >= threshold)
1901*9119bafbSConrad Meyer             return r % bound;
1902*9119bafbSConrad Meyer     }
1903*9119bafbSConrad Meyer }
1904*9119bafbSConrad Meyer 
1905*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1906*9119bafbSConrad Meyer inline uint64_t pcg_unique_128_rxs_m_64_random_r(struct pcg_state_128* rng)
1907*9119bafbSConrad Meyer {
1908*9119bafbSConrad Meyer     pcg_unique_128_step_r(rng);
1909*9119bafbSConrad Meyer     return pcg_output_rxs_m_128_64(rng->state);
1910*9119bafbSConrad Meyer }
1911*9119bafbSConrad Meyer #endif
1912*9119bafbSConrad Meyer 
1913*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1914*9119bafbSConrad Meyer inline uint64_t pcg_unique_128_rxs_m_64_boundedrand_r(struct pcg_state_128* rng,
1915*9119bafbSConrad Meyer                                                       uint64_t bound)
1916*9119bafbSConrad Meyer {
1917*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
1918*9119bafbSConrad Meyer     for (;;) {
1919*9119bafbSConrad Meyer         uint64_t r = pcg_unique_128_rxs_m_64_random_r(rng);
1920*9119bafbSConrad Meyer         if (r >= threshold)
1921*9119bafbSConrad Meyer             return r % bound;
1922*9119bafbSConrad Meyer     }
1923*9119bafbSConrad Meyer }
1924*9119bafbSConrad Meyer #endif
1925*9119bafbSConrad Meyer 
1926*9119bafbSConrad Meyer inline uint8_t pcg_setseq_16_rxs_m_8_random_r(struct pcg_state_setseq_16* rng)
1927*9119bafbSConrad Meyer {
1928*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
1929*9119bafbSConrad Meyer     pcg_setseq_16_step_r(rng);
1930*9119bafbSConrad Meyer     return pcg_output_rxs_m_16_8(oldstate);
1931*9119bafbSConrad Meyer }
1932*9119bafbSConrad Meyer 
1933*9119bafbSConrad Meyer inline uint8_t
1934*9119bafbSConrad Meyer pcg_setseq_16_rxs_m_8_boundedrand_r(struct pcg_state_setseq_16* rng,
1935*9119bafbSConrad Meyer                                     uint8_t bound)
1936*9119bafbSConrad Meyer {
1937*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
1938*9119bafbSConrad Meyer     for (;;) {
1939*9119bafbSConrad Meyer         uint8_t r = pcg_setseq_16_rxs_m_8_random_r(rng);
1940*9119bafbSConrad Meyer         if (r >= threshold)
1941*9119bafbSConrad Meyer             return r % bound;
1942*9119bafbSConrad Meyer     }
1943*9119bafbSConrad Meyer }
1944*9119bafbSConrad Meyer 
1945*9119bafbSConrad Meyer inline uint16_t pcg_setseq_32_rxs_m_16_random_r(struct pcg_state_setseq_32* rng)
1946*9119bafbSConrad Meyer {
1947*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
1948*9119bafbSConrad Meyer     pcg_setseq_32_step_r(rng);
1949*9119bafbSConrad Meyer     return pcg_output_rxs_m_32_16(oldstate);
1950*9119bafbSConrad Meyer }
1951*9119bafbSConrad Meyer 
1952*9119bafbSConrad Meyer inline uint16_t
1953*9119bafbSConrad Meyer pcg_setseq_32_rxs_m_16_boundedrand_r(struct pcg_state_setseq_32* rng,
1954*9119bafbSConrad Meyer                                      uint16_t bound)
1955*9119bafbSConrad Meyer {
1956*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
1957*9119bafbSConrad Meyer     for (;;) {
1958*9119bafbSConrad Meyer         uint16_t r = pcg_setseq_32_rxs_m_16_random_r(rng);
1959*9119bafbSConrad Meyer         if (r >= threshold)
1960*9119bafbSConrad Meyer             return r % bound;
1961*9119bafbSConrad Meyer     }
1962*9119bafbSConrad Meyer }
1963*9119bafbSConrad Meyer 
1964*9119bafbSConrad Meyer inline uint32_t pcg_setseq_64_rxs_m_32_random_r(struct pcg_state_setseq_64* rng)
1965*9119bafbSConrad Meyer {
1966*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
1967*9119bafbSConrad Meyer     pcg_setseq_64_step_r(rng);
1968*9119bafbSConrad Meyer     return pcg_output_rxs_m_64_32(oldstate);
1969*9119bafbSConrad Meyer }
1970*9119bafbSConrad Meyer 
1971*9119bafbSConrad Meyer inline uint32_t
1972*9119bafbSConrad Meyer pcg_setseq_64_rxs_m_32_boundedrand_r(struct pcg_state_setseq_64* rng,
1973*9119bafbSConrad Meyer                                      uint32_t bound)
1974*9119bafbSConrad Meyer {
1975*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
1976*9119bafbSConrad Meyer     for (;;) {
1977*9119bafbSConrad Meyer         uint32_t r = pcg_setseq_64_rxs_m_32_random_r(rng);
1978*9119bafbSConrad Meyer         if (r >= threshold)
1979*9119bafbSConrad Meyer             return r % bound;
1980*9119bafbSConrad Meyer     }
1981*9119bafbSConrad Meyer }
1982*9119bafbSConrad Meyer 
1983*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1984*9119bafbSConrad Meyer inline uint64_t
1985*9119bafbSConrad Meyer pcg_setseq_128_rxs_m_64_random_r(struct pcg_state_setseq_128* rng)
1986*9119bafbSConrad Meyer {
1987*9119bafbSConrad Meyer     pcg_setseq_128_step_r(rng);
1988*9119bafbSConrad Meyer     return pcg_output_rxs_m_128_64(rng->state);
1989*9119bafbSConrad Meyer }
1990*9119bafbSConrad Meyer #endif
1991*9119bafbSConrad Meyer 
1992*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
1993*9119bafbSConrad Meyer inline uint64_t
1994*9119bafbSConrad Meyer pcg_setseq_128_rxs_m_64_boundedrand_r(struct pcg_state_setseq_128* rng,
1995*9119bafbSConrad Meyer                                       uint64_t bound)
1996*9119bafbSConrad Meyer {
1997*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
1998*9119bafbSConrad Meyer     for (;;) {
1999*9119bafbSConrad Meyer         uint64_t r = pcg_setseq_128_rxs_m_64_random_r(rng);
2000*9119bafbSConrad Meyer         if (r >= threshold)
2001*9119bafbSConrad Meyer             return r % bound;
2002*9119bafbSConrad Meyer     }
2003*9119bafbSConrad Meyer }
2004*9119bafbSConrad Meyer #endif
2005*9119bafbSConrad Meyer 
2006*9119bafbSConrad Meyer inline uint8_t pcg_mcg_16_rxs_m_8_random_r(struct pcg_state_16* rng)
2007*9119bafbSConrad Meyer {
2008*9119bafbSConrad Meyer     uint16_t oldstate = rng->state;
2009*9119bafbSConrad Meyer     pcg_mcg_16_step_r(rng);
2010*9119bafbSConrad Meyer     return pcg_output_rxs_m_16_8(oldstate);
2011*9119bafbSConrad Meyer }
2012*9119bafbSConrad Meyer 
2013*9119bafbSConrad Meyer inline uint8_t pcg_mcg_16_rxs_m_8_boundedrand_r(struct pcg_state_16* rng,
2014*9119bafbSConrad Meyer                                                 uint8_t bound)
2015*9119bafbSConrad Meyer {
2016*9119bafbSConrad Meyer     uint8_t threshold = ((uint8_t)(-bound)) % bound;
2017*9119bafbSConrad Meyer     for (;;) {
2018*9119bafbSConrad Meyer         uint8_t r = pcg_mcg_16_rxs_m_8_random_r(rng);
2019*9119bafbSConrad Meyer         if (r >= threshold)
2020*9119bafbSConrad Meyer             return r % bound;
2021*9119bafbSConrad Meyer     }
2022*9119bafbSConrad Meyer }
2023*9119bafbSConrad Meyer 
2024*9119bafbSConrad Meyer inline uint16_t pcg_mcg_32_rxs_m_16_random_r(struct pcg_state_32* rng)
2025*9119bafbSConrad Meyer {
2026*9119bafbSConrad Meyer     uint32_t oldstate = rng->state;
2027*9119bafbSConrad Meyer     pcg_mcg_32_step_r(rng);
2028*9119bafbSConrad Meyer     return pcg_output_rxs_m_32_16(oldstate);
2029*9119bafbSConrad Meyer }
2030*9119bafbSConrad Meyer 
2031*9119bafbSConrad Meyer inline uint16_t pcg_mcg_32_rxs_m_16_boundedrand_r(struct pcg_state_32* rng,
2032*9119bafbSConrad Meyer                                                   uint16_t bound)
2033*9119bafbSConrad Meyer {
2034*9119bafbSConrad Meyer     uint16_t threshold = ((uint16_t)(-bound)) % bound;
2035*9119bafbSConrad Meyer     for (;;) {
2036*9119bafbSConrad Meyer         uint16_t r = pcg_mcg_32_rxs_m_16_random_r(rng);
2037*9119bafbSConrad Meyer         if (r >= threshold)
2038*9119bafbSConrad Meyer             return r % bound;
2039*9119bafbSConrad Meyer     }
2040*9119bafbSConrad Meyer }
2041*9119bafbSConrad Meyer 
2042*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_rxs_m_32_random_r(struct pcg_state_64* rng)
2043*9119bafbSConrad Meyer {
2044*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
2045*9119bafbSConrad Meyer     pcg_mcg_64_step_r(rng);
2046*9119bafbSConrad Meyer     return pcg_output_rxs_m_64_32(oldstate);
2047*9119bafbSConrad Meyer }
2048*9119bafbSConrad Meyer 
2049*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_rxs_m_32_boundedrand_r(struct pcg_state_64* rng,
2050*9119bafbSConrad Meyer                                                   uint32_t bound)
2051*9119bafbSConrad Meyer {
2052*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
2053*9119bafbSConrad Meyer     for (;;) {
2054*9119bafbSConrad Meyer         uint32_t r = pcg_mcg_64_rxs_m_32_random_r(rng);
2055*9119bafbSConrad Meyer         if (r >= threshold)
2056*9119bafbSConrad Meyer             return r % bound;
2057*9119bafbSConrad Meyer     }
2058*9119bafbSConrad Meyer }
2059*9119bafbSConrad Meyer 
2060*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2061*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_rxs_m_64_random_r(struct pcg_state_128* rng)
2062*9119bafbSConrad Meyer {
2063*9119bafbSConrad Meyer     pcg_mcg_128_step_r(rng);
2064*9119bafbSConrad Meyer     return pcg_output_rxs_m_128_64(rng->state);
2065*9119bafbSConrad Meyer }
2066*9119bafbSConrad Meyer #endif
2067*9119bafbSConrad Meyer 
2068*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2069*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_rxs_m_64_boundedrand_r(struct pcg_state_128* rng,
2070*9119bafbSConrad Meyer                                                    uint64_t bound)
2071*9119bafbSConrad Meyer {
2072*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
2073*9119bafbSConrad Meyer     for (;;) {
2074*9119bafbSConrad Meyer         uint64_t r = pcg_mcg_128_rxs_m_64_random_r(rng);
2075*9119bafbSConrad Meyer         if (r >= threshold)
2076*9119bafbSConrad Meyer             return r % bound;
2077*9119bafbSConrad Meyer     }
2078*9119bafbSConrad Meyer }
2079*9119bafbSConrad Meyer #endif
2080*9119bafbSConrad Meyer 
2081*9119bafbSConrad Meyer /* Generation functions for XSL RR (only defined for "large" types) */
2082*9119bafbSConrad Meyer 
2083*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_xsl_rr_32_random_r(struct pcg_state_64* rng)
2084*9119bafbSConrad Meyer {
2085*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
2086*9119bafbSConrad Meyer     pcg_oneseq_64_step_r(rng);
2087*9119bafbSConrad Meyer     return pcg_output_xsl_rr_64_32(oldstate);
2088*9119bafbSConrad Meyer }
2089*9119bafbSConrad Meyer 
2090*9119bafbSConrad Meyer inline uint32_t pcg_oneseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng,
2091*9119bafbSConrad Meyer                                                       uint32_t bound)
2092*9119bafbSConrad Meyer {
2093*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
2094*9119bafbSConrad Meyer     for (;;) {
2095*9119bafbSConrad Meyer         uint32_t r = pcg_oneseq_64_xsl_rr_32_random_r(rng);
2096*9119bafbSConrad Meyer         if (r >= threshold)
2097*9119bafbSConrad Meyer             return r % bound;
2098*9119bafbSConrad Meyer     }
2099*9119bafbSConrad Meyer }
2100*9119bafbSConrad Meyer 
2101*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2102*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_128_xsl_rr_64_random_r(struct pcg_state_128* rng)
2103*9119bafbSConrad Meyer {
2104*9119bafbSConrad Meyer     pcg_oneseq_128_step_r(rng);
2105*9119bafbSConrad Meyer     return pcg_output_xsl_rr_128_64(rng->state);
2106*9119bafbSConrad Meyer }
2107*9119bafbSConrad Meyer #endif
2108*9119bafbSConrad Meyer 
2109*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2110*9119bafbSConrad Meyer inline uint64_t
2111*9119bafbSConrad Meyer pcg_oneseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
2112*9119bafbSConrad Meyer                                        uint64_t bound)
2113*9119bafbSConrad Meyer {
2114*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
2115*9119bafbSConrad Meyer     for (;;) {
2116*9119bafbSConrad Meyer         uint64_t r = pcg_oneseq_128_xsl_rr_64_random_r(rng);
2117*9119bafbSConrad Meyer         if (r >= threshold)
2118*9119bafbSConrad Meyer             return r % bound;
2119*9119bafbSConrad Meyer     }
2120*9119bafbSConrad Meyer }
2121*9119bafbSConrad Meyer #endif
2122*9119bafbSConrad Meyer 
2123*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_xsl_rr_32_random_r(struct pcg_state_64* rng)
2124*9119bafbSConrad Meyer {
2125*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
2126*9119bafbSConrad Meyer     pcg_unique_64_step_r(rng);
2127*9119bafbSConrad Meyer     return pcg_output_xsl_rr_64_32(oldstate);
2128*9119bafbSConrad Meyer }
2129*9119bafbSConrad Meyer 
2130*9119bafbSConrad Meyer inline uint32_t pcg_unique_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng,
2131*9119bafbSConrad Meyer                                                       uint32_t bound)
2132*9119bafbSConrad Meyer {
2133*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
2134*9119bafbSConrad Meyer     for (;;) {
2135*9119bafbSConrad Meyer         uint32_t r = pcg_unique_64_xsl_rr_32_random_r(rng);
2136*9119bafbSConrad Meyer         if (r >= threshold)
2137*9119bafbSConrad Meyer             return r % bound;
2138*9119bafbSConrad Meyer     }
2139*9119bafbSConrad Meyer }
2140*9119bafbSConrad Meyer 
2141*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2142*9119bafbSConrad Meyer inline uint64_t pcg_unique_128_xsl_rr_64_random_r(struct pcg_state_128* rng)
2143*9119bafbSConrad Meyer {
2144*9119bafbSConrad Meyer     pcg_unique_128_step_r(rng);
2145*9119bafbSConrad Meyer     return pcg_output_xsl_rr_128_64(rng->state);
2146*9119bafbSConrad Meyer }
2147*9119bafbSConrad Meyer #endif
2148*9119bafbSConrad Meyer 
2149*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2150*9119bafbSConrad Meyer inline uint64_t
2151*9119bafbSConrad Meyer pcg_unique_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
2152*9119bafbSConrad Meyer                                        uint64_t bound)
2153*9119bafbSConrad Meyer {
2154*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
2155*9119bafbSConrad Meyer     for (;;) {
2156*9119bafbSConrad Meyer         uint64_t r = pcg_unique_128_xsl_rr_64_random_r(rng);
2157*9119bafbSConrad Meyer         if (r >= threshold)
2158*9119bafbSConrad Meyer             return r % bound;
2159*9119bafbSConrad Meyer     }
2160*9119bafbSConrad Meyer }
2161*9119bafbSConrad Meyer #endif
2162*9119bafbSConrad Meyer 
2163*9119bafbSConrad Meyer inline uint32_t
2164*9119bafbSConrad Meyer pcg_setseq_64_xsl_rr_32_random_r(struct pcg_state_setseq_64* rng)
2165*9119bafbSConrad Meyer {
2166*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
2167*9119bafbSConrad Meyer     pcg_setseq_64_step_r(rng);
2168*9119bafbSConrad Meyer     return pcg_output_xsl_rr_64_32(oldstate);
2169*9119bafbSConrad Meyer }
2170*9119bafbSConrad Meyer 
2171*9119bafbSConrad Meyer inline uint32_t
2172*9119bafbSConrad Meyer pcg_setseq_64_xsl_rr_32_boundedrand_r(struct pcg_state_setseq_64* rng,
2173*9119bafbSConrad Meyer                                       uint32_t bound)
2174*9119bafbSConrad Meyer {
2175*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
2176*9119bafbSConrad Meyer     for (;;) {
2177*9119bafbSConrad Meyer         uint32_t r = pcg_setseq_64_xsl_rr_32_random_r(rng);
2178*9119bafbSConrad Meyer         if (r >= threshold)
2179*9119bafbSConrad Meyer             return r % bound;
2180*9119bafbSConrad Meyer     }
2181*9119bafbSConrad Meyer }
2182*9119bafbSConrad Meyer 
2183*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2184*9119bafbSConrad Meyer inline uint64_t
2185*9119bafbSConrad Meyer pcg_setseq_128_xsl_rr_64_random_r(struct pcg_state_setseq_128* rng)
2186*9119bafbSConrad Meyer {
2187*9119bafbSConrad Meyer     pcg_setseq_128_step_r(rng);
2188*9119bafbSConrad Meyer     return pcg_output_xsl_rr_128_64(rng->state);
2189*9119bafbSConrad Meyer }
2190*9119bafbSConrad Meyer #endif
2191*9119bafbSConrad Meyer 
2192*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2193*9119bafbSConrad Meyer inline uint64_t
2194*9119bafbSConrad Meyer pcg_setseq_128_xsl_rr_64_boundedrand_r(struct pcg_state_setseq_128* rng,
2195*9119bafbSConrad Meyer                                        uint64_t bound)
2196*9119bafbSConrad Meyer {
2197*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
2198*9119bafbSConrad Meyer     for (;;) {
2199*9119bafbSConrad Meyer         uint64_t r = pcg_setseq_128_xsl_rr_64_random_r(rng);
2200*9119bafbSConrad Meyer         if (r >= threshold)
2201*9119bafbSConrad Meyer             return r % bound;
2202*9119bafbSConrad Meyer     }
2203*9119bafbSConrad Meyer }
2204*9119bafbSConrad Meyer #endif
2205*9119bafbSConrad Meyer 
2206*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_xsl_rr_32_random_r(struct pcg_state_64* rng)
2207*9119bafbSConrad Meyer {
2208*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
2209*9119bafbSConrad Meyer     pcg_mcg_64_step_r(rng);
2210*9119bafbSConrad Meyer     return pcg_output_xsl_rr_64_32(oldstate);
2211*9119bafbSConrad Meyer }
2212*9119bafbSConrad Meyer 
2213*9119bafbSConrad Meyer inline uint32_t pcg_mcg_64_xsl_rr_32_boundedrand_r(struct pcg_state_64* rng,
2214*9119bafbSConrad Meyer                                                    uint32_t bound)
2215*9119bafbSConrad Meyer {
2216*9119bafbSConrad Meyer     uint32_t threshold = -bound % bound;
2217*9119bafbSConrad Meyer     for (;;) {
2218*9119bafbSConrad Meyer         uint32_t r = pcg_mcg_64_xsl_rr_32_random_r(rng);
2219*9119bafbSConrad Meyer         if (r >= threshold)
2220*9119bafbSConrad Meyer             return r % bound;
2221*9119bafbSConrad Meyer     }
2222*9119bafbSConrad Meyer }
2223*9119bafbSConrad Meyer 
2224*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2225*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_xsl_rr_64_random_r(struct pcg_state_128* rng)
2226*9119bafbSConrad Meyer {
2227*9119bafbSConrad Meyer     pcg_mcg_128_step_r(rng);
2228*9119bafbSConrad Meyer     return pcg_output_xsl_rr_128_64(rng->state);
2229*9119bafbSConrad Meyer }
2230*9119bafbSConrad Meyer #endif
2231*9119bafbSConrad Meyer 
2232*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2233*9119bafbSConrad Meyer inline uint64_t pcg_mcg_128_xsl_rr_64_boundedrand_r(struct pcg_state_128* rng,
2234*9119bafbSConrad Meyer                                                     uint64_t bound)
2235*9119bafbSConrad Meyer {
2236*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
2237*9119bafbSConrad Meyer     for (;;) {
2238*9119bafbSConrad Meyer         uint64_t r = pcg_mcg_128_xsl_rr_64_random_r(rng);
2239*9119bafbSConrad Meyer         if (r >= threshold)
2240*9119bafbSConrad Meyer             return r % bound;
2241*9119bafbSConrad Meyer     }
2242*9119bafbSConrad Meyer }
2243*9119bafbSConrad Meyer #endif
2244*9119bafbSConrad Meyer 
2245*9119bafbSConrad Meyer /* Generation functions for XSL RR RR (only defined for "large" types) */
2246*9119bafbSConrad Meyer 
2247*9119bafbSConrad Meyer inline uint64_t pcg_oneseq_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng)
2248*9119bafbSConrad Meyer {
2249*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
2250*9119bafbSConrad Meyer     pcg_oneseq_64_step_r(rng);
2251*9119bafbSConrad Meyer     return pcg_output_xsl_rr_rr_64_64(oldstate);
2252*9119bafbSConrad Meyer }
2253*9119bafbSConrad Meyer 
2254*9119bafbSConrad Meyer inline uint64_t
2255*9119bafbSConrad Meyer pcg_oneseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,
2256*9119bafbSConrad Meyer                                          uint64_t bound)
2257*9119bafbSConrad Meyer {
2258*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
2259*9119bafbSConrad Meyer     for (;;) {
2260*9119bafbSConrad Meyer         uint64_t r = pcg_oneseq_64_xsl_rr_rr_64_random_r(rng);
2261*9119bafbSConrad Meyer         if (r >= threshold)
2262*9119bafbSConrad Meyer             return r % bound;
2263*9119bafbSConrad Meyer     }
2264*9119bafbSConrad Meyer }
2265*9119bafbSConrad Meyer 
2266*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2267*9119bafbSConrad Meyer inline pcg128_t pcg_oneseq_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng)
2268*9119bafbSConrad Meyer {
2269*9119bafbSConrad Meyer     pcg_oneseq_128_step_r(rng);
2270*9119bafbSConrad Meyer     return pcg_output_xsl_rr_rr_128_128(rng->state);
2271*9119bafbSConrad Meyer }
2272*9119bafbSConrad Meyer #endif
2273*9119bafbSConrad Meyer 
2274*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2275*9119bafbSConrad Meyer inline pcg128_t
2276*9119bafbSConrad Meyer pcg_oneseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,
2277*9119bafbSConrad Meyer                                            pcg128_t bound)
2278*9119bafbSConrad Meyer {
2279*9119bafbSConrad Meyer     pcg128_t threshold = -bound % bound;
2280*9119bafbSConrad Meyer     for (;;) {
2281*9119bafbSConrad Meyer         pcg128_t r = pcg_oneseq_128_xsl_rr_rr_128_random_r(rng);
2282*9119bafbSConrad Meyer         if (r >= threshold)
2283*9119bafbSConrad Meyer             return r % bound;
2284*9119bafbSConrad Meyer     }
2285*9119bafbSConrad Meyer }
2286*9119bafbSConrad Meyer #endif
2287*9119bafbSConrad Meyer 
2288*9119bafbSConrad Meyer inline uint64_t pcg_unique_64_xsl_rr_rr_64_random_r(struct pcg_state_64* rng)
2289*9119bafbSConrad Meyer {
2290*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
2291*9119bafbSConrad Meyer     pcg_unique_64_step_r(rng);
2292*9119bafbSConrad Meyer     return pcg_output_xsl_rr_rr_64_64(oldstate);
2293*9119bafbSConrad Meyer }
2294*9119bafbSConrad Meyer 
2295*9119bafbSConrad Meyer inline uint64_t
2296*9119bafbSConrad Meyer pcg_unique_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_64* rng,
2297*9119bafbSConrad Meyer                                          uint64_t bound)
2298*9119bafbSConrad Meyer {
2299*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
2300*9119bafbSConrad Meyer     for (;;) {
2301*9119bafbSConrad Meyer         uint64_t r = pcg_unique_64_xsl_rr_rr_64_random_r(rng);
2302*9119bafbSConrad Meyer         if (r >= threshold)
2303*9119bafbSConrad Meyer             return r % bound;
2304*9119bafbSConrad Meyer     }
2305*9119bafbSConrad Meyer }
2306*9119bafbSConrad Meyer 
2307*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2308*9119bafbSConrad Meyer inline pcg128_t pcg_unique_128_xsl_rr_rr_128_random_r(struct pcg_state_128* rng)
2309*9119bafbSConrad Meyer {
2310*9119bafbSConrad Meyer     pcg_unique_128_step_r(rng);
2311*9119bafbSConrad Meyer     return pcg_output_xsl_rr_rr_128_128(rng->state);
2312*9119bafbSConrad Meyer }
2313*9119bafbSConrad Meyer #endif
2314*9119bafbSConrad Meyer 
2315*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2316*9119bafbSConrad Meyer inline pcg128_t
2317*9119bafbSConrad Meyer pcg_unique_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_128* rng,
2318*9119bafbSConrad Meyer                                            pcg128_t bound)
2319*9119bafbSConrad Meyer {
2320*9119bafbSConrad Meyer     pcg128_t threshold = -bound % bound;
2321*9119bafbSConrad Meyer     for (;;) {
2322*9119bafbSConrad Meyer         pcg128_t r = pcg_unique_128_xsl_rr_rr_128_random_r(rng);
2323*9119bafbSConrad Meyer         if (r >= threshold)
2324*9119bafbSConrad Meyer             return r % bound;
2325*9119bafbSConrad Meyer     }
2326*9119bafbSConrad Meyer }
2327*9119bafbSConrad Meyer #endif
2328*9119bafbSConrad Meyer 
2329*9119bafbSConrad Meyer inline uint64_t
2330*9119bafbSConrad Meyer pcg_setseq_64_xsl_rr_rr_64_random_r(struct pcg_state_setseq_64* rng)
2331*9119bafbSConrad Meyer {
2332*9119bafbSConrad Meyer     uint64_t oldstate = rng->state;
2333*9119bafbSConrad Meyer     pcg_setseq_64_step_r(rng);
2334*9119bafbSConrad Meyer     return pcg_output_xsl_rr_rr_64_64(oldstate);
2335*9119bafbSConrad Meyer }
2336*9119bafbSConrad Meyer 
2337*9119bafbSConrad Meyer inline uint64_t
2338*9119bafbSConrad Meyer pcg_setseq_64_xsl_rr_rr_64_boundedrand_r(struct pcg_state_setseq_64* rng,
2339*9119bafbSConrad Meyer                                          uint64_t bound)
2340*9119bafbSConrad Meyer {
2341*9119bafbSConrad Meyer     uint64_t threshold = -bound % bound;
2342*9119bafbSConrad Meyer     for (;;) {
2343*9119bafbSConrad Meyer         uint64_t r = pcg_setseq_64_xsl_rr_rr_64_random_r(rng);
2344*9119bafbSConrad Meyer         if (r >= threshold)
2345*9119bafbSConrad Meyer             return r % bound;
2346*9119bafbSConrad Meyer     }
2347*9119bafbSConrad Meyer }
2348*9119bafbSConrad Meyer 
2349*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2350*9119bafbSConrad Meyer inline pcg128_t
2351*9119bafbSConrad Meyer pcg_setseq_128_xsl_rr_rr_128_random_r(struct pcg_state_setseq_128* rng)
2352*9119bafbSConrad Meyer {
2353*9119bafbSConrad Meyer     pcg_setseq_128_step_r(rng);
2354*9119bafbSConrad Meyer     return pcg_output_xsl_rr_rr_128_128(rng->state);
2355*9119bafbSConrad Meyer }
2356*9119bafbSConrad Meyer #endif
2357*9119bafbSConrad Meyer 
2358*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2359*9119bafbSConrad Meyer inline pcg128_t
2360*9119bafbSConrad Meyer pcg_setseq_128_xsl_rr_rr_128_boundedrand_r(struct pcg_state_setseq_128* rng,
2361*9119bafbSConrad Meyer                                            pcg128_t bound)
2362*9119bafbSConrad Meyer {
2363*9119bafbSConrad Meyer     pcg128_t threshold = -bound % bound;
2364*9119bafbSConrad Meyer     for (;;) {
2365*9119bafbSConrad Meyer         pcg128_t r = pcg_setseq_128_xsl_rr_rr_128_random_r(rng);
2366*9119bafbSConrad Meyer         if (r >= threshold)
2367*9119bafbSConrad Meyer             return r % bound;
2368*9119bafbSConrad Meyer     }
2369*9119bafbSConrad Meyer }
2370*9119bafbSConrad Meyer #endif
2371*9119bafbSConrad Meyer 
2372*9119bafbSConrad Meyer /*** Typedefs */
2373*9119bafbSConrad Meyer typedef struct pcg_state_setseq_64      pcg32_random_t;
2374*9119bafbSConrad Meyer typedef struct pcg_state_64             pcg32s_random_t;
2375*9119bafbSConrad Meyer typedef struct pcg_state_64             pcg32u_random_t;
2376*9119bafbSConrad Meyer typedef struct pcg_state_64             pcg32f_random_t;
2377*9119bafbSConrad Meyer /*** random_r */
2378*9119bafbSConrad Meyer #define pcg32_random_r                  pcg_setseq_64_xsh_rr_32_random_r
2379*9119bafbSConrad Meyer #define pcg32s_random_r                 pcg_oneseq_64_xsh_rr_32_random_r
2380*9119bafbSConrad Meyer #define pcg32u_random_r                 pcg_unique_64_xsh_rr_32_random_r
2381*9119bafbSConrad Meyer #define pcg32f_random_r                 pcg_mcg_64_xsh_rs_32_random_r
2382*9119bafbSConrad Meyer /*** boundedrand_r */
2383*9119bafbSConrad Meyer #define pcg32_boundedrand_r             pcg_setseq_64_xsh_rr_32_boundedrand_r
2384*9119bafbSConrad Meyer #define pcg32s_boundedrand_r            pcg_oneseq_64_xsh_rr_32_boundedrand_r
2385*9119bafbSConrad Meyer #define pcg32u_boundedrand_r            pcg_unique_64_xsh_rr_32_boundedrand_r
2386*9119bafbSConrad Meyer #define pcg32f_boundedrand_r            pcg_mcg_64_xsh_rs_32_boundedrand_r
2387*9119bafbSConrad Meyer /*** srandom_r */
2388*9119bafbSConrad Meyer #define pcg32_srandom_r                 pcg_setseq_64_srandom_r
2389*9119bafbSConrad Meyer #define pcg32s_srandom_r                pcg_oneseq_64_srandom_r
2390*9119bafbSConrad Meyer #define pcg32u_srandom_r                pcg_unique_64_srandom_r
2391*9119bafbSConrad Meyer #define pcg32f_srandom_r                pcg_mcg_64_srandom_r
2392*9119bafbSConrad Meyer /*** advance_r */
2393*9119bafbSConrad Meyer #define pcg32_advance_r                 pcg_setseq_64_advance_r
2394*9119bafbSConrad Meyer #define pcg32s_advance_r                pcg_oneseq_64_advance_r
2395*9119bafbSConrad Meyer #define pcg32u_advance_r                pcg_unique_64_advance_r
2396*9119bafbSConrad Meyer #define pcg32f_advance_r                pcg_mcg_64_advance_r
2397*9119bafbSConrad Meyer 
2398*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2399*9119bafbSConrad Meyer /*** Typedefs */
2400*9119bafbSConrad Meyer typedef struct pcg_state_setseq_128     pcg64_random_t;
2401*9119bafbSConrad Meyer typedef struct pcg_state_128            pcg64s_random_t;
2402*9119bafbSConrad Meyer typedef struct pcg_state_128            pcg64u_random_t;
2403*9119bafbSConrad Meyer typedef struct pcg_state_128            pcg64f_random_t;
2404*9119bafbSConrad Meyer /*** random_r */
2405*9119bafbSConrad Meyer #define pcg64_random_r                  pcg_setseq_128_xsl_rr_64_random_r
2406*9119bafbSConrad Meyer #define pcg64s_random_r                 pcg_oneseq_128_xsl_rr_64_random_r
2407*9119bafbSConrad Meyer #define pcg64u_random_r                 pcg_unique_128_xsl_rr_64_random_r
2408*9119bafbSConrad Meyer #define pcg64f_random_r                 pcg_mcg_128_xsl_rr_64_random_r
2409*9119bafbSConrad Meyer /*** boundedrand_r */
2410*9119bafbSConrad Meyer #define pcg64_boundedrand_r             pcg_setseq_128_xsl_rr_64_boundedrand_r
2411*9119bafbSConrad Meyer #define pcg64s_boundedrand_r            pcg_oneseq_128_xsl_rr_64_boundedrand_r
2412*9119bafbSConrad Meyer #define pcg64u_boundedrand_r            pcg_unique_128_xsl_rr_64_boundedrand_r
2413*9119bafbSConrad Meyer #define pcg64f_boundedrand_r            pcg_mcg_128_xsl_rr_64_boundedrand_r
2414*9119bafbSConrad Meyer /*** srandom_r */
2415*9119bafbSConrad Meyer #define pcg64_srandom_r                 pcg_setseq_128_srandom_r
2416*9119bafbSConrad Meyer #define pcg64s_srandom_r                pcg_oneseq_128_srandom_r
2417*9119bafbSConrad Meyer #define pcg64u_srandom_r                pcg_unique_128_srandom_r
2418*9119bafbSConrad Meyer #define pcg64f_srandom_r                pcg_mcg_128_srandom_r
2419*9119bafbSConrad Meyer /*** advance_r */
2420*9119bafbSConrad Meyer #define pcg64_advance_r                 pcg_setseq_128_advance_r
2421*9119bafbSConrad Meyer #define pcg64s_advance_r                pcg_oneseq_128_advance_r
2422*9119bafbSConrad Meyer #define pcg64u_advance_r                pcg_unique_128_advance_r
2423*9119bafbSConrad Meyer #define pcg64f_advance_r                pcg_mcg_128_advance_r
2424*9119bafbSConrad Meyer #endif
2425*9119bafbSConrad Meyer 
2426*9119bafbSConrad Meyer /*** Typedefs */
2427*9119bafbSConrad Meyer typedef struct pcg_state_8              pcg8si_random_t;
2428*9119bafbSConrad Meyer typedef struct pcg_state_16             pcg16si_random_t;
2429*9119bafbSConrad Meyer typedef struct pcg_state_32             pcg32si_random_t;
2430*9119bafbSConrad Meyer typedef struct pcg_state_64             pcg64si_random_t;
2431*9119bafbSConrad Meyer /*** random_r */
2432*9119bafbSConrad Meyer #define pcg8si_random_r                 pcg_oneseq_8_rxs_m_xs_8_random_r
2433*9119bafbSConrad Meyer #define pcg16si_random_r                pcg_oneseq_16_rxs_m_xs_16_random_r
2434*9119bafbSConrad Meyer #define pcg32si_random_r                pcg_oneseq_32_rxs_m_xs_32_random_r
2435*9119bafbSConrad Meyer #define pcg64si_random_r                pcg_oneseq_64_rxs_m_xs_64_random_r
2436*9119bafbSConrad Meyer /*** boundedrand_r */
2437*9119bafbSConrad Meyer #define pcg8si_boundedrand_r            pcg_oneseq_8_rxs_m_xs_8_boundedrand_r
2438*9119bafbSConrad Meyer #define pcg16si_boundedrand_r           pcg_oneseq_16_rxs_m_xs_16_boundedrand_r
2439*9119bafbSConrad Meyer #define pcg32si_boundedrand_r           pcg_oneseq_32_rxs_m_xs_32_boundedrand_r
2440*9119bafbSConrad Meyer #define pcg64si_boundedrand_r           pcg_oneseq_64_rxs_m_xs_64_boundedrand_r
2441*9119bafbSConrad Meyer /*** srandom_r */
2442*9119bafbSConrad Meyer #define pcg8si_srandom_r                pcg_oneseq_8_srandom_r
2443*9119bafbSConrad Meyer #define pcg16si_srandom_r               pcg_oneseq_16_srandom_r
2444*9119bafbSConrad Meyer #define pcg32si_srandom_r               pcg_oneseq_32_srandom_r
2445*9119bafbSConrad Meyer #define pcg64si_srandom_r               pcg_oneseq_64_srandom_r
2446*9119bafbSConrad Meyer /*** advance_r */
2447*9119bafbSConrad Meyer #define pcg8si_advance_r                pcg_oneseq_8_advance_r
2448*9119bafbSConrad Meyer #define pcg16si_advance_r               pcg_oneseq_16_advance_r
2449*9119bafbSConrad Meyer #define pcg32si_advance_r               pcg_oneseq_32_advance_r
2450*9119bafbSConrad Meyer #define pcg64si_advance_r               pcg_oneseq_64_advance_r
2451*9119bafbSConrad Meyer 
2452*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2453*9119bafbSConrad Meyer typedef struct pcg_state_128        pcg128si_random_t;
2454*9119bafbSConrad Meyer #define pcg128si_random_r           pcg_oneseq_128_rxs_m_xs_128_random_r
2455*9119bafbSConrad Meyer #define pcg128si_boundedrand_r      pcg_oneseq_128_rxs_m_xs_128_boundedrand_r
2456*9119bafbSConrad Meyer #define pcg128si_srandom_r          pcg_oneseq_128_srandom_r
2457*9119bafbSConrad Meyer #define pcg128si_advance_r          pcg_oneseq_128_advance_r
2458*9119bafbSConrad Meyer #endif
2459*9119bafbSConrad Meyer 
2460*9119bafbSConrad Meyer /*** Typedefs */
2461*9119bafbSConrad Meyer typedef struct pcg_state_setseq_8       pcg8i_random_t;
2462*9119bafbSConrad Meyer typedef struct pcg_state_setseq_16      pcg16i_random_t;
2463*9119bafbSConrad Meyer typedef struct pcg_state_setseq_32      pcg32i_random_t;
2464*9119bafbSConrad Meyer typedef struct pcg_state_setseq_64      pcg64i_random_t;
2465*9119bafbSConrad Meyer /*** random_r */
2466*9119bafbSConrad Meyer #define pcg8i_random_r                  pcg_setseq_8_rxs_m_xs_8_random_r
2467*9119bafbSConrad Meyer #define pcg16i_random_r                 pcg_setseq_16_rxs_m_xs_16_random_r
2468*9119bafbSConrad Meyer #define pcg32i_random_r                 pcg_setseq_32_rxs_m_xs_32_random_r
2469*9119bafbSConrad Meyer #define pcg64i_random_r                 pcg_setseq_64_rxs_m_xs_64_random_r
2470*9119bafbSConrad Meyer /*** boundedrand_r */
2471*9119bafbSConrad Meyer #define pcg8i_boundedrand_r             pcg_setseq_8_rxs_m_xs_8_boundedrand_r
2472*9119bafbSConrad Meyer #define pcg16i_boundedrand_r            pcg_setseq_16_rxs_m_xs_16_boundedrand_r
2473*9119bafbSConrad Meyer #define pcg32i_boundedrand_r            pcg_setseq_32_rxs_m_xs_32_boundedrand_r
2474*9119bafbSConrad Meyer #define pcg64i_boundedrand_r            pcg_setseq_64_rxs_m_xs_64_boundedrand_r
2475*9119bafbSConrad Meyer /*** srandom_r */
2476*9119bafbSConrad Meyer #define pcg8i_srandom_r                 pcg_setseq_8_srandom_r
2477*9119bafbSConrad Meyer #define pcg16i_srandom_r                pcg_setseq_16_srandom_r
2478*9119bafbSConrad Meyer #define pcg32i_srandom_r                pcg_setseq_32_srandom_r
2479*9119bafbSConrad Meyer #define pcg64i_srandom_r                pcg_setseq_64_srandom_r
2480*9119bafbSConrad Meyer /*** advance_r */
2481*9119bafbSConrad Meyer #define pcg8i_advance_r                 pcg_setseq_8_advance_r
2482*9119bafbSConrad Meyer #define pcg16i_advance_r                pcg_setseq_16_advance_r
2483*9119bafbSConrad Meyer #define pcg32i_advance_r                pcg_setseq_32_advance_r
2484*9119bafbSConrad Meyer #define pcg64i_advance_r                pcg_setseq_64_advance_r
2485*9119bafbSConrad Meyer 
2486*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2487*9119bafbSConrad Meyer typedef struct pcg_state_setseq_128   pcg128i_random_t;
2488*9119bafbSConrad Meyer #define pcg128i_random_r              pcg_setseq_128_rxs_m_xs_128_random_r
2489*9119bafbSConrad Meyer #define pcg128i_boundedrand_r         pcg_setseq_128_rxs_m_xs_128_boundedrand_r
2490*9119bafbSConrad Meyer #define pcg128i_srandom_r             pcg_setseq_128_srandom_r
2491*9119bafbSConrad Meyer #define pcg128i_advance_r             pcg_setseq_128_advance_r
2492*9119bafbSConrad Meyer #endif
2493*9119bafbSConrad Meyer 
2494*9119bafbSConrad Meyer extern uint32_t pcg32_random(void);
2495*9119bafbSConrad Meyer extern uint32_t pcg32_boundedrand(uint32_t bound);
2496*9119bafbSConrad Meyer extern void     pcg32_srandom(uint64_t seed, uint64_t seq);
2497*9119bafbSConrad Meyer extern void     pcg32_advance(uint64_t delta);
2498*9119bafbSConrad Meyer 
2499*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2500*9119bafbSConrad Meyer extern uint64_t pcg64_random(void);
2501*9119bafbSConrad Meyer extern uint64_t pcg64_boundedrand(uint64_t bound);
2502*9119bafbSConrad Meyer extern void     pcg64_srandom(pcg128_t seed, pcg128_t seq);
2503*9119bafbSConrad Meyer extern void     pcg64_advance(pcg128_t delta);
2504*9119bafbSConrad Meyer #endif
2505*9119bafbSConrad Meyer 
2506*9119bafbSConrad Meyer /*
2507*9119bafbSConrad Meyer  * Static initialization constants (if you can't call srandom for some
2508*9119bafbSConrad Meyer  * bizarre reason).
2509*9119bafbSConrad Meyer  */
2510*9119bafbSConrad Meyer 
2511*9119bafbSConrad Meyer #define PCG32_INITIALIZER       PCG_STATE_SETSEQ_64_INITIALIZER
2512*9119bafbSConrad Meyer #define PCG32U_INITIALIZER      PCG_STATE_UNIQUE_64_INITIALIZER
2513*9119bafbSConrad Meyer #define PCG32S_INITIALIZER      PCG_STATE_ONESEQ_64_INITIALIZER
2514*9119bafbSConrad Meyer #define PCG32F_INITIALIZER      PCG_STATE_MCG_64_INITIALIZER
2515*9119bafbSConrad Meyer 
2516*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2517*9119bafbSConrad Meyer #define PCG64_INITIALIZER       PCG_STATE_SETSEQ_128_INITIALIZER
2518*9119bafbSConrad Meyer #define PCG64U_INITIALIZER      PCG_STATE_UNIQUE_128_INITIALIZER
2519*9119bafbSConrad Meyer #define PCG64S_INITIALIZER      PCG_STATE_ONESEQ_128_INITIALIZER
2520*9119bafbSConrad Meyer #define PCG64F_INITIALIZER      PCG_STATE_MCG_128_INITIALIZER
2521*9119bafbSConrad Meyer #endif
2522*9119bafbSConrad Meyer 
2523*9119bafbSConrad Meyer #define PCG8SI_INITIALIZER      PCG_STATE_ONESEQ_8_INITIALIZER
2524*9119bafbSConrad Meyer #define PCG16SI_INITIALIZER     PCG_STATE_ONESEQ_16_INITIALIZER
2525*9119bafbSConrad Meyer #define PCG32SI_INITIALIZER     PCG_STATE_ONESEQ_32_INITIALIZER
2526*9119bafbSConrad Meyer #define PCG64SI_INITIALIZER     PCG_STATE_ONESEQ_64_INITIALIZER
2527*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2528*9119bafbSConrad Meyer #define PCG128SI_INITIALIZER    PCG_STATE_ONESEQ_128_INITIALIZER
2529*9119bafbSConrad Meyer #endif
2530*9119bafbSConrad Meyer 
2531*9119bafbSConrad Meyer #define PCG8I_INITIALIZER       PCG_STATE_SETSEQ_8_INITIALIZER
2532*9119bafbSConrad Meyer #define PCG16I_INITIALIZER      PCG_STATE_SETSEQ_16_INITIALIZER
2533*9119bafbSConrad Meyer #define PCG32I_INITIALIZER      PCG_STATE_SETSEQ_32_INITIALIZER
2534*9119bafbSConrad Meyer #define PCG64I_INITIALIZER      PCG_STATE_SETSEQ_64_INITIALIZER
2535*9119bafbSConrad Meyer #if PCG_HAS_128BIT_OPS
2536*9119bafbSConrad Meyer #define PCG128I_INITIALIZER     PCG_STATE_SETSEQ_128_INITIALIZER
2537*9119bafbSConrad Meyer #endif
2538*9119bafbSConrad Meyer 
2539*9119bafbSConrad Meyer #if __cplusplus
2540*9119bafbSConrad Meyer }
2541*9119bafbSConrad Meyer #endif
2542*9119bafbSConrad Meyer 
2543*9119bafbSConrad Meyer #endif /* PCG_VARIANTS_H_INCLUDED */
2544*9119bafbSConrad Meyer 
2545