]> granicus.if.org Git - php/commitdiff
PowerPC64 support for add and sub with overflow check
authorGustavo Frederico Temple Pedrosa <gustavo.pedrosa@eldorado.org.br>
Thu, 11 Dec 2014 18:14:51 +0000 (18:14 +0000)
committerRemi Collet <remi@php.net>
Fri, 12 Dec 2014 09:47:54 +0000 (10:47 +0100)
This adds fast architecture-specific implementations of the
following functions for the ppc64:

* fast_add_function
* fast_sub_function

Zend/zend_operators.h

index c6d40b8f85e7a4bb516d448690d4b10d5af482f6..ccd00b4e52892403e5ce3ee575dc417b0f212fa5 100644 (file)
@@ -602,6 +602,36 @@ static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *o
                          "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
@@ -691,6 +721,36 @@ static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *o
                          "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));