diff options
author | Segher Boessenkool <segher@kernel.crashing.org> | 2016-11-29 02:48:30 +0100 |
---|---|---|
committer | Segher Boessenkool <segher@gcc.gnu.org> | 2016-11-29 02:48:30 +0100 |
commit | 48cf0e51e9cd4a78488dc216ed6f190df4c5b481 (patch) | |
tree | 2c9d73fb0ca8669cbec06f9357fe5860c278ac14 /gcc/simplify-rtx.c | |
parent | deb2bb610eae556f5337458b1ac14fdf95a4e070 (diff) | |
download | gcc-48cf0e51e9cd4a78488dc216ed6f190df4c5b481.zip gcc-48cf0e51e9cd4a78488dc216ed6f190df4c5b481.tar.gz gcc-48cf0e51e9cd4a78488dc216ed6f190df4c5b481.tar.bz2 |
simplify-rtx: Handle truncate of extract
simplify_truncation changes the truncation of many operations into
the operation on the truncation. This patch makes this code also
handle extracts.
* simplify-rtx.c (simplify_truncation): Handle truncate of zero_extract
and sign_extract.
From-SVN: r242946
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r-- | gcc/simplify-rtx.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 83fb37d..7778db5 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -747,6 +747,36 @@ simplify_truncation (machine_mode mode, rtx op, } } + /* Turn (truncate:M1 (*_extract:M2 (reg:M2) (len) (pos))) into + (*_extract:M1 (truncate:M1 (reg:M2)) (len) (pos')) if possible without + changing len. */ + if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT) + && REG_P (XEXP (op, 0)) + && CONST_INT_P (XEXP (op, 1)) + && CONST_INT_P (XEXP (op, 2))) + { + rtx op0 = XEXP (op, 0); + unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1)); + unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2)); + if (BITS_BIG_ENDIAN && pos >= op_precision - precision) + { + op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0)); + if (op0) + { + pos -= op_precision - precision; + return simplify_gen_ternary (GET_CODE (op), mode, mode, op0, + XEXP (op, 1), GEN_INT (pos)); + } + } + else if (!BITS_BIG_ENDIAN && precision >= len + pos) + { + op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0)); + if (op0) + return simplify_gen_ternary (GET_CODE (op), mode, mode, op0, + XEXP (op, 1), XEXP (op, 2)); + } + } + /* Recognize a word extraction from a multi-word subreg. */ if ((GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ASHIFTRT) |