aboutsummaryrefslogtreecommitdiff
path: root/gcc/hwint.c
diff options
context:
space:
mode:
authorSebastian Pop <sebastian.pop@amd.com>2011-08-01 21:53:07 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2011-08-01 21:53:07 +0000
commit3c67fd9c30f45017fb3b490162fce106d37b7cbe (patch)
treeb283fc957cb0e873ede675b16d01fe03cbf1bd48 /gcc/hwint.c
parent4bbff96e369cf96ee1c6bd3fd9f7728c08e05da8 (diff)
downloadgcc-3c67fd9c30f45017fb3b490162fce106d37b7cbe.zip
gcc-3c67fd9c30f45017fb3b490162fce106d37b7cbe.tar.gz
gcc-3c67fd9c30f45017fb3b490162fce106d37b7cbe.tar.bz2
Makefile.in (hwint.o): Depend on DIAGNOSTIC_CORE_H.
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. Co-Authored-By: Joseph Myers <joseph@codesourcery.com> From-SVN: r177075
Diffstat (limited to 'gcc/hwint.c')
-rw-r--r--gcc/hwint.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/gcc/hwint.c b/gcc/hwint.c
index 85c1326..a128dc1 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));
+}