mirror of
https://github.com/php/php-src.git
synced 2024-11-24 10:24:11 +08:00
Improve performance of PowerPC64 ZEND_SIGNED_MULTIPLY_LONG
Detecting overflow with the XER is slow, partially because we have to clear it before use. We can do better by using a trick where we compare the high 64 bits of the result with the low 64 bits shifted right 63 bits. This is 7% faster on a POWER8 running a simple testcase: <?php function testcase($count = 100000000) { for ($i = 0; $i < $count; $i++) { $x = 1; $x = $x * 2; $x = $x * 2; $x = $x * 2; $x = $x * 2; } } testcase(); ?>
This commit is contained in:
parent
a581910a76
commit
305199a131
@ -74,20 +74,19 @@
|
||||
|
||||
#elif defined(__powerpc64__) && defined(__GNUC__)
|
||||
|
||||
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
|
||||
long __tmpvar; \
|
||||
__asm__("li 14, 0\n\t" \
|
||||
"mtxer 14\n\t" \
|
||||
"mulldo. %0, %2,%3\n\t" \
|
||||
"xor %1, %1, %1\n\t" \
|
||||
"bns+ 0f\n\t" \
|
||||
"li %1, 1\n\t" \
|
||||
"0:\n" \
|
||||
: "=r"(__tmpvar),"=r"(usedval) \
|
||||
: "r"(a), "r"(b) \
|
||||
: "r14", "cc"); \
|
||||
if (usedval) (dval) = (double) (a) * (double) (b); \
|
||||
else (lval) = __tmpvar; \
|
||||
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
|
||||
long __low, __high; \
|
||||
__asm__("mulld %0,%2,%3\n\t" \
|
||||
"mulhd %1,%2,%3\n" \
|
||||
: "=&r"(__low), "=&r"(__high) \
|
||||
: "r"(a), "r"(b)); \
|
||||
if ((__low >> 63) != __high) { \
|
||||
(dval) = (double) (a) * (double) (b); \
|
||||
(usedval) = 1; \
|
||||
} else { \
|
||||
(lval) = __low; \
|
||||
(usedval) = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#elif SIZEOF_ZEND_LONG == 4
|
||||
|
Loading…
Reference in New Issue
Block a user