diff options
author | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-09-18 01:09:40 +0000 |
---|---|---|
committer | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-09-18 01:09:40 +0000 |
commit | dc77d5c5c908baeac52de1a267398b6210e69098 (patch) | |
tree | c0cfca6716c8f6cbcceac8450b8516d949cd8c34 /gcc/expr.c | |
parent | 1689eae17d5da8b2a4e16e3c6a3cdaac688a27ef (diff) | |
download | gcc-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.c | 45 |
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)) |