diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/stmt.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr27528.c | 38 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr27528.c | 18 |
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. @@ -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 */ +} |