diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/combine.c | 8 | ||||
-rw-r--r-- | gcc/rtl.h | 1 | ||||
-rw-r--r-- | gcc/rtlanal.c | 17 |
4 files changed, 27 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8acb3b68335..2691d51d26d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2009-08-11 Adam Nemet <anemet@caviumnetworks.com> + + * combine.c (try_widen_shift_mode): Factor out code to check if an + integer constant is a low-order bitmask from here ... + * rtlanal.c (low_bitmask_len): ... to here. + * rtl.h (low_bitmask_len): Declare. + 2009-08-11 Uros Bizjak <ubizjak@gmail.com> PR target/8603 diff --git a/gcc/combine.c b/gcc/combine.c index 3a2c41205e5..faa7e0dc038 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -9027,13 +9027,9 @@ try_widen_shift_mode (enum rtx_code code, rtx op, int count, /* We can also widen if the bits brought in will be masked off. This operation is performed in ORIG_MODE. */ - if (outer_code == AND - && GET_MODE_BITSIZE (orig_mode) <= HOST_BITS_PER_WIDE_INT) + if (outer_code == AND) { - int care_bits; - - outer_const &= GET_MODE_MASK (orig_mode); - care_bits = exact_log2 (outer_const + 1); + int care_bits = low_bitmask_len (orig_mode, outer_const); if (care_bits >= 0 && GET_MODE_BITSIZE (orig_mode) - care_bits >= count) diff --git a/gcc/rtl.h b/gcc/rtl.h index d5ae561d3af..cf07348a3cb 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1095,6 +1095,7 @@ extern unsigned HOST_WIDE_INT nonzero_bits (const_rtx, enum machine_mode); extern unsigned int num_sign_bit_copies (const_rtx, enum machine_mode); extern bool constant_pool_constant_p (rtx); extern bool truncated_to_mode (enum machine_mode, const_rtx); +extern int low_bitmask_len (enum machine_mode, unsigned HOST_WIDE_INT); /* 1 if RTX is a subreg containing a reg that is already known to be diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 49289b65c37..aebcfa66904 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -5032,3 +5032,20 @@ constant_pool_constant_p (rtx x) x = avoid_constant_pool_reference (x); return GET_CODE (x) == CONST_DOUBLE; } + +/* If M is a bitmask that selects a field of low-order bits within an item but + not the entire word, return the length of the field. Return -1 otherwise. + M is used in machine mode MODE. */ + +int +low_bitmask_len (enum machine_mode mode, unsigned HOST_WIDE_INT m) +{ + if (mode != VOIDmode) + { + if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT) + return -1; + m &= GET_MODE_MASK (mode); + } + + return exact_log2 (m + 1); +} |