diff options
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c index e0b2619034d..6327629d458 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -472,9 +472,13 @@ strict_volatile_bitfield_p (rtx op0, unsigned HOST_WIDE_INT bitsize, return false; /* Check for cases of unaligned fields that must be split. */ - if (bitnum % BITS_PER_UNIT + bitsize > modesize - || (STRICT_ALIGNMENT - && bitnum % GET_MODE_ALIGNMENT (fieldmode) + bitsize > modesize)) + if (bitnum % modesize + bitsize > modesize) + return false; + + /* The memory must be sufficiently aligned for a MODESIZE access. + This condition guarantees, that the memory access will not + touch anything after the end of the structure. */ + if (MEM_ALIGN (op0) < modesize) return false; /* Check for cases where the C++ memory model applies. */ @@ -973,13 +977,15 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, if (strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, fieldmode, bitregion_start, bitregion_end)) { - /* Storing any naturally aligned field can be done with a simple - store. For targets that support fast unaligned memory, any - naturally sized, unit aligned field can be done directly. */ + /* Storing of a full word can be done with a simple store. + We know here that the field can be accessed with one single + instruction. For targets that support unaligned memory, + an unaligned access may be necessary. */ if (bitsize == GET_MODE_BITSIZE (fieldmode)) { str_rtx = adjust_bitfield_address (str_rtx, fieldmode, bitnum / BITS_PER_UNIT); + gcc_assert (bitnum % BITS_PER_UNIT == 0); emit_move_insn (str_rtx, value); } else @@ -988,6 +994,7 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, str_rtx = narrow_bit_field_mem (str_rtx, fieldmode, bitsize, bitnum, &bitnum); + gcc_assert (bitnum + bitsize <= GET_MODE_BITSIZE (fieldmode)); temp = copy_to_reg (str_rtx); if (!store_bit_field_1 (temp, bitsize, bitnum, 0, 0, fieldmode, value, true)) @@ -1790,17 +1797,21 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, if (strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, mode1, 0, 0)) { - /* Extraction of a full MODE1 value can be done with a load as long as - the field is on a byte boundary and is sufficiently aligned. */ - if (bitsize == GET_MODE_BITSIZE(mode1)) + /* Extraction of a full MODE1 value can be done with a simple load. + We know here that the field can be accessed with one single + instruction. For targets that support unaligned memory, + an unaligned access may be necessary. */ + if (bitsize == GET_MODE_BITSIZE (mode1)) { rtx result = adjust_bitfield_address (str_rtx, mode1, bitnum / BITS_PER_UNIT); + gcc_assert (bitnum % BITS_PER_UNIT == 0); return convert_extracted_bit_field (result, mode, tmode, unsignedp); } str_rtx = narrow_bit_field_mem (str_rtx, mode1, bitsize, bitnum, &bitnum); + gcc_assert (bitnum + bitsize <= GET_MODE_BITSIZE (mode1)); str_rtx = copy_to_reg (str_rtx); } |