Hi, starting with r177691 store_bit_field is used for source operands which cannot be covered exactly with word mode chunks. So far store_bit_field does not seem to handle that correctly. With the attached patch extract_bit_field is used for the remaining bits of the source on big endian targets.
This fixes 74 failures on s390x and ppc64. All 22_locale/* failures are fixed on powerpc-apple-darwin9. Bootstrapped on s390x-linux and ppc64-linux. Dominique bootstrapped the patch on powerpc-apple-darwin9 and x86_64-apple-darwin10. Ok for mainline? Bye, -Andreas- 2011-09-21 Andreas Krebbel <andreas.kreb...@de.ibm.com> PR middle-end/50325 * expmed.c (store_bit_field_1): Use extract_bit_field on big endian targets if the source cannot be exactly covered by word mode chunks. Index: gcc/expmed.c =================================================================== *** gcc/expmed.c.orig --- gcc/expmed.c *************** store_bit_field_1 (rtx str_rtx, unsigned *** 543,549 **** is not allowed. */ fieldmode = GET_MODE (value); if (fieldmode == VOIDmode) ! fieldmode = smallest_mode_for_size (nwords * BITS_PER_WORD, MODE_INT); last = get_last_insn (); for (i = 0; i < nwords; i++) --- 543,550 ---- is not allowed. */ fieldmode = GET_MODE (value); if (fieldmode == VOIDmode) ! fieldmode = smallest_mode_for_size (nwords * ! BITS_PER_WORD, MODE_INT); last = get_last_insn (); for (i = 0; i < nwords; i++) *************** store_bit_field_1 (rtx str_rtx, unsigned *** 557,565 **** 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), bitnum + bit_offset, bitregion_start, bitregion_end, word_mode, --- 558,575 ---- 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 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) ! value_word = extract_bit_field (value_word, new_bitsize, 0, ! true, false, NULL_RTX, ! BLKmode, word_mode); ! ! if (!store_bit_field_1 (op0, new_bitsize, bitnum + bit_offset, bitregion_start, bitregion_end, word_mode,