===================================================================
@@ -551,19 +551,27 @@ store_bit_field_1 (rtx str_rtx, unsigned
/* If I is 0, use the low-order word in both field and target;
if I is 1, use the next to lowest word; and so on. */
unsigned int wordnum = (backwards ? nwords - i - 1 : i);
+ unsigned int nbits = (i == nwords - 1
+ ? bitsize - i * BITS_PER_WORD
+ : BITS_PER_WORD);
unsigned int bit_offset = (backwards
- ? MAX ((int) bitsize - ((int) i + 1)
- * BITS_PER_WORD,
- 0)
- : (int) i * BITS_PER_WORD);
+ ? bitsize - i * BITS_PER_WORD - nbits
+ : 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),
- bitnum + bit_offset,
+ if (WORDS_BIG_ENDIAN && !backwards && nbits != BITS_PER_WORD)
+ {
+ /* Original fieldmode was BLKmode. The value in this
+ case consists of bits in memory order, so any unused
+ bits in the last word are in the least significant
+ position. */
+ value_word = expand_shift (RSHIFT_EXPR, word_mode, value_word,
+ BITS_PER_WORD - nbits,
+ value_word, 1);
+ }
+ if (!store_bit_field_1 (op0, nbits, bitnum + bit_offset,
bitregion_start, bitregion_end,
- word_mode,
- value_word, fallback_p))
+ word_mode, value_word, fallback_p))
{
delete_insns_since (last);
return false;