This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Avoid generating SUBREGs across mode boundaries [patch]
- From: Diego Novillo <dnovillo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 14 Feb 2002 17:41:28 -0500
- Subject: Avoid generating SUBREGs across mode boundaries [patch]
- Organization: Red Hat Canada
On stormy16-elf we fail to compile gcc.c-torture/compile/20020109-2.c
because in store_bit_field() we're requesting a SUBREG not
aligned to an SImode boundary.
Fixed with this patch. Bootstrapped on x86 with no testsuite
regressions.
Diego.
* expmed.c (store_bit_field): Do not store bit fields using SUBREG
operations if the field does not start at a mode boundary.
Index: expmed.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expmed.c,v
retrieving revision 1.104
diff -d -p -d -u -p -r1.104 expmed.c
--- expmed.c 2002/02/01 23:43:14 1.104
+++ expmed.c 2002/02/14 21:56:32
@@ -299,6 +299,7 @@ store_bit_field (str_rtx, bitsize, bitnu
unsigned HOST_WIDE_INT offset = bitnum / unit;
unsigned HOST_WIDE_INT bitpos = bitnum % unit;
rtx op0 = str_rtx;
+ int byte_offset;
enum machine_mode op_mode = mode_for_extraction (EP_insv, 3);
@@ -333,11 +334,15 @@ store_bit_field (str_rtx, bitsize, bitnu
done with a simple store. For targets that support fast unaligned
memory, any naturally sized, unit aligned field can be done directly. */
+ byte_offset = (bitnum % BITS_PER_WORD) / BITS_PER_UNIT
+ + (offset * UNITS_PER_WORD);
+
if (bitpos == 0
&& bitsize == GET_MODE_BITSIZE (fieldmode)
&& (GET_CODE (op0) != MEM
- ? (GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD
+ ? ((GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD
|| GET_MODE_SIZE (GET_MODE (op0)) == GET_MODE_SIZE (fieldmode))
+ && byte_offset % GET_MODE_SIZE (fieldmode) == 0)
: (! SLOW_UNALIGNED_ACCESS (fieldmode, MEM_ALIGN (op0))
|| (offset * BITS_PER_UNIT % bitsize == 0
&& MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0))))
@@ -357,9 +362,7 @@ store_bit_field (str_rtx, bitsize, bitnu
abort ();
}
if (GET_CODE (op0) == REG)
- op0 = gen_rtx_SUBREG (fieldmode, op0,
- (bitnum % BITS_PER_WORD) / BITS_PER_UNIT
- + (offset * UNITS_PER_WORD));
+ op0 = gen_rtx_SUBREG (fieldmode, op0, byte_offset);
else
op0 = adjust_address (op0, fieldmode, offset);
}