aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2015-03-05 18:56:37 +0000
committerBernd Edlinger <edlinger@gcc.gnu.org>2015-03-05 18:56:37 +0000
commit53c615a2769209147ad242d646051954b3a2b8f4 (patch)
tree9e9c800b382c8690b9fcedb6e5aaba6e7dd1e858 /gcc
parent9374ef820b2e1b5410bfd9ccb4c2dbd023a369c6 (diff)
downloadgcc-53c615a2769209147ad242d646051954b3a2b8f4.zip
gcc-53c615a2769209147ad242d646051954b3a2b8f4.tar.gz
gcc-53c615a2769209147ad242d646051954b3a2b8f4.tar.bz2
re PR rtl-optimization/65067 (regression on accessing volatile bit field)
gcc: 2015-03-05 Bernd Edlinger <bernd.edlinger@hotmail.de> PR rtl-optimization/65067 * expmed.c (store_bit_field, extract_bit_field): Reworked the strict volatile bitfield handling. testsuite: 2015-03-05 Bernd Edlinger <bernd.edlinger@hotmail.de> * gcc.target/arm/pr65067.c: New test. From-SVN: r221222
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/expmed.c34
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/arm/pr65067.c22
4 files changed, 49 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f780919..3ec2d1c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2015-03-05 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR rtl-optimization/65067
+ * expmed.c (store_bit_field, extract_bit_field): Reworked the
+ strict volatile bitfield handling.
+
2015-03-05 Martin Liska <mliska@suse.cz>
PR ipa/65318
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 18e62a0..0034203 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -976,7 +976,7 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
/* 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. */
- if (simple_mem_bitfield_p (str_rtx, bitsize, bitnum, fieldmode))
+ if (bitsize == GET_MODE_BITSIZE (fieldmode))
{
str_rtx = adjust_bitfield_address (str_rtx, fieldmode,
bitnum / BITS_PER_UNIT);
@@ -984,12 +984,16 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
}
else
{
+ rtx temp;
+
str_rtx = narrow_bit_field_mem (str_rtx, fieldmode, bitsize, bitnum,
&bitnum);
- /* Explicitly override the C/C++ memory model; ignore the
- bit range so that we can do the access in the mode mandated
- by -fstrict-volatile-bitfields instead. */
- store_fixed_bit_field_1 (str_rtx, bitsize, bitnum, value);
+ temp = copy_to_reg (str_rtx);
+ if (!store_bit_field_1 (temp, bitsize, bitnum, 0, 0,
+ fieldmode, value, true))
+ gcc_unreachable ();
+
+ emit_move_insn (str_rtx, temp);
}
return;
@@ -1786,24 +1790,20 @@ extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
if (strict_volatile_bitfield_p (str_rtx, bitsize, bitnum, mode1, 0, 0))
{
- rtx result;
-
/* 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 (simple_mem_bitfield_p (str_rtx, bitsize, bitnum, mode1))
- result = adjust_bitfield_address (str_rtx, mode1,
- bitnum / BITS_PER_UNIT);
- else
+ if (bitsize == GET_MODE_BITSIZE(mode1))
{
- str_rtx = narrow_bit_field_mem (str_rtx, mode1, bitsize, bitnum,
- &bitnum);
- result = extract_fixed_bit_field_1 (mode, str_rtx, bitsize, bitnum,
- target, unsignedp);
+ rtx result = adjust_bitfield_address (str_rtx, mode1,
+ bitnum / BITS_PER_UNIT);
+ return convert_extracted_bit_field (result, mode, tmode, unsignedp);
}
- return convert_extracted_bit_field (result, mode, tmode, unsignedp);
+ str_rtx = narrow_bit_field_mem (str_rtx, mode1, bitsize, bitnum,
+ &bitnum);
+ str_rtx = copy_to_reg (str_rtx);
}
-
+
return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp,
target, mode, tmode, true);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 09d42b3..321db12 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2015-03-05 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * gcc.target/arm/pr65067.c: New test.
+
2015-03-05 Martin Liska <mliska@suse.cz>
PR ipa/65318
diff --git a/gcc/testsuite/gcc.target/arm/pr65067.c b/gcc/testsuite/gcc.target/arm/pr65067.c
new file mode 100644
index 0000000..9ddd7bb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr65067.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-mthumb -mcpu=cortex-m3 -O2" } */
+
+struct tmp {
+ unsigned int dummy;
+ union {
+ struct {
+ unsigned int xyz : 1;
+ unsigned int mode: 3;
+ unsigned int res : 28;
+ } bf;
+ unsigned int wordval;
+ } reg;
+};
+
+void set_mode(int mode)
+{
+ volatile struct tmp *t = (struct tmp *) 0x1000;
+ t->reg.bf.mode = mode;
+}
+
+/* { dg-final { scan-assembler "bfi" } } */