diff options
author | Andi Gutmans <andi@php.net> | 2004-03-17 09:25:52 +0000 |
---|---|---|
committer | Andi Gutmans <andi@php.net> | 2004-03-17 09:25:52 +0000 |
commit | 29ee03aa55688ca9a6441c3aa1ed8be905830027 (patch) | |
tree | 3c6cf763687b89bb9d1d971d9dccad327058df70 /Zend/zend_multiply.h | |
parent | 8aea19c345fa9f92a8fc7b6cedcb16c9f385e1c3 (diff) | |
download | php-git-29ee03aa55688ca9a6441c3aa1ed8be905830027.tar.gz |
- Apply Ard's patch to support multiplication & overflow on both 32bit
and 64bit machines
Diffstat (limited to 'Zend/zend_multiply.h')
-rw-r--r-- | Zend/zend_multiply.h | 46 |
1 files changed, 19 insertions, 27 deletions
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h index 2e6fe6a11a..eda4ca135e 100644 --- a/Zend/zend_multiply.h +++ b/Zend/zend_multiply.h @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) 2003-2004 Sascha Schumann | + | Copyright (c) 1998-2004 Zend Technologies Ltd. (http://www.zend.com) | +----------------------------------------------------------------------+ | This source file is subject to version 2.00 of the Zend license, | | that is bundled with this package in the file LICENSE, and is | @@ -12,36 +12,28 @@ | obtain it through the world-wide-web, please send a note to | | license@zend.com so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Author: Sascha Schumann <sascha@schumann.cx> | + | Author: Ard Biesheuvel <ard@ard.nu> | +----------------------------------------------------------------------+ */ /* $Id$ */ -#if defined(__i386__) && defined(__GNUC__) +#define HALF (4*sizeof(long)) +#define UH(b) ((b) >> HALF) +#define LH(a) ((a) & ~(-1L << HALF)) -#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \ - long __tmpvar; \ - __asm__ ("imul %3,%0\n" \ - "adc $0,%1" \ - : "=r"(__tmpvar),"=r"(usedval) \ - : "0"(a), "r"(b), "1"(0)); \ - if (usedval) (dval) = (double) (a) * (double) (b); \ - else (lval) = __tmpvar; \ +#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \ + long __mid,__upr,__res = (a) * (b); \ + if (-(long)(a) > 0 && -(long)(b) > 0) { /* overflow intended */ \ + __mid = UH(-(a))*LH(-(b)) + LH(-(a))*UH(-(b)); \ + __upr = UH(-(a))*UH(-(b)) + UH(__mid); \ + } else { \ + __mid = UH(a)*LH(b) + LH(a)*UH(b); \ + __upr = UH(a)*UH(b) + UH(__mid); \ + } \ + if (((usedval) = !((__upr==-1&&__res<0)||(!__upr&&__res>=0)))) { \ + (dval) = (double)(a)*(double)(b); \ + } else { \ + (lval) = __res; \ + } \ } while (0) - -#else - -#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \ - double __tmpvar = (double) (a) * (double) (b); \ - \ - if (__tmpvar >= LONG_MAX || __tmpvar <= LONG_MIN) { \ - (dval) = __tmpvar; \ - (usedval) = 1; \ - } else { \ - (lval) = (a) * (b); \ - (usedval) = 0; \ - } \ -} while (0) - -#endif |