]> granicus.if.org Git - php/commitdiff
Improve performance of PowerPC64 fast_long_add_function
authorAnton Blanchard <anton@samba.org>
Tue, 26 May 2015 13:41:42 +0000 (23:41 +1000)
committerRemi Collet <remi@php.net>
Wed, 29 Jul 2015 07:22:38 +0000 (09:22 +0200)
Detecting overflow with the XER is slow, partially because we have to
clear it before use.

PHP already has a fast way of detecting overflow in its fallback
c implementation. Overflow only occurs if the signs of the two
operands are the same and the sign of the result is different.
Furthermore, leaving it in c allows gcc to schedule the instructions
better.

This is 9% faster on a POWER8 running a simple testcase:

<?php
        function testcase($count = 100000000) {
$x = 1;
                for ($i = 0; $i < $count; $i++) {
                        $x = $x + 1;
                        $x = $x + 1;
                        $x = $x + 1;
                        $x = $x + 1;
                        $x = $x + 1;
                }
        }

        testcase();
?>

Zend/zend_operators.h

index 7e4fdccb9313dc1a861befcbbcf56664f5d25e4d..f46a72904534cca87e297dcea5bc1fb76f069f5c 100644 (file)
@@ -556,36 +556,6 @@ static zend_always_inline void fast_long_add_function(zval *result, zval *op1, z
                  "n"(IS_DOUBLE),
                  "n"(ZVAL_OFFSETOF_TYPE)
                : "rax","cc");
-#elif defined(__GNUC__) && defined(__powerpc64__)
-       __asm__(
-               "ld 14, 0(%1)\n\t"
-               "ld 15, 0(%2)\n\t"
-               "li 16, 0 \n\t"
-               "mtxer 16\n\t"
-               "addo. 14, 14, 15\n\t"
-               "bso- 0f\n\t"
-               "std 14, 0(%0)\n\t"
-               "li 14, %3\n\t"
-               "stw 14, %c5(%0)\n\t"
-               "b 1f\n"
-               "0:\n\t"
-               "lfd 0, 0(%1)\n\t"
-               "lfd 1, 0(%2)\n\t"
-               "fcfid 0, 0\n\t"
-               "fcfid 1, 1\n\t"
-               "fadd 0, 0, 1\n\t"
-               "li 14, %4\n\t"
-               "stw 14, %c5(%0)\n\t"
-               "stfd 0, 0(%0)\n"
-               "1:"
-               :
-               : "r"(&result->value),
-                 "r"(&op1->value),
-                 "r"(&op2->value),
-                 "n"(IS_LONG),
-                 "n"(IS_DOUBLE),
-                 "n"(ZVAL_OFFSETOF_TYPE)
-               : "r14","r15","r16","fr0","fr1","cc");
 #else
        /*
         * 'result' may alias with op1 or op2, so we need to
@@ -680,36 +650,6 @@ static zend_always_inline void fast_long_sub_function(zval *result, zval *op1, z
                  "n"(IS_DOUBLE),
                  "n"(ZVAL_OFFSETOF_TYPE)
                : "rax","cc");
-#elif defined(__GNUC__) && defined(__powerpc64__)
-       __asm__(
-               "ld 14, 0(%1)\n\t"
-               "ld 15, 0(%2)\n\t"
-               "li 16, 0\n\t"
-               "mtxer 16\n\t"
-               "subo. 14, 14, 15\n\t"
-               "bso- 0f\n\t"
-               "std 14, 0(%0)\n\t"
-               "li 14, %3\n\t"
-               "stw 14, %c5(%0)\n\t"
-               "b 1f\n"
-               "0:\n\t"
-               "lfd 0, 0(%1)\n\t"
-               "lfd 1, 0(%2)\n\t"
-               "fcfid 0, 0\n\t"
-               "fcfid 1, 1\n\t"
-               "fsub 0, 0, 1\n\t"
-               "li 14, %4\n\t"
-               "stw 14, %c5(%0)\n\t"
-               "stfd 0, 0(%0)\n"
-               "1:"
-               :
-               : "r"(&result->value),
-                 "r"(&op1->value),
-                 "r"(&op2->value),
-                 "n"(IS_LONG),
-                 "n"(IS_DOUBLE),
-                 "n"(ZVAL_OFFSETOF_TYPE)
-               : "r14","r15","r16","fr0","fr1","cc");
 #else
        ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));