summaryrefslogtreecommitdiff
path: root/Zend/zend_multiply.h
diff options
context:
space:
mode:
authorAndrea Faulds <ajf@ajf.me>2016-08-10 00:15:13 +0100
committerAndrea Faulds <ajf@ajf.me>2016-08-10 00:46:05 +0100
commit0987737397c28f8df48a5085cb0d5e857962af93 (patch)
treeb0aad0cfaae2fa9a1b799ada9715f02435444611 /Zend/zend_multiply.h
parentf41b69e814b8b23509a9c15de4fca5ea59dc80cb (diff)
downloadphp-git-0987737397c28f8df48a5085cb0d5e857962af93.tar.gz
Use checked arithmetic intrinsics instead of asm, when possible
Diffstat (limited to 'Zend/zend_multiply.h')
-rw-r--r--Zend/zend_multiply.h24
1 files changed, 23 insertions, 1 deletions
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h
index dfd21f7da3..7fb500a5f0 100644
--- a/Zend/zend_multiply.h
+++ b/Zend/zend_multiply.h
@@ -19,10 +19,32 @@
/* $Id$ */
+#include "zend_portability.h"
+
#ifndef ZEND_MULTIPLY_H
#define ZEND_MULTIPLY_H
-#if (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__)
+#if __has_builtin(__builtin_smull_overflow) && SIZEOF_LONG == SIZEOF_ZEND_LONG
+
+#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
+ long __tmpvar; \
+ if (((usedval) = __builtin_smull_overflow((a), (b), &__tmpvar))) { \
+ (dval) = (double) (a) * (double) (b); \
+ } \
+ else (lval) = __tmpvar; \
+} while (0)
+
+#elif __has_builtin(__builtin_smulll_overflow) && SIZEOF_LONG_LONG == SIZEOF_ZEND_LONG
+
+#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
+ long long __tmpvar; \
+ if (((usedval) = __builtin_smulll_overflow((a), (b), &__tmpvar))) { \
+ (dval) = (double) (a) * (double) (b); \
+ } \
+ else (lval) = __tmpvar; \
+} while (0)
+
+#elif (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__)
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
zend_long __tmpvar; \