Skip to content

random: Split the uint128 implementation into its own header #13132

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ext/random/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ PHP_NEW_EXTENSION(random,
gammasection.c \
randomizer.c,
no,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
PHP_INSTALL_HEADERS([ext/random], [php_random.h])
PHP_INSTALL_HEADERS([ext/random], [php_random.h php_random_uint128.h])
2 changes: 1 addition & 1 deletion ext/random/config.w32
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
EXTENSION("random", "random.c", false /* never shared */, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
PHP_RANDOM="yes";
ADD_SOURCES(configure_module_dirname, "csprng.c engine_combinedlcg.c engine_mt19937.c engine_pcgoneseq128xslrr64.c engine_xoshiro256starstar.c engine_secure.c engine_user.c gammasection.c randomizer.c", "random");
PHP_INSTALL_HEADERS("ext/random", "php_random.h");
PHP_INSTALL_HEADERS("ext/random", "php_random.h php_random_uint128.h");
1 change: 1 addition & 0 deletions ext/random/engine_pcgoneseq128xslrr64.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "php.h"
#include "php_random.h"
#include "php_random_uint128.h"

#include "Zend/zend_exceptions.h"

Expand Down
104 changes: 1 addition & 103 deletions ext/random/php_random.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
# define PHP_RANDOM_H

# include "php.h"
# include "php_random_uint128.h"

PHPAPI double php_combined_lcg(void);

Expand Down Expand Up @@ -64,109 +65,6 @@ PHPAPI zend_long php_mt_rand_common(zend_long min, zend_long max);
PHPAPI void php_srand(zend_long seed);
PHPAPI zend_long php_rand(void);

# if !defined(__SIZEOF_INT128__) || defined(PHP_RANDOM_FORCE_EMULATE_128)
typedef struct _php_random_uint128_t {
uint64_t hi;
uint64_t lo;
} php_random_uint128_t;

static inline uint64_t php_random_uint128_hi(php_random_uint128_t num)
{
return num.hi;
}

static inline uint64_t php_random_uint128_lo(php_random_uint128_t num)
{
return num.lo;
}

static inline php_random_uint128_t php_random_uint128_constant(uint64_t hi, uint64_t lo)
{
php_random_uint128_t r;

r.hi = hi;
r.lo = lo;

return r;
}

static inline php_random_uint128_t php_random_uint128_add(php_random_uint128_t num1, php_random_uint128_t num2)
{
php_random_uint128_t r;

r.lo = (num1.lo + num2.lo);
r.hi = (num1.hi + num2.hi + (r.lo < num1.lo));

return r;
}

static inline php_random_uint128_t php_random_uint128_multiply(php_random_uint128_t num1, php_random_uint128_t num2)
{
php_random_uint128_t r;
const uint64_t
x0 = num1.lo & 0xffffffffULL,
x1 = num1.lo >> 32,
y0 = num2.lo & 0xffffffffULL,
y1 = num2.lo >> 32,
z0 = (((x1 * y0) + (x0 * y0 >> 32)) & 0xffffffffULL) + x0 * y1;

r.hi = num1.hi * num2.lo + num1.lo * num2.hi;
r.lo = num1.lo * num2.lo;
r.hi += x1 * y1 + ((x1 * y0 + (x0 * y0 >> 32)) >> 32) + (z0 >> 32);

return r;
}

static inline uint64_t php_random_pcgoneseq128xslrr64_rotr64(php_random_uint128_t num)
{
const uint64_t
v = (num.hi ^ num.lo),
s = num.hi >> 58U;

return (v >> s) | (v << ((-s) & 63));
}
# else
typedef __uint128_t php_random_uint128_t;

static inline uint64_t php_random_uint128_hi(php_random_uint128_t num)
{
return (uint64_t) (num >> 64);
}

static inline uint64_t php_random_uint128_lo(php_random_uint128_t num)
{
return (uint64_t) num;
}

static inline php_random_uint128_t php_random_uint128_constant(uint64_t hi, uint64_t lo)
{
php_random_uint128_t r;

r = ((php_random_uint128_t) hi << 64) + lo;

return r;
}

static inline php_random_uint128_t php_random_uint128_add(php_random_uint128_t num1, php_random_uint128_t num2)
{
return num1 + num2;
}

static inline php_random_uint128_t php_random_uint128_multiply(php_random_uint128_t num1, php_random_uint128_t num2)
{
return num1 * num2;
}

static inline uint64_t php_random_pcgoneseq128xslrr64_rotr64(php_random_uint128_t num)
{
const uint64_t
v = ((uint64_t) (num >> 64U)) ^ (uint64_t) num,
s = num >> 122U;

return (v >> s) | (v << ((-s) & 63));
}
# endif

PHPAPI zend_result php_random_bytes(void *bytes, size_t size, bool should_throw);
PHPAPI zend_result php_random_int(zend_long min, zend_long max, zend_long *result, bool should_throw);

Expand Down
128 changes: 128 additions & 0 deletions ext/random/php_random_uint128.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| [email protected] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Tim Düsterhus <[email protected]> |
| Go Kudo <[email protected]> |
| |
| Based on code from: Melissa O'Neill <[email protected]> |
+----------------------------------------------------------------------+
*/

#ifndef PHP_RANDOM_UINT128_H
# define PHP_RANDOM_UINT128_H

# include <stdint.h>

# if !defined(__SIZEOF_INT128__) || defined(PHP_RANDOM_FORCE_EMULATE_128)
typedef struct _php_random_uint128_t {
uint64_t hi;
uint64_t lo;
} php_random_uint128_t;

static inline uint64_t php_random_uint128_hi(php_random_uint128_t num)
{
return num.hi;
}

static inline uint64_t php_random_uint128_lo(php_random_uint128_t num)
{
return num.lo;
}

static inline php_random_uint128_t php_random_uint128_constant(uint64_t hi, uint64_t lo)
{
php_random_uint128_t r;

r.hi = hi;
r.lo = lo;

return r;
}

static inline php_random_uint128_t php_random_uint128_add(php_random_uint128_t num1, php_random_uint128_t num2)
{
php_random_uint128_t r;

r.lo = (num1.lo + num2.lo);
r.hi = (num1.hi + num2.hi + (r.lo < num1.lo));

return r;
}

static inline php_random_uint128_t php_random_uint128_multiply(php_random_uint128_t num1, php_random_uint128_t num2)
{
php_random_uint128_t r;
const uint64_t
x0 = num1.lo & 0xffffffffULL,
x1 = num1.lo >> 32,
y0 = num2.lo & 0xffffffffULL,
y1 = num2.lo >> 32,
z0 = (((x1 * y0) + (x0 * y0 >> 32)) & 0xffffffffULL) + x0 * y1;

r.hi = num1.hi * num2.lo + num1.lo * num2.hi;
r.lo = num1.lo * num2.lo;
r.hi += x1 * y1 + ((x1 * y0 + (x0 * y0 >> 32)) >> 32) + (z0 >> 32);

return r;
}

static inline uint64_t php_random_pcgoneseq128xslrr64_rotr64(php_random_uint128_t num)
{
const uint64_t
v = (num.hi ^ num.lo),
s = num.hi >> 58U;

return (v >> s) | (v << ((-s) & 63));
}
# else
typedef __uint128_t php_random_uint128_t;

static inline uint64_t php_random_uint128_hi(php_random_uint128_t num)
{
return (uint64_t) (num >> 64);
}

static inline uint64_t php_random_uint128_lo(php_random_uint128_t num)
{
return (uint64_t) num;
}

static inline php_random_uint128_t php_random_uint128_constant(uint64_t hi, uint64_t lo)
{
php_random_uint128_t r;

r = ((php_random_uint128_t) hi << 64) + lo;

return r;
}

static inline php_random_uint128_t php_random_uint128_add(php_random_uint128_t num1, php_random_uint128_t num2)
{
return num1 + num2;
}

static inline php_random_uint128_t php_random_uint128_multiply(php_random_uint128_t num1, php_random_uint128_t num2)
{
return num1 * num2;
}

static inline uint64_t php_random_pcgoneseq128xslrr64_rotr64(php_random_uint128_t num)
{
const uint64_t
v = ((uint64_t) (num >> 64U)) ^ (uint64_t) num,
s = num >> 122U;

return (v >> s) | (v << ((-s) & 63));
}
# endif

#endif /* PHP_RANDOM_UINT128_H */