2424 | Shawn Cokus <[email protected] > | 2525 | David Blackman |
2626 | Sebastiano Vigna <[email protected] > | 27+ | Melissa O'Neill <[email protected] > | 2728 +----------------------------------------------------------------------+
2829*/
2930#ifndef PHP_RANDOM_H
8586# define php_random_int_silent (min , max , result ) \
8687 php_random_int((min), (max), (result), 0)
8788
89+ # if !defined(__SIZEOF_INT128__ ) || defined(FORCE_EMULATE_128 )
90+ # define RANDOM_PCG64_EMULATED
91+ typedef struct _random_uint128_t {
92+ uint64_t hi ;
93+ uint64_t lo ;
94+ } random_uint128_t ;
95+ # define UINT128_HI64 (value ) value.hi;
96+ # define UINT128_LO64 (value ) value.lo;
97+ # define UINT128_CON (x , y , result ) \
98+ do { \
99+ result.hi = x; \
100+ result.lo = y; \
101+ } while (0);
102+ # define UINT128_ADD (x , y , result ) \
103+ do { \
104+ const uint64_t _lo = (x.lo + y.lo), _hi = (x.hi + y.hi + (_lo < x.lo)); \
105+ result.hi = _hi; \
106+ result.lo = _lo; \
107+ } while (0);
108+ # define UINT128_MUL (x , y , result ) \
109+ do { \
110+ const uint64_t \
111+ _x0 = x.lo & 0xffffffffULL, \
112+ _x1 = x.lo >> 32, \
113+ _y0 = y.lo & 0xffffffffULL, \
114+ _y1 = y.lo >> 32, \
115+ _z0 = ((_x1 * _y0 + (_x0 * _y0 >> 32)) & 0xffffffffULL) + _x0 * _y1; \
116+ result.hi = x.hi * y.lo + x.lo * y.hi; \
117+ result.lo = x.lo * y.lo; \
118+ result.hi += _x1 * _y1 + ((_x1 * _y0 + (_x0 * _y0 >> 32)) >> 32) + (_z0 >> 32); \
119+ } while (0);
120+ # define PCG64_ROTL1OR1 (x , result ) \
121+ do { \
122+ result.hi = x.hi << 1U | x.lo >> 63U; \
123+ result.lo = x.lo << 1U | 1U; \
124+ } while (0);
125+ # define PCG64_ROTR64 (x , result ) \
126+ do { \
127+ const uint64_t _v = (x.hi ^ x.lo), _s = x.hi >> 58U; \
128+ result = (_v >> _s) | (_v << ((-_s) & 63)); \
129+ } while (0);
130+ # else
131+ typedef __uint128_t random_uint128_t ;
132+ # define UINT128_HI64 (value ) (uint64_t) (value >> 64);
133+ # define UINT128_LO64 (value ) (uint64_t) value;
134+ # define UINT128_CON (x , y , result ) result = (((random_uint128_t) x << 64) + y);
135+ # define UINT128_ADD (x , y , result ) result = x + y;
136+ # define UINT128_MUL (x , y , result ) result = x * y;
137+ # define PCG64_ROTL1OR1 (x , result ) result = (x << 1U) | 1U;
138+ # define PCG64_ROTR64 (x , result ) \
139+ do { \
140+ uint64_t _v = ((uint64_t) (x >> 64U)) ^ (uint64_t) x, _s = x >> 122U; \
141+ result = (_v >> _s) | (_v << ((-_s) & 63)); \
142+ } while (0);
143+ # endif
144+
88145# define RANDOM_ENGINE_GENERATE (algo , state , result , generated_size , rng_unsafe ) \
89146 do { \
90147 result = algo->generate(state, rng_unsafe); \
@@ -132,15 +189,19 @@ extern PHPAPI zend_class_entry *random_ce_Random_SeedableEngine;
132189extern PHPAPI zend_class_entry * random_ce_Random_SerializableEngine ;
133190
134191extern PHPAPI zend_class_entry * random_ce_Random_Engine_CombinedLCG ;
192+ extern PHPAPI zend_class_entry * random_ce_Random_Engine_PCG64 ;
135193extern PHPAPI zend_class_entry * random_ce_Random_Engine_MersenneTwister ;
136194extern PHPAPI zend_class_entry * random_ce_Random_Engine_Secure ;
195+ extern PHPAPI zend_class_entry * random_ce_Random_Engine_XorShift128Plus ;
137196extern PHPAPI zend_class_entry * random_ce_Random_Engine_Xoshiro256StarStar ;
138197extern PHPAPI zend_class_entry * random_ce_Random_Randomizer ;
139198
140199extern const php_random_engine_algo php_random_engine_algo_combinedlcg ;
141200extern const php_random_engine_algo php_random_engine_algo_mersennetwister ;
201+ extern const php_random_engine_algo php_random_engine_algo_pcg64 ;
142202extern const php_random_engine_algo php_random_engine_algo_secure ;
143203extern const php_random_engine_algo php_random_engine_algo_user ;
204+ extern const php_random_engine_algo php_random_engine_algo_xorshift128plus ;
144205extern const php_random_engine_algo php_random_engine_algo_xoshiro256starstar ;
145206
146207typedef struct _php_random_engine {
@@ -161,12 +222,21 @@ typedef struct _php_random_engine_state_mersennetwister {
161222 bool seeded ;
162223} php_random_engine_state_mersennetwister ;
163224
225+ typedef struct _php_random_engine_state_pcg64 {
226+ random_uint128_t s ;
227+ random_uint128_t inc ;
228+ } php_random_engine_state_pcg64 ;
229+
164230typedef struct _php_random_engine_state_user {
165231 zend_object * object ;
166232 zend_function * generate_method ;
167233 size_t last_generate_size ;
168234} php_random_engine_state_user ;
169235
236+ typedef struct _php_random_engine_state_xorshift128plus {
237+ uint64_t s [2 ];
238+ } php_random_engine_state_xorshift128plus ;
239+
170240typedef struct _php_random_engine_state_xoshiro256starstar {
171241 uint64_t s [4 ];
172242} php_random_engine_state_xoshiro256starstar ;
0 commit comments