diff options
author | Julian Brown <julian@codesourcery.com> | 2011-09-14 13:47:42 +0000 |
---|---|---|
committer | Julian Brown <jules@gcc.gnu.org> | 2011-09-14 13:47:42 +0000 |
commit | 86b601168af25ef6881ebd5364235abc788731ca (patch) | |
tree | 1e6ac52a6b4abbbaab31d0119d7a31c0a62ec1e4 /gcc/expmed.c | |
parent | fafaf06fba1bd3a03b1518666160d9765965a0db (diff) | |
download | gcc-86b601168af25ef6881ebd5364235abc788731ca.tar.gz |
arm.c (arm_override_options): Add unaligned_access support.
gcc/
* config/arm/arm.c (arm_override_options): Add unaligned_access
support.
(arm_file_start): Emit attribute for unaligned access as
appropriate.
* config/arm/arm.md (UNSPEC_UNALIGNED_LOAD)
(UNSPEC_UNALIGNED_STORE): Add constants for unspecs.
(insv, extzv): Add unaligned-access support.
(extv): Change to expander. Likewise.
(extzv_t1, extv_regsi): Add helpers.
(unaligned_loadsi, unaligned_loadhis, unaligned_loadhiu)
(unaligned_storesi, unaligned_storehi): New.
(*extv_reg): New (previous extv implementation).
* config/arm/arm.opt (munaligned_access): Add option.
* config/arm/constraints.md (Uw): New constraint.
* expmed.c (store_bit_field_1): Adjust bitfield numbering according
to size of access, not size of unit, when BITS_BIG_ENDIAN !=
BYTES_BIG_ENDIAN. Don't use bitfield accesses for
volatile accesses when -fstrict-volatile-bitfields is in effect.
(extract_bit_field_1): Likewise.
From-SVN: r178852
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c index 0047cd09076..1528fbb1112 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -620,6 +620,10 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, && GET_MODE (value) != BLKmode && bitsize > 0 && GET_MODE_BITSIZE (op_mode) >= bitsize + /* Do not use insv for volatile bitfields when + -fstrict-volatile-bitfields is in effect. */ + && !(MEM_P (op0) && MEM_VOLATILE_P (op0) + && flag_strict_volatile_bitfields > 0) && ! ((REG_P (op0) || GET_CODE (op0) == SUBREG) && (bitsize + bitpos > GET_MODE_BITSIZE (op_mode)))) { @@ -659,19 +663,21 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, copy_back = true; } - /* On big-endian machines, we count bits from the most significant. - If the bit field insn does not, we must invert. */ - - if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN) - xbitpos = unit - bitsize - xbitpos; - /* We have been counting XBITPOS within UNIT. Count instead within the size of the register. */ - if (BITS_BIG_ENDIAN && !MEM_P (xop0)) + if (BYTES_BIG_ENDIAN && !MEM_P (xop0)) xbitpos += GET_MODE_BITSIZE (op_mode) - unit; unit = GET_MODE_BITSIZE (op_mode); + /* If BITS_BIG_ENDIAN is zero on a BYTES_BIG_ENDIAN machine, we count + "backwards" from the size of the unit we are inserting into. + Otherwise, we count bits from the most significant on a + BYTES/BITS_BIG_ENDIAN machine. */ + + if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN) + xbitpos = unit - bitsize - xbitpos; + /* Convert VALUE to op_mode (which insv insn wants) in VALUE1. */ value1 = value; if (GET_MODE (value) != op_mode) @@ -1507,6 +1513,10 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, if (ext_mode != MAX_MACHINE_MODE && bitsize > 0 && GET_MODE_BITSIZE (ext_mode) >= bitsize + /* Do not use extv/extzv for volatile bitfields when + -fstrict-volatile-bitfields is in effect. */ + && !(MEM_P (op0) && MEM_VOLATILE_P (op0) + && flag_strict_volatile_bitfields > 0) /* If op0 is a register, we need it in EXT_MODE to make it acceptable to the format of ext(z)v. */ && !(GET_CODE (op0) == SUBREG && GET_MODE (op0) != ext_mode) @@ -1528,17 +1538,20 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, /* Get ref to first byte containing part of the field. */ xop0 = adjust_address (xop0, byte_mode, xoffset); - /* On big-endian machines, we count bits from the most significant. - If the bit field insn does not, we must invert. */ - if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN) - xbitpos = unit - bitsize - xbitpos; - /* Now convert from counting within UNIT to counting in EXT_MODE. */ - if (BITS_BIG_ENDIAN && !MEM_P (xop0)) + if (BYTES_BIG_ENDIAN && !MEM_P (xop0)) xbitpos += GET_MODE_BITSIZE (ext_mode) - unit; unit = GET_MODE_BITSIZE (ext_mode); + /* If BITS_BIG_ENDIAN is zero on a BYTES_BIG_ENDIAN machine, we count + "backwards" from the size of the unit we are extracting from. + Otherwise, we count bits from the most significant on a + BYTES/BITS_BIG_ENDIAN machine. */ + + if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN) + xbitpos = unit - bitsize - xbitpos; + if (xtarget == 0) xtarget = xspec_target = gen_reg_rtx (tmode); |