This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR50325 store_bit_field: Fix for big endian targets
- From: "Andreas Krebbel" <krebbel at linux dot vnet dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 21 Sep 2011 08:54:21 +0200
- Subject: [PATCH] PR50325 store_bit_field: Fix for big endian targets
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.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.
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,