From: Anton Blanchard <anton@samba.org>
Date: Tue, 26 May 2015 13:06:12 +0000 (+1000)
Subject: Improve performance of PowerPC64 fast_long_increment_function
X-Git-Tag: php-7.0.0beta3~5^2~72
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4d578f28df214c5faf115d3a629f9ffe82640b2b;p=php

Improve performance of PowerPC64 fast_long_increment_function

Detecting overflow with the XER is slow, partially because we have to
clear it before use.

gcc does a better job of detecting overflow of an increment or decrement
than we can with inline assembly. It knows that an increment will only
overflow if it is one less than the overflow value. This means we end
up with a simple compare/branch. Furthermore, leaving it in c allows gcc
to schedule the instructions better.

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

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

        testcase();
?>
---

diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index 21bf9dd67f..7e4fdccb93 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -460,33 +460,6 @@ static zend_always_inline void fast_long_increment_function(zval *op1)
 		  "n"(IS_DOUBLE),
 		  "n"(ZVAL_OFFSETOF_TYPE)
 		: "cc");
-#elif defined(__GNUC__) && defined(__powerpc64__)
-	 __asm__(
-		"ld 14, 0(%0)\n\t"
-		"li 15, 1\n\t"
-		"li 16, 0\n\t"
-		"mtxer 16\n\t"
-		"addo. 14, 14, 15\n\t"
-		"std 14, 0(%0)\n\t"
-		"bns+  0f\n\t"
-		"xor 14, 14, 14\n\t"
-		"lis 15, 0x43e00000@h\n\t"
-		"ori 15, 15, 0x43e00000@l\n\t"
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-		"stw 14, 0(%0)\n\t"
-		"stw 15, 0x4(%0)\n\t"
-#else
-		"stw 14, 0x4(%0)\n\t"
-		"stw 15, 0(%0)\n\t"
-#endif
-		"li 14, %1\n\t"
-		"stw 14, %c2(%0)\n"
-		"0:"
-		:
-		: "r"(&op1->value),
-		  "n"(IS_DOUBLE),
-		  "n"(ZVAL_OFFSETOF_TYPE)
-		: "r14", "r15", "r16", "cc");
 #else
 	if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MAX)) {
 		/* switch to double */
@@ -525,33 +498,6 @@ static zend_always_inline void fast_long_decrement_function(zval *op1)
 		  "n"(IS_DOUBLE),
 		  "n"(ZVAL_OFFSETOF_TYPE)
 		: "cc");
-#elif defined(__GNUC__) && defined(__powerpc64__)
-	__asm__(
-		"ld 14, 0(%0)\n\t"
-		"li 15, 1\n\t"
-		"li 16, 0\n\t"
-		"mtxer 16\n\t"
-		"subo. 14, 14, 15\n\t"
-		"std 14, 0(%0)\n\t"
-		"bns+  0f\n\t"
-		"xor 14, 14, 14\n\t"
-		"lis 15, 0xc3e00000@h\n\t"
-		"ori 15, 15, 0xc3e00000@l\n\t"
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-		"stw 14, 0(%0)\n\t"
-		"stw 15, 0x4(%0)\n\t"
-#else
-		"stw 14, 0x4(%0)\n\t"
-		"stw 15, 0(%0)\n\t"
-#endif
-		"li 14, %1\n\t"
-		"stw 14, %c2(%0)\n"
-		"0:"
-		:
-		: "r"(&op1->value),
-		  "n"(IS_DOUBLE),
-		  "n"(ZVAL_OFFSETOF_TYPE)
-		: "r14", "r15", "r16", "cc");
 #else
 	if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MIN)) {
 		/* switch to double */