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,

Reply via email to