Commit:    aa12cdc361b29b4050676763858b3cfa637be6cb
Author:    Ard Biesheuvel <ard.biesheu...@linaro.org>         Mon, 11 Feb 2013 
13:53:27 +0100
Parents:   5bfdf4f069975514a358473f7e7fee3710e50597
Branches:  master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=aa12cdc361b29b4050676763858b3cfa637be6cb

Log:
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)

Changed paths:
  M  Zend/zend_alloc.c
  M  Zend/zend_operators.h


Diff:
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
index 1cc2c67..98ab6be 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 e395fd3..93c60e4 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);


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to