com php-src: Added ARM accelerated implementations for ZEND_SIGNED_MULTIPLY_LONG(): Zend/zend_multiply .h
| From: | Ard Biesheuvel | Date: | Thu, 17 Jan 2013 17:04:05 +0000 |
| Subject: | com php-src: Added ARM accelerated implementations for ZEND_SIGNED_MULTIPLY_LONG(): Zend/zend_multiply .h | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-71011@lists.php.net to get a copy of this message | ||
Commit: 0b8ec19629083de65310f0a136320e8e79a1c8ef
Author: Ard Biesheuvel <ard.biesheuvel@linaro.org> Thu, 17 Jan 2013 17:51:12 +0100
Parents: abb12f5d7b82c40bc11eb374130e1607fad76d31
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=0b8ec19629083de65310f0a136320e8e79a1c8ef
Log:
Added ARM accelerated implementations for ZEND_SIGNED_MULTIPLY_LONG()
Added inline assembler implementations:
- for 32-bit ARM, as the existing C implementation uses 64-bit
integer arithmetic, which relies on software emulation by libgcc;
- for 64-bit ARM, as the existing C implementation uses long doubles
to check for overflow before using the integer result.
Also updated my email address and fixed some whitespace
Changed paths:
M Zend/zend_multiply.h
Diff:
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h
index c3c9657..e52956f 100644
--- a/Zend/zend_multiply.h
+++ b/Zend/zend_multiply.h
@@ -13,7 +13,7 @@
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Sascha Schumann <sascha@schumann.cx> |
- | Ard Biesheuvel <ard@ard.nu> |
+ | Ard Biesheuvel <ard.biesheuvel@linaro.org> |
+----------------------------------------------------------------------+
*/
@@ -43,6 +43,31 @@
else (lval) = __tmpvar; \
} while (0)
+#elif defined(__arm__) && defined(__GNUC__)
+
+#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
+ long __tmpvar; \
+ __asm__("smull %0, %1, %2, %3\n" \
+ "sub %1, %1, %0, asr #31" \
+ : "=r"(__tmpvar), "=r"(usedval) \
+ : "r"(a), "r"(b)); \
+ if (usedval) (dval) = (double) (a) * (double) (b); \
+ else (lval) = __tmpvar; \
+} while (0)
+
+#elif defined(__aarch64__) && defined(__GNUC__)
+
+#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
+ long __tmpvar; \
+ __asm__("mul %0, %2, %3\n" \
+ "smulh %1, %2, %3\n" \
+ "sub %1, %1, %0, asr #63\n" \
+ : "=X"(__tmpvar), "=X"(usedval) \
+ : "X"(a), "X"(b)); \
+ if (usedval) (dval) = (double) (a) * (double) (b); \
+ else (lval) = __tmpvar; \
+} while (0)
+
#elif SIZEOF_LONG == 4 && defined(HAVE_ZEND_LONG64)
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
@@ -58,15 +83,15 @@
#else
-#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
- long __lres = (a) * (b); \
- long double __dres = (long double)(a) * (long double)(b); \
- long double __delta = (long double) __lres - __dres; \
- if ( ((usedval) = (( __dres + __delta ) != __dres))) { \
- (dval) = __dres; \
- } else { \
- (lval) = __lres; \
- } \
+#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
+ long __lres = (a) * (b); \
+ long double __dres = (long double)(a) * (long double)(b); \
+ long double __delta = (long double) __lres - __dres; \
+ if ( ((usedval) = (( __dres + __delta ) != __dres))) { \
+ (dval) = __dres; \
+ } else { \
+ (lval) = __lres; \
+ } \
} while (0)
#endif