re PR middle-end/50325 (76 new fails with rev. 177691)
authorAndreas Krebbel <Andreas.Krebbel@de.ibm.com>
Wed, 16 Nov 2011 09:27:56 +0000 (09:27 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Wed, 16 Nov 2011 09:27:56 +0000 (09:27 +0000)
2011-11-16  Andreas Krebbel  <Andreas.Krebbel@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.

From-SVN: r181405

gcc/ChangeLog
gcc/expmed.c

index 09b031315afbdfa5010da4a19af37b0aff001260..ce6df44a2f3f11124c5e7c188734dd28d12b4006 100644 (file)
@@ -1,3 +1,10 @@
+2011-11-16  Andreas Krebbel  <Andreas.Krebbel@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.
+
 2011-11-15  Joseph Myers  <joseph@codesourcery.com>
 
        * config/i386/i386elf.h (ASM_OUTPUT_ASCII): Change STRING_LIMIT to
index b3e6d6d181600d409ff0463e7f9ae8b0a0e2534c..6a9da64e37cd3aa37b69be74c15f0bd63ee6d9f7 100644 (file)
@@ -543,7 +543,8 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
         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,18 @@ 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)
+           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,