rtlanal.c (lsb_bitfield_op_p): New predicate for bitfield operations from the least significant bit.
2013-09-25 Yvan Roux <yvan.roux@linaro.org> Vladimir Makarov <vmakarov@redhat.com> * rtlanal.c (lsb_bitfield_op_p): New predicate for bitfield operations from the least significant bit. (strip_address_mutations): Add bitfield operations handling. (must_be_index_p): Add shifting and rotate operations handling. (set_address_base): Use must_be_base_p predicate. (set_address_index):Use must_be_index_p predicate. Co-Authored-By: Vladimir Makarov <vmakarov@redhat.com> From-SVN: r202914
This commit is contained in:
parent
b86f6e9e46
commit
3936bafc7e
@ -1,3 +1,13 @@
|
||||
2013-09-25 Yvan Roux <yvan.roux@linaro.org>
|
||||
Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
* rtlanal.c (lsb_bitfield_op_p): New predicate for bitfield operations
|
||||
from the least significant bit.
|
||||
(strip_address_mutations): Add bitfield operations handling.
|
||||
(must_be_index_p): Add shifting and rotate operations handling.
|
||||
(set_address_base): Use must_be_base_p predicate.
|
||||
(set_address_index):Use must_be_index_p predicate.
|
||||
|
||||
2013-09-25 Alexander Ivchenko <alexander.ivchenko@intel.com>
|
||||
Maxim Kuznetsov <maxim.kuznetsov@intel.com>
|
||||
Sergey Lega <sergey.s.lega@intel.com>
|
||||
|
@ -5467,12 +5467,29 @@ split_double (rtx value, rtx *first, rtx *second)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if X is a sign_extract or zero_extract from the least
|
||||
significant bit. */
|
||||
|
||||
static bool
|
||||
lsb_bitfield_op_p (rtx x)
|
||||
{
|
||||
if (GET_RTX_CLASS (GET_CODE (x)) == RTX_BITFIELD_OPS)
|
||||
{
|
||||
enum machine_mode mode = GET_MODE (XEXP (x, 0));
|
||||
unsigned HOST_WIDE_INT len = INTVAL (XEXP (x, 1));
|
||||
HOST_WIDE_INT pos = INTVAL (XEXP (x, 2));
|
||||
|
||||
return (pos == (BITS_BIG_ENDIAN ? GET_MODE_PRECISION (mode) - len : 0));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Strip outer address "mutations" from LOC and return a pointer to the
|
||||
inner value. If OUTER_CODE is nonnull, store the code of the innermost
|
||||
stripped expression there.
|
||||
|
||||
"Mutations" either convert between modes or apply some kind of
|
||||
alignment. */
|
||||
extension, truncation or alignment. */
|
||||
|
||||
rtx *
|
||||
strip_address_mutations (rtx *loc, enum rtx_code *outer_code)
|
||||
@ -5484,6 +5501,10 @@ strip_address_mutations (rtx *loc, enum rtx_code *outer_code)
|
||||
/* Things like SIGN_EXTEND, ZERO_EXTEND and TRUNCATE can be
|
||||
used to convert between pointer sizes. */
|
||||
loc = &XEXP (*loc, 0);
|
||||
else if (lsb_bitfield_op_p (*loc))
|
||||
/* A [SIGN|ZERO]_EXTRACT from the least significant bit effectively
|
||||
acts as a combined truncation and extension. */
|
||||
loc = &XEXP (*loc, 0);
|
||||
else if (code == AND && CONST_INT_P (XEXP (*loc, 1)))
|
||||
/* (and ... (const_int -X)) is used to align to X bytes. */
|
||||
loc = &XEXP (*loc, 0);
|
||||
@ -5513,7 +5534,13 @@ must_be_base_p (rtx x)
|
||||
static bool
|
||||
must_be_index_p (rtx x)
|
||||
{
|
||||
return GET_CODE (x) == MULT || GET_CODE (x) == ASHIFT;
|
||||
return (GET_CODE (x) == MULT
|
||||
|| GET_CODE (x) == ASHIFT
|
||||
/* Needed by ARM targets. */
|
||||
|| GET_CODE (x) == ASHIFTRT
|
||||
|| GET_CODE (x) == LSHIFTRT
|
||||
|| GET_CODE (x) == ROTATE
|
||||
|| GET_CODE (x) == ROTATERT);
|
||||
}
|
||||
|
||||
/* Set the segment part of address INFO to LOC, given that INNER is the
|
||||
@ -5535,7 +5562,7 @@ set_address_segment (struct address_info *info, rtx *loc, rtx *inner)
|
||||
static void
|
||||
set_address_base (struct address_info *info, rtx *loc, rtx *inner)
|
||||
{
|
||||
if (GET_CODE (*inner) == LO_SUM)
|
||||
if (must_be_base_p (*inner))
|
||||
inner = strip_address_mutations (&XEXP (*inner, 0));
|
||||
gcc_checking_assert (REG_P (*inner)
|
||||
|| MEM_P (*inner)
|
||||
@ -5552,8 +5579,7 @@ set_address_base (struct address_info *info, rtx *loc, rtx *inner)
|
||||
static void
|
||||
set_address_index (struct address_info *info, rtx *loc, rtx *inner)
|
||||
{
|
||||
if ((GET_CODE (*inner) == MULT || GET_CODE (*inner) == ASHIFT)
|
||||
&& CONSTANT_P (XEXP (*inner, 1)))
|
||||
if (must_be_index_p (*inner) && CONSTANT_P (XEXP (*inner, 1)))
|
||||
inner = strip_address_mutations (&XEXP (*inner, 0));
|
||||
gcc_checking_assert (REG_P (*inner)
|
||||
|| MEM_P (*inner)
|
||||
|
Loading…
x
Reference in New Issue
Block a user