summaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2008-09-18 01:09:40 +0000
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2008-09-18 01:09:40 +0000
commitdc77d5c5c908baeac52de1a267398b6210e69098 (patch)
treec0cfca6716c8f6cbcceac8450b8516d949cd8c34 /gcc/expr.c
parent1689eae17d5da8b2a4e16e3c6a3cdaac688a27ef (diff)
downloadgcc-dc77d5c5c908baeac52de1a267398b6210e69098.tar.gz
* expr.c (emit_group_store): Do not shift before moving via a
stack slot. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140442 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c45
1 files changed, 25 insertions, 20 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index f2e9c79abf2..ae0daf0b251 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2039,33 +2039,17 @@ emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED, int ssize)
HOST_WIDE_INT bytepos = INTVAL (XEXP (XVECEXP (src, 0, i), 1));
enum machine_mode mode = GET_MODE (tmps[i]);
unsigned int bytelen = GET_MODE_SIZE (mode);
+ unsigned int adj_bytelen = bytelen;
rtx dest = dst;
/* Handle trailing fragments that run over the size of the struct. */
if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
- {
- /* store_bit_field always takes its value from the lsb.
- Move the fragment to the lsb if it's not already there. */
- if (
-#ifdef BLOCK_REG_PADDING
- BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
- == (BYTES_BIG_ENDIAN ? upward : downward)
-#else
- BYTES_BIG_ENDIAN
-#endif
- )
- {
- int shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
- tmps[i] = expand_shift (RSHIFT_EXPR, mode, tmps[i],
- build_int_cst (NULL_TREE, shift),
- tmps[i], 0);
- }
- bytelen = ssize - bytepos;
- }
+ adj_bytelen = ssize - bytepos;
if (GET_CODE (dst) == CONCAT)
{
- if (bytepos + bytelen <= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0))))
+ if (bytepos + adj_bytelen
+ <= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0))))
dest = XEXP (dst, 0);
else if (bytepos >= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0))))
{
@@ -2103,6 +2087,27 @@ emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED, int ssize)
}
}
+ if (ssize >= 0 && bytepos + (HOST_WIDE_INT) bytelen > ssize)
+ {
+ /* store_bit_field always takes its value from the lsb.
+ Move the fragment to the lsb if it's not already there. */
+ if (
+#ifdef BLOCK_REG_PADDING
+ BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
+ == (BYTES_BIG_ENDIAN ? upward : downward)
+#else
+ BYTES_BIG_ENDIAN
+#endif
+ )
+ {
+ int shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
+ tmps[i] = expand_shift (RSHIFT_EXPR, mode, tmps[i],
+ build_int_cst (NULL_TREE, shift),
+ tmps[i], 0);
+ }
+ bytelen = adj_bytelen;
+ }
+
/* Optimize the access just a bit. */
if (MEM_P (dest)
&& (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (dest))