diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2013-02-11 13:53:27 +0100 |
---|---|---|
committer | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2013-02-11 13:53:27 +0100 |
commit | aa12cdc361b29b4050676763858b3cfa637be6cb (patch) | |
tree | b3a0a43d417221a0de5da89b6e8dc73ff2597f40 /Zend | |
parent | 5bfdf4f069975514a358473f7e7fee3710e50597 (diff) | |
download | php-git-aa12cdc361b29b4050676763858b3cfa637be6cb.tar.gz |
Improve x86 inline assembler
- added cc annotation to inline asm that clobbers the condition
flags
- remove hardcoded constants (IS_LONG,IS_DOUBLE)
- remove hardcoded offsets (zval->value, zval->type)
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend_alloc.c | 10 | ||||
-rw-r--r-- | Zend/zend_operators.h | 92 |
2 files changed, 65 insertions, 37 deletions
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 1cc2c67833..98ab6bea36 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -667,12 +667,12 @@ static inline unsigned int zend_mm_high_bit(size_t _size) #if defined(__GNUC__) && (defined(__native_client__) || defined(i386)) unsigned int n; - __asm__("bsrl %1,%0\n\t" : "=r" (n) : "rm" (_size)); + __asm__("bsrl %1,%0\n\t" : "=r" (n) : "rm" (_size) : "cc"); return n; #elif defined(__GNUC__) && defined(__x86_64__) unsigned long n; - __asm__("bsrq %1,%0\n\t" : "=r" (n) : "rm" (_size)); + __asm__("bsrq %1,%0\n\t" : "=r" (n) : "rm" (_size) : "cc"); return (unsigned int)n; #elif defined(_MSC_VER) && defined(_M_IX86) __asm { @@ -693,17 +693,17 @@ static inline unsigned int zend_mm_low_bit(size_t _size) #if defined(__GNUC__) && (defined(__native_client__) || defined(i386)) unsigned int n; - __asm__("bsfl %1,%0\n\t" : "=r" (n) : "rm" (_size)); + __asm__("bsfl %1,%0\n\t" : "=r" (n) : "rm" (_size) : "cc"); return n; #elif defined(__GNUC__) && defined(__x86_64__) unsigned long n; - __asm__("bsfq %1,%0\n\t" : "=r" (n) : "rm" (_size)); + __asm__("bsfq %1,%0\n\t" : "=r" (n) : "rm" (_size) : "cc"); return (unsigned int)n; #elif defined(_MSC_VER) && defined(_M_IX86) __asm { bsf eax, _size - } + } #else static const int offset[16] = {4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0}; unsigned int n; diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index e395fd39cc..93c60e4901 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -477,6 +477,10 @@ ZEND_API void zend_update_current_locale(void); #define zend_update_current_locale() #endif +/* The offset in bytes between the value and type fields of a zval */ +#define ZVAL_OFFSETOF_TYPE \ + (__builtin_offsetof(zval,type) - __builtin_offsetof(zval,value)) + static zend_always_inline int fast_increment_function(zval *op1) { if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { @@ -486,20 +490,26 @@ static zend_always_inline int fast_increment_function(zval *op1) "jno 0f\n\t" "movl $0x0, (%0)\n\t" "movl $0x41e00000, 0x4(%0)\n\t" - "movb $0x2,0xc(%0)\n" + "movb %1, %c2(%0)\n" "0:" : - : "r"(op1)); + : "r"(&op1->value), + "n"(IS_DOUBLE), + "n"(ZVAL_OFFSETOF_TYPE) + : "cc"); #elif defined(__GNUC__) && defined(__x86_64__) __asm__( "incq (%0)\n\t" "jno 0f\n\t" "movl $0x0, (%0)\n\t" "movl $0x43e00000, 0x4(%0)\n\t" - "movb $0x2,0x14(%0)\n" + "movb %1, %c2(%0)\n" "0:" : - : "r"(op1)); + : "r"(&op1->value), + "n"(IS_DOUBLE), + "n"(ZVAL_OFFSETOF_TYPE) + : "cc"); #else if (UNEXPECTED(Z_LVAL_P(op1) == LONG_MAX)) { /* switch to double */ @@ -523,20 +533,26 @@ static zend_always_inline int fast_decrement_function(zval *op1) "jno 0f\n\t" "movl $0x00200000, (%0)\n\t" "movl $0xc1e00000, 0x4(%0)\n\t" - "movb $0x2,0xc(%0)\n" + "movb %1,%c2(%0)\n" "0:" : - : "r"(op1)); + : "r"(&op1->value), + "n"(IS_DOUBLE), + "n"(ZVAL_OFFSETOF_TYPE) + : "cc"); #elif defined(__GNUC__) && defined(__x86_64__) __asm__( "decq (%0)\n\t" "jno 0f\n\t" "movl $0x00000000, (%0)\n\t" "movl $0xc3e00000, 0x4(%0)\n\t" - "movb $0x2,0x14(%0)\n" + "movb %1,%c2(%0)\n" "0:" : - : "r"(op1)); + : "r"(&op1->value), + "n"(IS_DOUBLE), + "n"(ZVAL_OFFSETOF_TYPE) + : "cc"); #else if (UNEXPECTED(Z_LVAL_P(op1) == LONG_MIN)) { /* switch to double */ @@ -561,40 +577,46 @@ static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *o "addl (%2), %%eax\n\t" "jo 0f\n\t" "movl %%eax, (%0)\n\t" - "movb $0x1,0xc(%0)\n\t" + "movb %3, %c5(%0)\n\t" "jmp 1f\n" "0:\n\t" "fildl (%1)\n\t" "fildl (%2)\n\t" "faddp %%st, %%st(1)\n\t" - "movb $0x2,0xc(%0)\n\t" + "movb %4, %c5(%0)\n\t" "fstpl (%0)\n" "1:" : - : "r"(result), - "r"(op1), - "r"(op2) - : "eax"); + : "r"(&result->value), + "r"(&op1->value), + "r"(&op2->value), + "n"(IS_LONG), + "n"(IS_DOUBLE), + "n"(ZVAL_OFFSETOF_TYPE) + : "eax","cc"); #elif defined(__GNUC__) && defined(__x86_64__) __asm__( "movq (%1), %%rax\n\t" "addq (%2), %%rax\n\t" "jo 0f\n\t" "movq %%rax, (%0)\n\t" - "movb $0x1,0x14(%0)\n\t" + "movb %3, %c5(%0)\n\t" "jmp 1f\n" "0:\n\t" "fildq (%1)\n\t" "fildq (%2)\n\t" "faddp %%st, %%st(1)\n\t" - "movb $0x2,0x14(%0)\n\t" + "movb %4, %c5(%0)\n\t" "fstpl (%0)\n" "1:" : - : "r"(result), - "r"(op1), - "r"(op2) - : "rax"); + : "r"(&result->value), + "r"(&op1->value), + "r"(&op2->value), + "n"(IS_LONG), + "n"(IS_DOUBLE), + "n"(ZVAL_OFFSETOF_TYPE) + : "rax","cc"); #else Z_LVAL_P(result) = Z_LVAL_P(op1) + Z_LVAL_P(op2); @@ -636,7 +658,7 @@ static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *o "subl (%2), %%eax\n\t" "jo 0f\n\t" "movl %%eax, (%0)\n\t" - "movb $0x1,0xc(%0)\n\t" + "movb %3, %c5(%0)\n\t" "jmp 1f\n" "0:\n\t" "fildl (%2)\n\t" @@ -646,21 +668,24 @@ static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *o #else "fsubp %%st, %%st(1)\n\t" #endif - "movb $0x2,0xc(%0)\n\t" + "movb %4, %c5(%0)\n\t" "fstpl (%0)\n" "1:" : - : "r"(result), - "r"(op1), - "r"(op2) - : "eax"); + : "r"(&result->value), + "r"(&op1->value), + "r"(&op2->value), + "n"(IS_LONG), + "n"(IS_DOUBLE), + "n"(ZVAL_OFFSETOF_TYPE) + : "eax","cc"); #elif defined(__GNUC__) && defined(__x86_64__) __asm__( "movq (%1), %%rax\n\t" "subq (%2), %%rax\n\t" "jo 0f\n\t" "movq %%rax, (%0)\n\t" - "movb $0x1,0x14(%0)\n\t" + "movb %3, %c5(%0)\n\t" "jmp 1f\n" "0:\n\t" "fildq (%2)\n\t" @@ -670,14 +695,17 @@ static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *o #else "fsubp %%st, %%st(1)\n\t" #endif - "movb $0x2,0x14(%0)\n\t" + "movb %4, %c5(%0)\n\t" "fstpl (%0)\n" "1:" : - : "r"(result), - "r"(op1), - "r"(op2) - : "rax"); + : "r"(&result->value), + "r"(&op1->value), + "r"(&op2->value), + "n"(IS_LONG), + "n"(IS_DOUBLE), + "n"(ZVAL_OFFSETOF_TYPE) + : "rax","cc"); #else Z_LVAL_P(result) = Z_LVAL_P(op1) - Z_LVAL_P(op2); |