===================================================================
@@ -475,6 +475,19 @@ store_bit_field_1 (rtx str_rtx, unsigned
return true;
}
+ offset = bitnum / unit;
+ bitpos = bitnum % unit;
+ byte_offset = (bitnum % BITS_PER_WORD) / BITS_PER_UNIT
+ + (offset * UNITS_PER_WORD);
+
+ /* If the bitfield is volatile, we need to make sure the access
+ remains on a type-aligned boundary. */
+ if (GET_CODE (op0) == MEM
+ && MEM_VOLATILE_P (op0)
+ && GET_MODE_BITSIZE (GET_MODE (op0)) > 0
+ && flag_strict_volatile_bitfields > 0)
+ goto no_subreg_mode_swap;
+
/* If the target is a register, overwriting the entire object, or storing
a full-word or multi-word field can be done with just a SUBREG.
@@ -482,11 +495,6 @@ store_bit_field_1 (rtx str_rtx, unsigned
done with a simple store. For targets that support fast unaligned
memory, any naturally sized, unit aligned field can be done directly. */
- offset = bitnum / unit;
- bitpos = bitnum % unit;
- byte_offset = (bitnum % BITS_PER_WORD) / BITS_PER_UNIT
- + (offset * UNITS_PER_WORD);
-
if (bitpos == 0
&& bitsize == GET_MODE_BITSIZE (fieldmode)
&& (!MEM_P (op0)
@@ -581,6 +589,7 @@ store_bit_field_1 (rtx str_rtx, unsigned
return true;
}
}
+ no_subreg_mode_swap:
/* Handle fields bigger than a word. */
@@ -809,8 +818,11 @@ store_bit_field_1 (rtx str_rtx, unsigned
}
/* If OP0 is a memory, try copying it to a register and seeing if a
- cheap register alternative is available. */
- if (HAVE_insv && MEM_P (op0))
+ cheap register alternative is available.
+ Do not try this optimization for volatile bitfields if
+ -fstrict-volatile-bitfields is in effect. */
+ if (HAVE_insv && MEM_P (op0)
+ && !(MEM_VOLATILE_P (op0) && flag_strict_volatile_bitfields > 0))
{
enum machine_mode bestmode;
unsigned HOST_WIDE_INT maxbits = MAX_FIXED_MODE_SIZE;
@@ -988,8 +1000,6 @@ store_fixed_bit_field (rtx op0, unsigned
mode = word_mode;
if (MEM_VOLATILE_P (op0)
- && GET_MODE_BITSIZE (GET_MODE (op0)) > 0
- && GET_MODE_BITSIZE (GET_MODE (op0)) <= maxbits
&& flag_strict_volatile_bitfields > 0)
mode = GET_MODE (op0);
else
@@ -1683,8 +1693,11 @@ extract_bit_field_1 (rtx str_rtx, unsign
}
/* If OP0 is a memory, try copying it to a register and seeing if a
- cheap register alternative is available. */
- if (ext_mode != MAX_MACHINE_MODE && MEM_P (op0))
+ cheap register alternative is available.
+ Do not try this optimization for volatile bitfields if
+ -fstrict-volatile-bitfields is in effect. */
+ if (ext_mode != MAX_MACHINE_MODE && MEM_P (op0)
+ && !(MEM_VOLATILE_P (op0) && flag_strict_volatile_bitfields > 0))
{
enum machine_mode bestmode;