Hi there,
This patch intends to prevent gcc from putting volatile memory access into
IT block for target like cortex-m7.
gcc/ChangeLog:
2015-02-12 Terry Guo <terry....@arm.com>
* config/arm/arm.c (arm_tune_cortex_m7): New global variable.
* config/arm/arm.h (TARGET_NO_VOLATILE_CE): New macro.
(arm_tune_cortex_m7): Declare new global variable.
* config/arm/arm.md (arm_comparison_operator): Disabled if not allow
volatile memory access in IT block.
gcc/testsuite/ChangeLog:
2015-02-12 Terry Guo <terry....@arm.com>
* gcc.target/arm/cortex-m7-it-volatile.c: New test.
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 297dfe1..d6b854d 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -290,6 +290,9 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
#define TARGET_CRC32 (arm_arch_crc)
+/* Targets that don't support accessing volatile memory inside IT block. */
+#define TARGET_NO_VOLATILE_CE (arm_tune_cortex_m7)
+
/* The following two macros concern the ability to execute coprocessor
instructions for VFPv3 or NEON. TARGET_VFP3/TARGET_VFPD32 are currently
only ever tested when we know we are generating for VFP hardware; we need
@@ -552,6 +555,9 @@ extern int arm_tune_wbuf;
/* Nonzero if tuning for Cortex-A9. */
extern int arm_tune_cortex_a9;
+/* Nonzero if tuning for Cortex-M7. */
+extern int arm_tune_cortex_m7;
+
/* Nonzero if we should define __THUMB_INTERWORK__ in the
preprocessor.
XXX This is a bit of a hack, it's intended to help work around
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 7bf5b4d..081ccec 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -846,6 +846,9 @@ int arm_tune_wbuf = 0;
/* Nonzero if tuning for Cortex-A9. */
int arm_tune_cortex_a9 = 0;
+/* Nonzero if tuning for Cortex-M7. */
+int arm_tune_cortex_m7 = 0;
+
/* Nonzero if generating Thumb instructions. */
int thumb_code = 0;
@@ -2859,7 +2862,8 @@ arm_option_override (void)
arm_arch_iwmmxt2 = (insn_flags & FL_IWMMXT2) != 0;
arm_arch_thumb_hwdiv = (insn_flags & FL_THUMB_DIV) != 0;
arm_arch_arm_hwdiv = (insn_flags & FL_ARM_DIV) != 0;
- arm_tune_cortex_a9 = (arm_tune == cortexa9) != 0;
+ arm_tune_cortex_a9 = (arm_tune == cortexa9);
+ arm_tune_cortex_m7 = (arm_tune == cortexm7);
arm_arch_crc = (insn_flags & FL_CRC32) != 0;
arm_m_profile_small_mul = (insn_flags & FL_SMALLMUL) != 0;
if (arm_restrict_it == 2)
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index c13e9b2..164ac13 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -10755,7 +10755,8 @@
[(match_operator 0 "arm_comparison_operator"
[(match_operand 1 "cc_register" "")
(const_int 0)])]
- "TARGET_32BIT"
+ "TARGET_32BIT
+ && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))"
""
[(set_attr "predicated" "yes")]
)
diff --git a/gcc/testsuite/gcc.target/arm/cortex-m7-it-volatile.c
b/gcc/testsuite/gcc.target/arm/cortex-m7-it-volatile.c
new file mode 100644
index 0000000..206afdb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/cortex-m7-it-volatile.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-options "-Os -mthumb -mcpu=cortex-m7" } */
+
+int
+foo (int a, int b, volatile int *c, volatile int *d)
+{
+ if (a > b)
+ return c[0];
+ else
+ return d[0];
+}
+
+/* { dg-final { scan-assembler-not "ldrgt" } } */