aboutsummaryrefslogtreecommitdiff
path: root/gcc/expmed.c
diff options
context:
space:
mode:
authorAndreas Krebbel <Andreas.Krebbel@de.ibm.com>2012-01-17 20:37:46 +0000
committerRichard Sandiford <rdsandiford@googlemail.com>2012-01-17 20:37:46 +0000
commitec3eeae72c55bb2ee910ed3715ac719e030501be (patch)
tree0817497fe59c2693e5501c674272b3c4672529f3 /gcc/expmed.c
parent61594a324ac2d6623ab0c237acd892d7a2bc2495 (diff)
gcc/
2012-01-17 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> Richard Sandiford <rdsandiford@googlemail.com> PR middle-end/50325 PR middle-end/51192 * optabs.h (simplify_expand_binop): Declare. * optabs.c (simplify_expand_binop): Make global. * expmed.c (store_bit_field_1): Use simplify_expand_binop on big endian targets if the source cannot be exactly covered by word mode chunks. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@183262 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r--gcc/expmed.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c
index bced96e74d4..09a933da5f5 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -557,9 +557,21 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
0)
: (int) i * BITS_PER_WORD);
rtx value_word = operand_subword_force (value, wordnum, fieldmode);
-
- if (!store_bit_field_1 (op0, MIN (BITS_PER_WORD,
- bitsize - i * BITS_PER_WORD),
+ unsigned HOST_WIDE_INT new_bitsize =
+ MIN (BITS_PER_WORD, bitsize - i * BITS_PER_WORD);
+
+ /* If the remaining chunk doesn't have full wordsize we have
+ to make sure that for big endian machines the higher order
+ bits are used. */
+ if (new_bitsize < BITS_PER_WORD && BYTES_BIG_ENDIAN && !backwards)
+ value_word = simplify_expand_binop (word_mode, lshr_optab,
+ value_word,
+ GEN_INT (BITS_PER_WORD
+ - new_bitsize),
+ NULL_RTX, true,
+ OPTAB_LIB_WIDEN);
+
+ if (!store_bit_field_1 (op0, new_bitsize,
bitnum + bit_offset,
bitregion_start, bitregion_end,
word_mode,