diff options
Diffstat (limited to 'gcc/tree.c')
-rw-r--r-- | gcc/tree.c | 34 |
1 files changed, 34 insertions, 0 deletions
@@ -609,6 +609,40 @@ build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi) return t; } +/* Builds an integer constant in TYPE such that lowest BITS bits are ones + and the rest are zeros. */ + +tree +build_low_bits_mask (tree type, unsigned bits) +{ + unsigned HOST_WIDE_INT low; + HOST_WIDE_INT high; + unsigned HOST_WIDE_INT all_ones = ~(unsigned HOST_WIDE_INT) 0; + + gcc_assert (bits <= TYPE_PRECISION (type)); + + if (bits == TYPE_PRECISION (type) + && !TYPE_UNSIGNED (type)) + { + /* Sign extended all-ones mask. */ + low = all_ones; + high = -1; + } + else if (bits <= HOST_BITS_PER_WIDE_INT) + { + low = all_ones >> (HOST_BITS_PER_WIDE_INT - bits); + high = 0; + } + else + { + bits -= HOST_BITS_PER_WIDE_INT; + low = all_ones; + high = all_ones >> (HOST_BITS_PER_WIDE_INT - bits); + } + + return build_int_cst_wide (type, low, high); +} + /* Checks that X is integer constant that can be expressed in (unsigned) HOST_WIDE_INT without loss of precision. */ |