Use "fast" assembler functions in "slow" ones.

Mark assembler functions that changes memory.
This commit is contained in:
Dmitry Stogov 2016-06-01 20:52:14 +03:00
parent 6a32d44392
commit 1b4946e658
2 changed files with 12 additions and 34 deletions

View file

@ -907,20 +907,9 @@ ZEND_API int ZEND_FASTCALL add_function(zval *result, zval *op1, zval *op2) /* {
while (1) {
switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
case TYPE_PAIR(IS_LONG, IS_LONG): {
zend_long lval = Z_LVAL_P(op1) + Z_LVAL_P(op2);
/* check for overflow by comparing sign bits */
if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
} else {
ZVAL_LONG(result, lval);
}
case TYPE_PAIR(IS_LONG, IS_LONG):
fast_long_add_function(result, op1, op2);
return SUCCESS;
}
case TYPE_PAIR(IS_LONG, IS_DOUBLE):
ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
return SUCCESS;
@ -971,20 +960,9 @@ ZEND_API int ZEND_FASTCALL sub_function(zval *result, zval *op1, zval *op2) /* {
while (1) {
switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
case TYPE_PAIR(IS_LONG, IS_LONG): {
zend_long lval = Z_LVAL_P(op1) - Z_LVAL_P(op2);
/* check for overflow by comparing sign bits */
if ((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
&& (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (lval & LONG_SIGN_MASK)) {
ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
} else {
ZVAL_LONG(result, lval);
}
case TYPE_PAIR(IS_LONG, IS_LONG):
fast_long_sub_function(result, op1, op2);
return SUCCESS;
}
case TYPE_PAIR(IS_LONG, IS_DOUBLE):
ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
return SUCCESS;

View file

@ -456,7 +456,7 @@ static zend_always_inline void fast_long_increment_function(zval *op1)
: "r"(&op1->value),
"n"(IS_DOUBLE),
"n"(ZVAL_OFFSETOF_TYPE)
: "cc");
: "cc", "memory");
#elif defined(__GNUC__) && defined(__x86_64__)
__asm__(
"incq (%0)\n\t"
@ -469,7 +469,7 @@ static zend_always_inline void fast_long_increment_function(zval *op1)
: "r"(&op1->value),
"n"(IS_DOUBLE),
"n"(ZVAL_OFFSETOF_TYPE)
: "cc");
: "cc", "memory");
#else
if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MAX)) {
/* switch to double */
@ -494,7 +494,7 @@ static zend_always_inline void fast_long_decrement_function(zval *op1)
: "r"(&op1->value),
"n"(IS_DOUBLE),
"n"(ZVAL_OFFSETOF_TYPE)
: "cc");
: "cc", "memory");
#elif defined(__GNUC__) && defined(__x86_64__)
__asm__(
"decq (%0)\n\t"
@ -507,7 +507,7 @@ static zend_always_inline void fast_long_decrement_function(zval *op1)
: "r"(&op1->value),
"n"(IS_DOUBLE),
"n"(ZVAL_OFFSETOF_TYPE)
: "cc");
: "cc", "memory");
#else
if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MIN)) {
/* switch to double */
@ -542,7 +542,7 @@ static zend_always_inline void fast_long_add_function(zval *result, zval *op1, z
"n"(IS_LONG),
"n"(IS_DOUBLE),
"n"(ZVAL_OFFSETOF_TYPE)
: "eax","cc");
: "eax","cc", "memory");
#elif defined(__GNUC__) && defined(__x86_64__)
__asm__(
"movq (%1), %%rax\n\t"
@ -565,7 +565,7 @@ static zend_always_inline void fast_long_add_function(zval *result, zval *op1, z
"n"(IS_LONG),
"n"(IS_DOUBLE),
"n"(ZVAL_OFFSETOF_TYPE)
: "rax","cc");
: "rax","cc", "memory");
#else
/*
* 'result' may alias with op1 or op2, so we need to
@ -632,7 +632,7 @@ static zend_always_inline void fast_long_sub_function(zval *result, zval *op1, z
"n"(IS_LONG),
"n"(IS_DOUBLE),
"n"(ZVAL_OFFSETOF_TYPE)
: "eax","cc");
: "eax","cc", "memory");
#elif defined(__GNUC__) && defined(__x86_64__)
__asm__(
"movq (%1), %%rax\n\t"
@ -659,7 +659,7 @@ static zend_always_inline void fast_long_sub_function(zval *result, zval *op1, z
"n"(IS_LONG),
"n"(IS_DOUBLE),
"n"(ZVAL_OFFSETOF_TYPE)
: "rax","cc");
: "rax","cc", "memory");
#else
ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));