Skip to content

Commit 2c0c2b3

Browse files
committed
Simplify conversion in BCMath
This simplifies the code, and also might indirectly improve performance due to a decrease in instruction cache pressure. Although the latter is probably negligible. This works because 0x30 has no overlapping bits with [0, 9].
1 parent 79af2ad commit 2c0c2b3

File tree

4 files changed

+12
-27
lines changed

4 files changed

+12
-27
lines changed

ext/bcmath/libbcmath/src/convert.c

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,16 @@
2626
* Example: SWAR_REPEAT(0xAB) will be 0xABABABAB for 32-bit and 0xABABABABABABABAB for 64-bit. */
2727
#define SWAR_REPEAT(x) (SWAR_ONES * (x))
2828

29-
static char *bc_copy_and_shift_numbers(char *restrict dest, const char *source, const char *source_end, unsigned char shift, bool add)
29+
char *bc_copy_and_toggle_bcd(char *restrict dest, const char *source, const char *source_end)
3030
{
31-
size_t bulk_shift = SWAR_REPEAT(shift);
32-
if (!add) {
33-
bulk_shift = -bulk_shift;
34-
shift = -shift;
35-
}
31+
const size_t bulk_shift = SWAR_REPEAT('0');
3632

3733
#ifdef __SSE2__
3834
/* SIMD SSE2 bulk shift + copy */
39-
__m128i shift_vector = _mm_set1_epi8(shift);
35+
__m128i shift_vector = _mm_set1_epi8('0');
4036
while (source + sizeof(__m128i) <= source_end) {
4137
__m128i bytes = _mm_loadu_si128((const __m128i *) source);
42-
bytes = _mm_add_epi8(bytes, shift_vector);
38+
bytes = _mm_xor_si128(bytes, shift_vector);
4339
_mm_storeu_si128((__m128i *) dest, bytes);
4440

4541
source += sizeof(__m128i);
@@ -55,28 +51,18 @@ static char *bc_copy_and_shift_numbers(char *restrict dest, const char *source,
5551
size_t bytes;
5652
memcpy(&bytes, source, sizeof(bytes));
5753

58-
bytes += bulk_shift;
54+
bytes ^= bulk_shift;
5955
memcpy(dest, &bytes, sizeof(bytes));
6056

6157
source += sizeof(size_t);
6258
dest += sizeof(size_t);
6359
}
6460

6561
while (source < source_end) {
66-
*dest = *source + shift;
62+
*dest = *source ^ '0';
6763
dest++;
6864
source++;
6965
}
7066

7167
return dest;
7268
}
73-
74-
char *bc_copy_ch_val(char *restrict dest, const char *source, const char *source_end)
75-
{
76-
return bc_copy_and_shift_numbers(dest, source, source_end, '0', false);
77-
}
78-
79-
char *bc_copy_bcd_val(char *restrict dest, const char *source, const char *source_end)
80-
{
81-
return bc_copy_and_shift_numbers(dest, source, source_end, '0', true);
82-
}

ext/bcmath/libbcmath/src/convert.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#ifndef BCMATH_CONVERT_H
1818
#define BCMATH_CONVERT_H
1919

20-
char *bc_copy_ch_val(char *restrict dest, const char *source, const char *source_end);
21-
char *bc_copy_bcd_val(char *restrict dest, const char *source, const char *source_end);
20+
char *bc_copy_and_toggle_bcd(char *restrict dest, const char *source, const char *source_end);
2221

2322
#endif

ext/bcmath/libbcmath/src/num2str.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,13 @@ zend_string *bc_num2str_ex(bc_num num, size_t scale)
5757

5858
/* Load the whole number. */
5959
const char *nptr = num->n_value;
60-
sptr = bc_copy_bcd_val(sptr, nptr, nptr + num->n_len);
60+
sptr = bc_copy_and_toggle_bcd(sptr, nptr, nptr + num->n_len);
6161
nptr += num->n_len;
6262

6363
/* Now the fraction. */
6464
if (scale > 0) {
6565
*sptr++ = '.';
66-
sptr = bc_copy_bcd_val(sptr, nptr, nptr + min_scale);
66+
sptr = bc_copy_and_toggle_bcd(sptr, nptr, nptr + min_scale);
6767
for (index = num->n_scale; index < scale; index++) {
6868
*sptr++ = BCD_CHAR(0);
6969
}

ext/bcmath/libbcmath/src/str2num.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,12 @@ bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, boo
164164
* If zero_int is true and the str_scale is 0, there is an early return,
165165
* so here str_scale is always greater than 0.
166166
*/
167-
nptr = bc_copy_ch_val(nptr, fractional_ptr, fractional_end);
167+
nptr = bc_copy_and_toggle_bcd(nptr, fractional_ptr, fractional_end);
168168
} else {
169169
const char *integer_end = integer_ptr + digits;
170-
nptr = bc_copy_ch_val(nptr, integer_ptr, integer_end);
170+
nptr = bc_copy_and_toggle_bcd(nptr, integer_ptr, integer_end);
171171
if (str_scale > 0) {
172-
nptr = bc_copy_ch_val(nptr, fractional_ptr, fractional_end);
172+
nptr = bc_copy_and_toggle_bcd(nptr, fractional_ptr, fractional_end);
173173
}
174174
}
175175

0 commit comments

Comments
 (0)