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,6 +189,7 @@ 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 ;
137195extern PHPAPI zend_class_entry * random_ce_Random_Engine_XorShift128Plus ;
@@ -140,6 +198,7 @@ extern PHPAPI zend_class_entry *random_ce_Random_Randomizer;
140198
141199extern const php_random_engine_algo php_random_engine_algo_combinedlcg ;
142200extern const php_random_engine_algo php_random_engine_algo_mersennetwister ;
201+ extern const php_random_engine_algo php_random_engine_algo_pcg64 ;
143202extern const php_random_engine_algo php_random_engine_algo_secure ;
144203extern const php_random_engine_algo php_random_engine_algo_user ;
145204extern const php_random_engine_algo php_random_engine_algo_xorshift128plus ;
@@ -163,6 +222,11 @@ typedef struct _php_random_engine_state_mersennetwister {
163222 bool seeded ;
164223} php_random_engine_state_mersennetwister ;
165224
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+
166230typedef struct _php_random_engine_state_user {
167231 zend_object * object ;
168232 zend_function * generate_method ;
0 commit comments