1 /* Operations on HOST_WIDE_INT.
2 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "diagnostic-core.h"
26 #if GCC_VERSION < 3004
28 /* The functions clz_hwi, ctz_hwi, ffs_hwi, floor_log2, ceil_log2,
29 and exact_log2 are defined as inline functions in hwint.h
30 if GCC_VERSION >= 3004.
31 The definitions here are used for older versions of GCC and
32 non-GCC bootstrap compilers. */
34 /* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
35 If X is 0, return -1. */
38 floor_log2 (unsigned HOST_WIDE_INT x
)
45 if (HOST_BITS_PER_WIDE_INT
> 64)
46 if (x
>= (unsigned HOST_WIDE_INT
) 1 << (t
+ 64))
48 if (HOST_BITS_PER_WIDE_INT
> 32)
49 if (x
>= ((unsigned HOST_WIDE_INT
) 1) << (t
+ 32))
51 if (x
>= ((unsigned HOST_WIDE_INT
) 1) << (t
+ 16))
53 if (x
>= ((unsigned HOST_WIDE_INT
) 1) << (t
+ 8))
55 if (x
>= ((unsigned HOST_WIDE_INT
) 1) << (t
+ 4))
57 if (x
>= ((unsigned HOST_WIDE_INT
) 1) << (t
+ 2))
59 if (x
>= ((unsigned HOST_WIDE_INT
) 1) << (t
+ 1))
65 /* Given X, an unsigned number, return the largest Y such that 2**Y >= X. */
68 ceil_log2 (unsigned HOST_WIDE_INT x
)
70 return floor_log2 (x
- 1) + 1;
73 /* Return the logarithm of X, base 2, considering X unsigned,
74 if X is a power of 2. Otherwise, returns -1. */
77 exact_log2 (unsigned HOST_WIDE_INT x
)
81 return floor_log2 (x
);
84 /* Given X, an unsigned number, return the number of least significant bits
85 that are zero. When X == 0, the result is the word size. */
88 ctz_hwi (unsigned HOST_WIDE_INT x
)
90 return x
? floor_log2 (x
& -x
) : HOST_BITS_PER_WIDE_INT
;
93 /* Similarly for most significant bits. */
96 clz_hwi (unsigned HOST_WIDE_INT x
)
98 return HOST_BITS_PER_WIDE_INT
- 1 - floor_log2(x
);
101 /* Similar to ctz_hwi, except that the least significant bit is numbered
102 starting from 1, and X == 0 yields 0. */
105 ffs_hwi (unsigned HOST_WIDE_INT x
)
107 return 1 + floor_log2 (x
& -x
);
110 /* Return the number of set bits in X. */
113 popcount_hwi (unsigned HOST_WIDE_INT x
)
117 for (i
= 0; i
< sizeof (x
); i
+= 1)
126 #endif /* GCC_VERSION < 3004 */
128 /* Compute the absolute value of X. */
131 abs_hwi (HOST_WIDE_INT x
)
133 gcc_checking_assert (x
!= HOST_WIDE_INT_MIN
);
134 return x
>= 0 ? x
: -x
;
137 /* Compute the absolute value of X as an unsigned type. */
139 unsigned HOST_WIDE_INT
140 absu_hwi (HOST_WIDE_INT x
)
142 return x
>= 0 ? (unsigned HOST_WIDE_INT
)x
: -(unsigned HOST_WIDE_INT
)x
;
145 /* Compute the greatest common divisor of two numbers A and B using
146 Euclid's algorithm. */
149 gcd (HOST_WIDE_INT a
, HOST_WIDE_INT b
)
151 HOST_WIDE_INT x
, y
, z
;
166 /* For X and Y positive integers, return X multiplied by Y and check
167 that the result does not overflow. */
170 pos_mul_hwi (HOST_WIDE_INT x
, HOST_WIDE_INT y
)
173 gcc_checking_assert ((HOST_WIDE_INT_MAX
) / x
>= y
);
178 /* Return X multiplied by Y and check that the result does not
182 mul_hwi (HOST_WIDE_INT x
, HOST_WIDE_INT y
)
184 gcc_checking_assert (x
!= HOST_WIDE_INT_MIN
185 && y
!= HOST_WIDE_INT_MIN
);
190 return pos_mul_hwi (x
, y
);
192 return -pos_mul_hwi (x
, -y
);
196 return -pos_mul_hwi (-x
, y
);
198 return pos_mul_hwi (-x
, -y
);
201 /* Compute the least common multiple of two numbers A and B . */
204 least_common_multiple (HOST_WIDE_INT a
, HOST_WIDE_INT b
)
206 return mul_hwi (abs_hwi (a
) / gcd (a
, b
), abs_hwi (b
));