summaryrefslogtreecommitdiffstats
path: root/gcc/simplify-rtx.c
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-22 12:44:54 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2004-01-22 12:44:54 +0000
commitf36eb1e90c6e27ff4f72826c76afaec43219a8a8 (patch)
tree3c307eaa8d9217b307aed75ea2e9ba109fafafb0 /gcc/simplify-rtx.c
parent745f32290d2ee826d468bbad01d4bbd545ef8974 (diff)
downloadppe42-gcc-f36eb1e90c6e27ff4f72826c76afaec43219a8a8.tar.gz
ppe42-gcc-f36eb1e90c6e27ff4f72826c76afaec43219a8a8.zip
* rtlanal.c (subreg_lsb_1): New function split out from subreg_lsb.
(subreg_lsb): Change to call new subreg_lsb_1 helper function. * rtl.h (subreg_lsb_1): Prototype here. * simplify-rtx.c (simplify_subreg): Optimize subregs of zero and sign extensions. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@76352 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r--gcc/simplify-rtx.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 7272424f8cc..5ba6882e680 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -3379,10 +3379,45 @@ simplify_subreg (enum machine_mode outermode, rtx op,
res = simplify_subreg (outermode, part, GET_MODE (part), final_offset);
if (res)
return res;
- /* We can at least simplify it by referring directly to the relevant part. */
+ /* We can at least simplify it by referring directly to the
+ relevant part. */
return gen_rtx_SUBREG (outermode, part, final_offset);
}
+ /* Optimize SUBREG truncations of zero and sign extended values. */
+ if ((GET_CODE (op) == ZERO_EXTEND
+ || GET_CODE (op) == SIGN_EXTEND)
+ && GET_MODE_BITSIZE (outermode) < GET_MODE_BITSIZE (innermode))
+ {
+ unsigned int bitpos = subreg_lsb_1 (outermode, innermode, byte);
+
+ /* If we're requesting the lowpart of a zero or sign extension,
+ there are three possibilities. If the outermode is the same
+ as the origmode, we can omit both the extension and the subreg.
+ If the outermode is not larger than the origmode, we can apply
+ the truncation without the extension. Finally, if the outermode
+ is larger than the origmode, but both are integer modes, we
+ can just extend to the appropriate mode. */
+ if (bitpos == 0)
+ {
+ enum machine_mode origmode = GET_MODE (XEXP (op, 0));
+ if (outermode == origmode)
+ return XEXP (op, 0);
+ if (GET_MODE_BITSIZE (outermode) <= GET_MODE_BITSIZE (origmode))
+ return simplify_gen_subreg (outermode, XEXP (op, 0),
+ origmode, byte);
+ if (SCALAR_INT_MODE_P (outermode))
+ return simplify_gen_unary (GET_CODE (op), outermode,
+ XEXP (op, 0), origmode);
+ }
+
+ /* A SUBREG resulting from a zero extension may fold to zero if
+ it extracts higher bits that the ZERO_EXTEND's source bits. */
+ if (GET_CODE (op) == ZERO_EXTEND
+ && bitpos >= GET_MODE_BITSIZE (GET_MODE (XEXP (op, 0))))
+ return CONST0_RTX (outermode);
+ }
+
return NULL_RTX;
}
OpenPOWER on IntegriCloud