1: /*
2: +----------------------------------------------------------------------+
3: | Zend Engine |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
6: +----------------------------------------------------------------------+
7: | This source file is subject to version 2.00 of the Zend license, |
8: | that is bundled with this package in the file LICENSE, and is |
9: | available through the world-wide-web at the following url: |
10: | http://www.zend.com/license/2_00.txt. |
11: | If you did not receive a copy of the Zend license and are unable to |
12: | obtain it through the world-wide-web, please send a note to |
13: | license@zend.com so we can mail you a copy immediately. |
14: +----------------------------------------------------------------------+
15: | Authors: Sascha Schumann <sascha@schumann.cx> |
16: | Ard Biesheuvel <ard@ard.nu> |
17: +----------------------------------------------------------------------+
18: */
19:
20: /* $Id: zend_multiply.h,v 1.1.1.4 2014/06/15 20:04:04 misho Exp $ */
21:
22: #if defined(__i386__) && defined(__GNUC__)
23:
24: #define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
25: long __tmpvar; \
26: __asm__ ("imul %3,%0\n" \
27: "adc $0,%1" \
28: : "=r"(__tmpvar),"=r"(usedval) \
29: : "0"(a), "r"(b), "1"(0)); \
30: if (usedval) (dval) = (double) (a) * (double) (b); \
31: else (lval) = __tmpvar; \
32: } while (0)
33:
34: #elif defined(__x86_64__) && defined(__GNUC__)
35:
36: #define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
37: long __tmpvar; \
38: __asm__ ("imul %3,%0\n" \
39: "adc $0,%1" \
40: : "=r"(__tmpvar),"=r"(usedval) \
41: : "0"(a), "r"(b), "1"(0)); \
42: if (usedval) (dval) = (double) (a) * (double) (b); \
43: else (lval) = __tmpvar; \
44: } while (0)
45:
46: #elif SIZEOF_LONG == 4 && defined(HAVE_ZEND_LONG64)
47:
48: #define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
49: zend_long64 __result = (zend_long64) (a) * (zend_long64) (b); \
50: if (__result > LONG_MAX || __result < LONG_MIN) { \
51: (dval) = (double) __result; \
52: (usedval) = 1; \
53: } else { \
54: (lval) = (long) __result; \
55: (usedval) = 0; \
56: } \
57: } while (0)
58:
59: #else
60:
61: #define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
62: long __lres = (a) * (b); \
63: long double __dres = (long double)(a) * (long double)(b); \
64: long double __delta = (long double) __lres - __dres; \
65: if ( ((usedval) = (( __dres + __delta ) != __dres))) { \
66: (dval) = __dres; \
67: } else { \
68: (lval) = __lres; \
69: } \
70: } while (0)
71:
72: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>