Skip to content

Commit 90a5b87

Browse files
authored
Simplify conversion in BCMath (#14157)
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 304f19b commit 90a5b87

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
@@ -21,20 +21,16 @@
2121
# include <emmintrin.h>
2222
#endif
2323

24-
static char *bc_copy_and_shift_numbers(char *restrict dest, const char *source, const char *source_end, unsigned char shift, bool add)
24+
char *bc_copy_and_toggle_bcd(char *restrict dest, const char *source, const char *source_end)
2525
{
26-
size_t bulk_shift = SWAR_REPEAT(shift);
27-
if (!add) {
28-
bulk_shift = -bulk_shift;
29-
shift = -shift;
30-
}
26+
const size_t bulk_shift = SWAR_REPEAT('0');
3127

3228
#ifdef __SSE2__
3329
/* SIMD SSE2 bulk shift + copy */
34-
__m128i shift_vector = _mm_set1_epi8(shift);
30+
__m128i shift_vector = _mm_set1_epi8('0');
3531
while (source + sizeof(__m128i) <= source_end) {
3632
__m128i bytes = _mm_loadu_si128((const __m128i *) source);
37-
bytes = _mm_add_epi8(bytes, shift_vector);
33+
bytes = _mm_xor_si128(bytes, shift_vector);
3834
_mm_storeu_si128((__m128i *) dest, bytes);
3935

4036
source += sizeof(__m128i);
@@ -50,28 +46,18 @@ static char *bc_copy_and_shift_numbers(char *restrict dest, const char *source,
5046
size_t bytes;
5147
memcpy(&bytes, source, sizeof(bytes));
5248

53-
bytes += bulk_shift;
49+
bytes ^= bulk_shift;
5450
memcpy(dest, &bytes, sizeof(bytes));
5551

5652
source += sizeof(size_t);
5753
dest += sizeof(size_t);
5854
}
5955

6056
while (source < source_end) {
61-
*dest = *source + shift;
57+
*dest = *source ^ '0';
6258
dest++;
6359
source++;
6460
}
6561

6662
return dest;
6763
}
68-
69-
char *bc_copy_ch_val(char *restrict dest, const char *source, const char *source_end)
70-
{
71-
return bc_copy_and_shift_numbers(dest, source, source_end, '0', false);
72-
}
73-
74-
char *bc_copy_bcd_val(char *restrict dest, const char *source, const char *source_end)
75-
{
76-
return bc_copy_and_shift_numbers(dest, source, source_end, '0', true);
77-
}

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
@@ -165,12 +165,12 @@ bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, boo
165165
* If zero_int is true and the str_scale is 0, there is an early return,
166166
* so here str_scale is always greater than 0.
167167
*/
168-
nptr = bc_copy_ch_val(nptr, fractional_ptr, fractional_end);
168+
nptr = bc_copy_and_toggle_bcd(nptr, fractional_ptr, fractional_end);
169169
} else {
170170
const char *integer_end = integer_ptr + digits;
171-
nptr = bc_copy_ch_val(nptr, integer_ptr, integer_end);
171+
nptr = bc_copy_and_toggle_bcd(nptr, integer_ptr, integer_end);
172172
if (str_scale > 0) {
173-
nptr = bc_copy_ch_val(nptr, fractional_ptr, fractional_end);
173+
nptr = bc_copy_and_toggle_bcd(nptr, fractional_ptr, fractional_end);
174174
}
175175
}
176176

0 commit comments

Comments
 (0)