diff -up ../_clean/gcc/expmed.c gcc/expmed.c --- ../_clean/gcc/expmed.c 2011-12-09 15:20:36.000000000 +0100 +++ gcc/expmed.c 2011-12-09 15:23:01.000000000 +0100 @@ -543,7 +543,8 @@ store_bit_field_1 (rtx str_rtx, unsigned is not allowed. */ fieldmode = GET_MODE (value); if (fieldmode == VOIDmode) - fieldmode = smallest_mode_for_size (nwords * BITS_PER_WORD, MODE_INT); + fieldmode = smallest_mode_for_size (nwords * + BITS_PER_WORD, MODE_INT); last = get_last_insn (); for (i = 0; i < nwords; i++) @@ -557,9 +558,21 @@ store_bit_field_1 (rtx str_rtx, unsigned 0) : (int) i * BITS_PER_WORD); rtx value_word = operand_subword_force (value, wordnum, fieldmode); + unsigned HOST_WIDE_INT new_bitsize = + MIN (BITS_PER_WORD, bitsize - i * BITS_PER_WORD); - if (!store_bit_field_1 (op0, 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, --- ../_clean/gcc/optabs.c 2011-12-23 23:39:30.000000000 +0100 +++ gcc/optabs.c 2011-12-24 18:40:01.000000000 +0100 @@ -659,7 +659,7 @@ expand_ternary_op (enum machine_mode mod calculated at compile time. The arguments and return value are otherwise the same as for expand_binop. */ -static rtx +rtx simplify_expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1, rtx target, int unsignedp, enum optab_methods methods) diff -up ../_clean/gcc/optabs.h gcc/optabs.h --- ../_clean/gcc/optabs.h 2011-12-23 23:39:30.000000000 +0100 +++ gcc/optabs.h 2011-12-24 18:40:01.000000000 +0100 @@ -859,6 +859,10 @@ extern rtx expand_ternary_op (enum machi extern rtx expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int, enum optab_methods); +extern rtx simplify_expand_binop (enum machine_mode mode, optab binoptab, + rtx op0, rtx op1, rtx target, int unsignedp, + enum optab_methods methods); + extern bool force_expand_binop (enum machine_mode, optab, rtx, rtx, rtx, int, enum optab_methods);