diff options
author | paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-01 21:53:07 +0000 |
---|---|---|
committer | paolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-08-01 21:53:07 +0000 |
commit | 2fa63533bafde2e69dda053d1b5eb0bc7403d601 (patch) | |
tree | b283fc957cb0e873ede675b16d01fe03cbf1bd48 /gcc/hwint.c | |
parent | c5a7bf9e4210918a6d64282bd3f9b58c5b92ee1c (diff) | |
download | gcc-2fa63533bafde2e69dda053d1b5eb0bc7403d601.tar.gz |
2011-08-01 Sebastian Pop <sebastian.pop@amd.com>
Joseph Myers <joseph@codesourcery.com>
* Makefile.in (hwint.o): Depend on DIAGNOSTIC_CORE_H.
* hwint.c: Include diagnostic-core.h.
(abs_hwi): New.
(gcd): Moved here...
(pos_mul_hwi): New.
(mul_hwi): New.
(least_common_multiple): Moved here...
* hwint.h (gcd): ... from here.
(least_common_multiple): ... from here.
(HOST_WIDE_INT_MIN): New.
(HOST_WIDE_INT_MAX): New.
(abs_hwi): Declared.
(gcd): Declared.
(pos_mul_hwi): Declared.
(mul_hwi): Declared.
(least_common_multiple): Declared.
* omega.c (check_pos_mul): Removed.
(check_mul): Removed.
(omega_solve_geq): Use pos_mul_hwi instead of check_pos_mul and
mul_hwi instead of check_mul.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@177075 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/hwint.c')
-rw-r--r-- | gcc/hwint.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/gcc/hwint.c b/gcc/hwint.c index 85c1326bdde..a128dc134f9 100644 --- a/gcc/hwint.c +++ b/gcc/hwint.c @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" +#include "diagnostic-core.h" #if GCC_VERSION < 3004 @@ -98,3 +99,76 @@ ffs_hwi (unsigned HOST_WIDE_INT x) } #endif /* GCC_VERSION < 3004 */ + +/* Compute the absolute value of X. */ + +HOST_WIDE_INT +abs_hwi (HOST_WIDE_INT x) +{ + gcc_checking_assert (x != HOST_WIDE_INT_MIN); + return x >= 0 ? x : -x; +} + +/* Compute the greatest common divisor of two numbers A and B using + Euclid's algorithm. */ + +HOST_WIDE_INT +gcd (HOST_WIDE_INT a, HOST_WIDE_INT b) +{ + HOST_WIDE_INT x, y, z; + + x = abs_hwi (a); + y = abs_hwi (b); + + while (x > 0) + { + z = y % x; + y = x; + x = z; + } + + return y; +} + +/* For X and Y positive integers, return X multiplied by Y and check + that the result does not overflow. */ + +HOST_WIDE_INT +pos_mul_hwi (HOST_WIDE_INT x, HOST_WIDE_INT y) +{ + if (x != 0) + gcc_checking_assert ((HOST_WIDE_INT_MAX) / x >= y); + + return x * y; +} + +/* Return X multiplied by Y and check that the result does not + overflow. */ + +HOST_WIDE_INT +mul_hwi (HOST_WIDE_INT x, HOST_WIDE_INT y) +{ + gcc_checking_assert (x != HOST_WIDE_INT_MIN + && y != HOST_WIDE_INT_MIN); + + if (x >= 0) + { + if (y >= 0) + return pos_mul_hwi (x, y); + + return -pos_mul_hwi (x, -y); + } + + if (y >= 0) + return -pos_mul_hwi (-x, y); + + return pos_mul_hwi (-x, -y); +} + +/* Compute the least common multiple of two numbers A and B . */ + +HOST_WIDE_INT +least_common_multiple (HOST_WIDE_INT a, HOST_WIDE_INT b) +{ + return mul_hwi (abs_hwi (a) / gcd (a, b), abs_hwi (b)); +} |