aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/stmt.c8
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr27528.c38
-rw-r--r--gcc/testsuite/gcc.dg/pr27528.c18
5 files changed, 74 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 142c0ec..99ac929 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2006-11-11 Richard Sandiford <richard@codesourcery.com>
+
+ PR middle-end/27528
+ * stmt.c (expand_asm_operands): Use EXPAND_INITIALIZER if the
+ constraints accept neither registers or memories.
+
2006-11-11 Jie Zhang <jie.zhang@analog.com>
* config/bfin/bfin.h (FUNCTION_PROFILER): Don't use LABELNO.
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 1937453..d5a181b 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -885,9 +885,13 @@ expand_asm_operands (tree string, tree outputs, tree inputs,
val = TREE_VALUE (tail);
type = TREE_TYPE (val);
+ /* EXPAND_INITIALIZER will not generate code for valid initializer
+ constants, but will still generate code for other types of operand.
+ This is the behavior we want for constant constraints. */
op = expand_expr (val, NULL_RTX, VOIDmode,
- (allows_mem && !allows_reg
- ? EXPAND_MEMORY : EXPAND_NORMAL));
+ allows_reg ? EXPAND_NORMAL
+ : allows_mem ? EXPAND_MEMORY
+ : EXPAND_INITIALIZER);
/* Never pass a CONCAT to an ASM. */
if (GET_CODE (op) == CONCAT)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b928b36..be5d63c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2006-11-11 Richard Sandiford <richard@codesourcery.com>
+
+ PR middle-end/27528
+ * gcc.c-torture/compile/pr27528.c: New test.
+ * gcc.dg/pr27528.c: Likewise.
+
2006-11-10 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/builtins-20.c: Add more cases for stripping sign ops.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr27528.c b/gcc/testsuite/gcc.c-torture/compile/pr27528.c
new file mode 100644
index 0000000..ee3cf65
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr27528.c
@@ -0,0 +1,38 @@
+/* Check that constant constraints like "i", "n" and "s" can be used in
+ cases where the operand is an initializer constant. */
+int x[2] = { 1, 2 };
+
+#ifdef __OPTIMIZE__
+static inline void __attribute__((__always_inline__))
+insn1 (int x)
+{
+ asm volatile ("# %0 %1" :: "n" (x), "i" (x));
+}
+
+static inline void __attribute__((__always_inline__))
+insn2 (const void *x)
+{
+ asm volatile ("# %0 %1" :: "s" (x), "i" (x));
+}
+#endif
+
+void
+foo (void)
+{
+#ifdef __OPTIMIZE__
+ insn1 (2);
+ insn1 (2);
+ insn1 (400);
+ insn1 (__LINE__);
+ insn2 (x);
+ insn2 (x);
+ insn2 (&x[1]);
+ insn2 ("string");
+#endif
+ asm volatile ("# %0 %1" :: "s" (x), "i" (x));
+ /* At the time of writing, &x[1] is decomposed before reaching expand
+ when compiling with -O0. */
+ asm volatile ("# %0 %1" :: "s" ("string"), "i" ("string"));
+ asm volatile ("# %0 %1" :: "s" (__FILE__), "i" (__FILE__));
+ asm volatile ("# %0 %1" :: "s" (__FUNCTION__), "i" (__FUNCTION__));
+}
diff --git a/gcc/testsuite/gcc.dg/pr27528.c b/gcc/testsuite/gcc.dg/pr27528.c
new file mode 100644
index 0000000..4f33a31
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr27528.c
@@ -0,0 +1,18 @@
+/* Check the warnings and errors generated for asm operands that aren't
+ obviously constant but that are constrained to be constants. */
+/* { dg-options "" } */
+/* { dg-error "impossible constraint" "" { target *-*-* } 13 } */
+/* { dg-error "impossible constraint" "" { target *-*-* } 14 } */
+/* { dg-error "impossible constraint" "" { target *-*-* } 15 } */
+/* { dg-error "impossible constraint" "" { target *-*-* } 16 } */
+int bar (int);
+void
+foo (int *x, int y)
+{
+ int constant = 0;
+ asm ("# %0" :: "i" (x)); /* { dg-warning "probably doesn't match" } */
+ asm ("# %0" :: "i" (bar (*x))); /* { dg-warning "probably doesn't match" } */
+ asm ("# %0" :: "i" (*x + 0x11)); /* { dg-warning "probably doesn't match" } */
+ asm ("# %0" :: "i" (constant)); /* { dg-warning "probably doesn't match" } */
+ asm ("# %0" :: "i" (y * 0)); /* folded */
+}