aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndreas Krebbel <Andreas.Krebbel@de.ibm.com>2009-03-09 13:30:19 +0000
committerAndreas Krebbel <krebbel@gcc.gnu.org>2009-03-09 13:30:19 +0000
commit929b7fc3c0afc5d5154ce9e40371a42a0610fd7f (patch)
tree031dd1ced917e31481cde7178045772632594fd5 /gcc
parent1803581d7698029091783f8c9ac6220aa52ccec5 (diff)
downloadgcc-929b7fc3c0afc5d5154ce9e40371a42a0610fd7f.zip
gcc-929b7fc3c0afc5d5154ce9e40371a42a0610fd7f.tar.gz
gcc-929b7fc3c0afc5d5154ce9e40371a42a0610fd7f.tar.bz2
recog.c (verfiy_changes): Disallow renaming of hard regs in inline asms for register asm ("") declarations.
2009-03-09 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> * recog.c (verfiy_changes): Disallow renaming of hard regs in inline asms for register asm ("") declarations. 2009-03-09 Andreas Krebbel <Andreas.Krebbel@de.ibm.com> * gcc.target/s390/20090223-1.c: New testcase. From-SVN: r144726
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/recog.c10
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/s390/20090223-1.c60
4 files changed, 79 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9ab8b72..300507d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2009-03-09 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * recog.c (verfiy_changes): Disallow renaming of hard regs in
+ inline asms for register asm ("") declarations.
+
2009-03-09 Eric Botcazou <ebotcazou@adacore.com>
* fold-const.c (fold_unary): Fix comment.
diff --git a/gcc/recog.c b/gcc/recog.c
index 7c22fae..70370e3 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -379,6 +379,16 @@ verify_changes (int num)
if (! memory_address_p (GET_MODE (object), XEXP (object, 0)))
break;
}
+ else if (REG_P (changes[i].old)
+ && asm_noperands (PATTERN (object)) > 0
+ && REG_EXPR (changes[i].old) != NULL_TREE
+ && DECL_ASSEMBLER_NAME_SET_P (REG_EXPR (changes[i].old))
+ && DECL_REGISTER (REG_EXPR (changes[i].old)))
+ {
+ /* Don't allow changes of hard register operands to inline
+ assemblies if they have been defined as register asm ("x"). */
+ break;
+ }
else if (insn_invalid_p (object))
{
rtx pat = PATTERN (object);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 135a0b4..0651163 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2009-03-09 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * gcc.target/s390/20090223-1.c: New testcase.
+
2009-03-08 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR libfortran/39402
diff --git a/gcc/testsuite/gcc.target/s390/20090223-1.c b/gcc/testsuite/gcc.target/s390/20090223-1.c
new file mode 100644
index 0000000..443ccb9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/20090223-1.c
@@ -0,0 +1,60 @@
+/* The RTL loop optimizer used to replace the output register of the
+ inline assembly with a pseudo although the variable is declared as
+ register asm ("0"). */
+
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+
+static unsigned char __attribute__ ((always_inline))
+mytoupper (unsigned char c)
+{
+ if (c >= 'a' && c <= 'z')
+ c -= 'a' - 'A';
+ return c;
+}
+
+static unsigned long __attribute__ ((always_inline))
+strlen (const char *s)
+{
+ register unsigned long r0 asm ("0");
+ const char *tmp = s;
+
+ asm (
+#ifdef __s390x__
+ " lghi %0, 0\n"
+#else
+ " lhi %0, 0\n"
+#endif
+ "0:srst %0,%1\n"
+ " jo 0b"
+ : "=d" (r0), "+a" (tmp)
+ :
+ :"cc");
+ return r0 - (unsigned long) s;
+}
+
+char boot_command_line[] = "this is a test";
+
+void __attribute__ ((noinline))
+foo (char *str)
+{
+ if (strcmp (str, "THIS IS A TEST") != 0)
+ abort ();
+}
+
+int
+main ()
+{
+ char upper_command_line[1024];
+ int i;
+
+ for (i = 0; i < strlen (boot_command_line); i++)
+ upper_command_line[i] = mytoupper (boot_command_line[i]);
+
+ upper_command_line[strlen (boot_command_line)] = 0;
+ foo (upper_command_line);
+
+ return 0;
+}