Skip to content

ext/bcmath: Renamed macros and variables #14507

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 9 commits into from
Jun 9, 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
42 changes: 21 additions & 21 deletions ext/bcmath/libbcmath/src/doaddsub.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,17 @@ bc_num _bc_do_add(bc_num n1, bc_num n2)
/* Now add the remaining fraction part and equal size integer parts. */
count = 0;
/* Uses SIMD to perform calculations at high speed. */
if (min_bytes >= sizeof(BC_UINT_T)) {
if (min_bytes >= sizeof(BC_VECTOR)) {
sumptr++;
n1ptr++;
n2ptr++;
while (count + sizeof(BC_UINT_T) <= min_bytes) {
sumptr -= sizeof(BC_UINT_T);
n1ptr -= sizeof(BC_UINT_T);
n2ptr -= sizeof(BC_UINT_T);
while (count + sizeof(BC_VECTOR) <= min_bytes) {
sumptr -= sizeof(BC_VECTOR);
n1ptr -= sizeof(BC_VECTOR);
n2ptr -= sizeof(BC_VECTOR);

BC_UINT_T n1bytes;
BC_UINT_T n2bytes;
BC_VECTOR n1bytes;
BC_VECTOR n2bytes;
memcpy(&n1bytes, n1ptr, sizeof(n1bytes));
memcpy(&n2bytes, n2ptr, sizeof(n2bytes));

Expand All @@ -103,15 +103,15 @@ bc_num _bc_do_add(bc_num n1, bc_num n2)
*/
n1bytes += SWAR_REPEAT(0xF6) + n2bytes + carry;
/* If the most significant bit is 0, a carry has occurred. */
carry = !(n1bytes & ((BC_UINT_T) 1 << (8 * sizeof(BC_UINT_T) - 1)));
carry = !(n1bytes & ((BC_VECTOR) 1 << (8 * sizeof(BC_VECTOR) - 1)));

/*
* The calculation result is a mixture of bytes that have been carried and bytes that have not.
* The most significant bit of each byte is 0 if it is carried forward, and 1 if it is not.
* Using this, subtract the 0xF6 added for adjustment from the byte that has not been carried
* over to return it to the correct value as a decimal number.
*/
BC_UINT_T sum_mask = ((n1bytes & SWAR_REPEAT(0x80)) >> 7) * 0xF6;
BC_VECTOR sum_mask = ((n1bytes & SWAR_REPEAT(0x80)) >> 7) * 0xF6;
n1bytes -= sum_mask;

#if BC_LITTLE_ENDIAN
Expand All @@ -121,7 +121,7 @@ bc_num _bc_do_add(bc_num n1, bc_num n2)

memcpy(sumptr, &n1bytes, sizeof(n1bytes));

count += sizeof(BC_UINT_T);
count += sizeof(BC_VECTOR);
}
sumptr--;
n1ptr--;
Expand Down Expand Up @@ -215,17 +215,17 @@ bc_num _bc_do_sub(bc_num n1, bc_num n2)
/* Now do the equal length scale and integer parts. */
count = 0;
/* Uses SIMD to perform calculations at high speed. */
if (min_bytes >= sizeof(BC_UINT_T)) {
if (min_bytes >= sizeof(BC_VECTOR)) {
diffptr++;
n1ptr++;
n2ptr++;
while (count + sizeof(BC_UINT_T) <= min_bytes) {
diffptr -= sizeof(BC_UINT_T);
n1ptr -= sizeof(BC_UINT_T);
n2ptr -= sizeof(BC_UINT_T);
while (count + sizeof(BC_VECTOR) <= min_bytes) {
diffptr -= sizeof(BC_VECTOR);
n1ptr -= sizeof(BC_VECTOR);
n2ptr -= sizeof(BC_VECTOR);

BC_UINT_T n1bytes;
BC_UINT_T n2bytes;
BC_VECTOR n1bytes;
BC_VECTOR n2bytes;
memcpy(&n1bytes, n1ptr, sizeof(n1bytes));
memcpy(&n2bytes, n2ptr, sizeof(n2bytes));

Expand All @@ -237,7 +237,7 @@ bc_num _bc_do_sub(bc_num n1, bc_num n2)

n1bytes -= n2bytes + borrow;
/* If the most significant bit is 1, a carry down has occurred. */
bool tmp_borrow = n1bytes & ((BC_UINT_T) 1 << (8 * sizeof(BC_UINT_T) - 1));
bool tmp_borrow = n1bytes & ((BC_VECTOR) 1 << (8 * sizeof(BC_VECTOR) - 1));

/*
* Check the most significant bit of each of the bytes, and if it is 1, a carry down has
Expand All @@ -246,7 +246,7 @@ bc_num _bc_do_sub(bc_num n1, bc_num n2)
* Therefore, for a byte that has been carried down, set all the upper 4 bits to 0 and subtract
* 6 from the lower 4 bits to adjust it to the correct value as a decimal number.
*/
BC_UINT_T borrow_mask = ((n1bytes & SWAR_REPEAT(0x80)) >> 7) * 0x06;
BC_VECTOR borrow_mask = ((n1bytes & SWAR_REPEAT(0x80)) >> 7) * 0x06;
n1bytes = (n1bytes & SWAR_REPEAT(0x0F)) - borrow_mask;

#if BC_LITTLE_ENDIAN
Expand All @@ -257,14 +257,14 @@ bc_num _bc_do_sub(bc_num n1, bc_num n2)
memcpy(diffptr, &n1bytes, sizeof(n1bytes));

borrow = tmp_borrow;
count += sizeof(BC_UINT_T);
count += sizeof(BC_VECTOR);
}
diffptr--;
n1ptr--;
n2ptr--;
}

/* Calculate the remaining bytes that are less than the size of BC_UINT_T using a normal loop. */
/* Calculate the remaining bytes that are less than the size of BC_VECTOR using a normal loop. */
for (; count < min_bytes; count++) {
val = *n1ptr-- - *n2ptr-- - borrow;
if (val < 0) {
Expand Down
4 changes: 2 additions & 2 deletions ext/bcmath/libbcmath/src/private.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ static inline uint64_t BC_BSWAP64(uint64_t u)

#if SIZEOF_SIZE_T >= 8
# define BC_BSWAP(u) BC_BSWAP64(u)
# define BC_UINT_T uint64_t
typedef uint64_t BC_VECTOR;
#else
# define BC_BSWAP(u) BC_BSWAP32(u)
# define BC_UINT_T uint32_t
typedef uint32_t BC_VECTOR;
#endif

#ifdef WORDS_BIGENDIAN
Expand Down
116 changes: 61 additions & 55 deletions ext/bcmath/libbcmath/src/recmul.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,34 @@
#include <stddef.h>
#include <assert.h>
#include <stdbool.h>
#include "private.h" /* For _bc_rm_leading_zeros() */
#include "private.h"
#include "zend_alloc.h"


#if SIZEOF_SIZE_T >= 8
# define BC_MUL_UINT_DIGITS 8
# define BC_MUL_UINT_OVERFLOW (BC_UINT_T) 100000000
# define BC_VECTOR_SIZE 8
/* The boundary number is computed from BASE ** BC_VECTOR_SIZE */
# define BC_VECTOR_BOUNDARY_NUM (BC_VECTOR) 100000000
#else
# define BC_MUL_UINT_DIGITS 4
# define BC_MUL_UINT_OVERFLOW (BC_UINT_T) 10000
# define BC_VECTOR_SIZE 4
/* The boundary number is computed from BASE ** BC_VECTOR_SIZE */
# define BC_VECTOR_BOUNDARY_NUM (BC_VECTOR) 10000
#endif

#define BC_MUL_MAX_ADD_COUNT (~((BC_UINT_T) 0) / (BC_MUL_UINT_OVERFLOW * BC_MUL_UINT_OVERFLOW))
/*
* Adding more than this many times may cause uint32_t/uint64_t to overflow.
* Typically this is 1844 for 64bit and 42 for 32bit.
*/
#define BC_VECTOR_NO_OVERFLOW_ADD_COUNT (~((BC_VECTOR) 0) / (BC_VECTOR_BOUNDARY_NUM * BC_VECTOR_BOUNDARY_NUM))


/* Multiply utility routines */

static inline void bc_digits_adjustment(BC_UINT_T *prod_uint, size_t prod_arr_size)
static inline void bc_digits_adjustment(BC_VECTOR *prod_vector, size_t prod_arr_size)
{
for (size_t i = 0; i < prod_arr_size - 1; i++) {
prod_uint[i + 1] += prod_uint[i] / BC_MUL_UINT_OVERFLOW;
prod_uint[i] %= BC_MUL_UINT_OVERFLOW;
prod_vector[i + 1] += prod_vector[i] / BC_VECTOR_BOUNDARY_NUM;
prod_vector[i] %= BC_VECTOR_BOUNDARY_NUM;
}
}

Expand All @@ -66,16 +72,16 @@ static inline void bc_digits_adjustment(BC_UINT_T *prod_uint, size_t prod_arr_si
* due to its divide-and-conquer nature.
*/
#if SIZEOF_SIZE_T == 4
static uint32_t bc_parse_chunk_chars(const char *str)
static BC_VECTOR bc_parse_chunk_chars(const char *str)
{
uint32_t tmp;
BC_VECTOR tmp;
memcpy(&tmp, str, sizeof(tmp));
#if !BC_LITTLE_ENDIAN
tmp = BC_BSWAP(tmp);
#endif

uint32_t lower_digits = (tmp & 0x0f000f00) >> 8;
uint32_t upper_digits = (tmp & 0x000f000f) * 10;
BC_VECTOR lower_digits = (tmp & 0x0f000f00) >> 8;
BC_VECTOR upper_digits = (tmp & 0x000f000f) * 10;

tmp = lower_digits + upper_digits;

Expand All @@ -85,16 +91,16 @@ static uint32_t bc_parse_chunk_chars(const char *str)
return lower_digits + upper_digits;
}
#elif SIZEOF_SIZE_T == 8
static uint64_t bc_parse_chunk_chars(const char *str)
static BC_VECTOR bc_parse_chunk_chars(const char *str)
{
uint64_t tmp;
BC_VECTOR tmp;
memcpy(&tmp, str, sizeof(tmp));
#if !BC_LITTLE_ENDIAN
tmp = BC_BSWAP(tmp);
#endif

uint64_t lower_digits = (tmp & 0x0f000f000f000f00) >> 8;
uint64_t upper_digits = (tmp & 0x000f000f000f000f) * 10;
BC_VECTOR lower_digits = (tmp & 0x0f000f000f000f00) >> 8;
BC_VECTOR upper_digits = (tmp & 0x000f000f000f000f) * 10;

tmp = lower_digits + upper_digits;

Expand All @@ -111,17 +117,17 @@ static uint64_t bc_parse_chunk_chars(const char *str)
#endif

/*
* Converts BCD to uint, going backwards from pointer n by the number of
* Converts bc_num to BC_VECTOR, going backwards from pointer n by the number of
* characters specified by len.
*/
static inline BC_UINT_T bc_partial_convert_to_uint(const char *n, size_t len)
static inline BC_VECTOR bc_partial_convert_to_vector(const char *n, size_t len)
{
if (len == BC_MUL_UINT_DIGITS) {
return bc_parse_chunk_chars(n - BC_MUL_UINT_DIGITS + 1);
if (len == BC_VECTOR_SIZE) {
return bc_parse_chunk_chars(n - BC_VECTOR_SIZE + 1);
}

BC_UINT_T num = 0;
BC_UINT_T base = 1;
BC_VECTOR num = 0;
BC_VECTOR base = 1;

for (size_t i = 0; i < len; i++) {
num += *n * base;
Expand All @@ -132,12 +138,12 @@ static inline BC_UINT_T bc_partial_convert_to_uint(const char *n, size_t len)
return num;
}

static inline void bc_convert_to_uint(BC_UINT_T *n_uint, const char *nend, size_t nlen)
static inline void bc_convert_to_vector(BC_VECTOR *n_vector, const char *nend, size_t nlen)
{
size_t i = 0;
while (nlen > 0) {
size_t len = MIN(BC_MUL_UINT_DIGITS, nlen);
n_uint[i] = bc_partial_convert_to_uint(nend, len);
size_t len = MIN(BC_VECTOR_SIZE, nlen);
n_vector[i] = bc_partial_convert_to_vector(nend, len);
nend -= len;
nlen -= len;
i++;
Expand All @@ -153,18 +159,18 @@ static inline void bc_fast_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len,
const char *n1end = n1->n_value + n1len - 1;
const char *n2end = n2->n_value + n2len - 1;

BC_UINT_T n1_uint = bc_partial_convert_to_uint(n1end, n1len);
BC_UINT_T n2_uint = bc_partial_convert_to_uint(n2end, n2len);
BC_UINT_T prod_uint = n1_uint * n2_uint;
BC_VECTOR n1_vector = bc_partial_convert_to_vector(n1end, n1len);
BC_VECTOR n2_vector = bc_partial_convert_to_vector(n2end, n2len);
BC_VECTOR prod_vector = n1_vector * n2_vector;

size_t prodlen = n1len + n2len;
*prod = bc_new_num_nonzeroed(prodlen, 0);
char *pptr = (*prod)->n_value;
char *pend = pptr + prodlen - 1;

while (pend >= pptr) {
*pend-- = prod_uint % BASE;
prod_uint /= BASE;
*pend-- = prod_vector % BASE;
prod_vector /= BASE;
}
}

Expand Down Expand Up @@ -215,7 +221,7 @@ static void bc_write_bcd_representation(uint32_t value, char *str)
}

/*
* Converts the BCD of bc_num by 4 (32 bits) or 8 (64 bits) digits to an array of BC_UINT_Ts.
* Converts the BCD of bc_num by 4 (32 bits) or 8 (64 bits) digits to an array of BC_VECTOR.
* The array is generated starting with the smaller digits.
* e.g. 12345678901234567890 => {34567890, 56789012, 1234}
*
Expand All @@ -229,28 +235,28 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc
const char *n2end = n2->n_value + n2len - 1;
size_t prodlen = n1len + n2len;

size_t n1_arr_size = (n1len + BC_MUL_UINT_DIGITS - 1) / BC_MUL_UINT_DIGITS;
size_t n2_arr_size = (n2len + BC_MUL_UINT_DIGITS - 1) / BC_MUL_UINT_DIGITS;
size_t n1_arr_size = (n1len + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;
size_t n2_arr_size = (n2len + BC_VECTOR_SIZE - 1) / BC_VECTOR_SIZE;
size_t prod_arr_size = n1_arr_size + n2_arr_size - 1;

/*
* let's say that N is the max of n1len and n2len (and a multiple of BC_MUL_UINT_DIGITS for simplicity),
* then this sum is <= N/BC_MUL_UINT_DIGITS + N/BC_MUL_UINT_DIGITS + N/BC_MUL_UINT_DIGITS + N/BC_MUL_UINT_DIGITS - 1
* which is equal to N - 1 if BC_MUL_UINT_DIGITS is 4, and N/2 - 1 if BC_MUL_UINT_DIGITS is 8.
* let's say that N is the max of n1len and n2len (and a multiple of BC_VECTOR_SIZE for simplicity),
* then this sum is <= N/BC_VECTOR_SIZE + N/BC_VECTOR_SIZE + N/BC_VECTOR_SIZE + N/BC_VECTOR_SIZE - 1
* which is equal to N - 1 if BC_VECTOR_SIZE is 4, and N/2 - 1 if BC_VECTOR_SIZE is 8.
*/
BC_UINT_T *buf = safe_emalloc(n1_arr_size + n2_arr_size + prod_arr_size, sizeof(BC_UINT_T), 0);
BC_VECTOR *buf = safe_emalloc(n1_arr_size + n2_arr_size + prod_arr_size, sizeof(BC_VECTOR), 0);

BC_UINT_T *n1_uint = buf;
BC_UINT_T *n2_uint = buf + n1_arr_size;
BC_UINT_T *prod_uint = n2_uint + n2_arr_size;
BC_VECTOR *n1_vector = buf;
BC_VECTOR *n2_vector = buf + n1_arr_size;
BC_VECTOR *prod_vector = n2_vector + n2_arr_size;

for (i = 0; i < prod_arr_size; i++) {
prod_uint[i] = 0;
prod_vector[i] = 0;
}

/* Convert to uint[] */
bc_convert_to_uint(n1_uint, n1end, n1len);
bc_convert_to_uint(n2_uint, n2end, n2len);
bc_convert_to_vector(n1_vector, n1end, n1len);
bc_convert_to_vector(n2_vector, n2end, n2len);

/* Multiplication and addition */
size_t count = 0;
Expand All @@ -260,34 +266,34 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc
* When multiplying large numbers of digits, there is a possibility of
* overflow, so digit adjustment is performed beforehand.
*/
if (UNEXPECTED(count >= BC_MUL_MAX_ADD_COUNT)) {
bc_digits_adjustment(prod_uint, prod_arr_size);
if (UNEXPECTED(count >= BC_VECTOR_NO_OVERFLOW_ADD_COUNT)) {
bc_digits_adjustment(prod_vector, prod_arr_size);
count = 0;
}
count++;
for (size_t j = 0; j < n2_arr_size; j++) {
prod_uint[i + j] += n1_uint[i] * n2_uint[j];
prod_vector[i + j] += n1_vector[i] * n2_vector[j];
}
}

/*
* Move a value exceeding 4/8 digits by carrying to the next digit.
* However, the last digit does nothing.
*/
bc_digits_adjustment(prod_uint, prod_arr_size);
bc_digits_adjustment(prod_vector, prod_arr_size);

/* Convert to bc_num */
*prod = bc_new_num_nonzeroed(prodlen, 0);
char *pptr = (*prod)->n_value;
char *pend = pptr + prodlen - 1;
i = 0;
while (i < prod_arr_size - 1) {
#if BC_MUL_UINT_DIGITS == 4
bc_write_bcd_representation(prod_uint[i], pend - 3);
#if BC_VECTOR_SIZE == 4
bc_write_bcd_representation(prod_vector[i], pend - 3);
pend -= 4;
#else
bc_write_bcd_representation(prod_uint[i] / 10000, pend - 7);
bc_write_bcd_representation(prod_uint[i] % 10000, pend - 3);
bc_write_bcd_representation(prod_vector[i] / 10000, pend - 7);
bc_write_bcd_representation(prod_vector[i] % 10000, pend - 3);
pend -= 8;
#endif
i++;
Expand All @@ -298,8 +304,8 @@ static void bc_standard_mul(bc_num n1, size_t n1len, bc_num n2, size_t n2len, bc
* Also need to fill it to the end with zeros, so loop until the end of the string.
*/
while (pend >= pptr) {
*pend-- = prod_uint[i] % BASE;
prod_uint[i] /= BASE;
*pend-- = prod_vector[i] % BASE;
prod_vector[i] /= BASE;
}

efree(buf);
Expand All @@ -320,7 +326,7 @@ bc_num bc_multiply(bc_num n1, bc_num n2, size_t scale)
size_t prod_scale = MIN(full_scale, MAX(scale, MAX(n1->n_scale, n2->n_scale)));

/* Do the multiply */
if (len1 <= BC_MUL_UINT_DIGITS && len2 <= BC_MUL_UINT_DIGITS) {
if (len1 <= BC_VECTOR_SIZE && len2 <= BC_VECTOR_SIZE) {
bc_fast_mul(n1, len1, n2, len2, &prod);
} else {
bc_standard_mul(n1, len1, n2, len2, &prod);
Expand Down
Loading