This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] Fix assembly dialect handling


Hi!

gcc up to now for assembly patterns like "foo|bar" used to output foo
no matter what assembly dialect was chosen.
As supporting dialect 1 to print bar in this case would almost
certainly slow down output_asm_insn (either it would have to strchr '|'
each pattern if it doesn't occur after '{') or put the result in a buffer
and output it only for the proper dialect and some people use | characters
in assembly comments and then wonder what output they get, this patch
tightens the rules by only choosing between assembly dialects in
{ ... [| ...]* }, disallows nesting the { braces and errors for unterminated
constructs too. | or } characters, if they don't form a dialect selection,
will be handled as any other non-special characters.
This patch found a couple of such constructs in i386.md where no matter
whether -mintel-syntax was given or not, the first syntax was chosen.
I've grepped all other targets which use assembly dialect and they seem to
be ok in this regard.
Ok to commit, provided it finishes the bootstrap and makes no regressions?

2001-10-11  Jakub Jelinek  <jakub@redhat.com>

	* final.c (output_asm_insn): Make sure assembly dialects are
	terminated, not nested.  Output `|' and `}' characters if they
	don't appear inside assembly dialect selection.
	* config/i386/i386.md (rep_movdi_rex64, rep_movsi, rep_movsi_rex64,
	rep_movqi, rep_movqi_rex64, rep_stosdi_rex64, rep_stossi,
	rep_stossi_rex64, rep_stosqi, rep_stosqi_rex64, strsetsi_1,
	strsetsi_rex_1): Add {} braces.

	* testsuite/gcc.dg/20011009-1.c: New test.

--- gcc/final.c.jj	Wed Oct  3 12:35:12 2001
+++ gcc/final.c	Thu Oct 11 12:56:31 2001
@@ -3310,6 +3310,9 @@ output_asm_insn (template, operands)
 {
   register const char *p;
   register int c;
+#ifdef ASSEMBLER_DIALECT
+  int dialect = 0;
+#endif
 
   /* An insn may return a null string template
      in a case where no assembler code is needed.  */
@@ -3344,6 +3347,11 @@ output_asm_insn (template, operands)
 	{
 	  register int i;
 
+	  if (dialect)
+	    output_operand_lossage ("nested assembly dialect alternatives");
+	  else
+	    dialect = 1;
+
 	  /* If we want the first dialect, do nothing.  Otherwise, skip
 	     DIALECT_NUMBER of strings ending with '|'.  */
 	  for (i = 0; i < dialect_number; i++)
@@ -3355,16 +3363,35 @@ output_asm_insn (template, operands)
 	      if (*p == '|')
 		p++;
 	    }
+
+	  if (*p == '\0')
+	    output_operand_lossage ("unterminated assembly dialect alternative");
 	}
 	break;
 
       case '|':
-	/* Skip to close brace.  */
-	while (*p && *p++ != '}')
-	  ;
+	if (dialect)
+	  {
+	    /* Skip to close brace.  */
+	    do
+	      {
+		if (*p == '\0')
+		  {
+		    output_operand_lossage ("unterminated assembly dialect alternative");
+		    break;
+		  }
+	      }	  
+	    while (*p++ != '}');
+	    dialect = 0;
+	  }
+	else
+	  putc (c, asm_out_file);
 	break;
 
       case '}':
+	if (! dialect)
+	  putc (c, asm_out_file);
+	dialect = 0;
 	break;
 #endif
 
--- gcc/config/i386/i386.md.jj	Thu Oct 11 13:10:19 2001
+++ gcc/config/i386/i386.md	Thu Oct 11 13:12:17 2001
@@ -14868,7 +14868,7 @@
    (use (match_dup 5))
    (use (reg:SI 19))]
   "TARGET_64BIT"
-  "rep\;movsq|rep movsq"
+  "rep{\;| }movsq"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "both")
@@ -14888,7 +14888,7 @@
    (use (match_dup 5))
    (use (reg:SI 19))]
   "!TARGET_64BIT"
-  "rep\;movsl|rep movsd"
+  "{rep\;movsl|rep movsd}"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "both")
@@ -14908,7 +14908,7 @@
    (use (match_dup 5))
    (use (reg:SI 19))]
   "TARGET_64BIT"
-  "rep\;movsl|rep movsd"
+  "{rep\;movsl|rep movsd}"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "both")
@@ -14926,7 +14926,7 @@
    (use (match_dup 5))
    (use (reg:SI 19))]
   "!TARGET_64BIT"
-  "rep\;movsb|rep movsb"
+  "rep{\;| }movsb"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "both")
@@ -14944,7 +14944,7 @@
    (use (match_dup 5))
    (use (reg:SI 19))]
   "TARGET_64BIT"
-  "rep\;movsb|rep movsb"
+  "rep{\;| }movsb"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "both")
@@ -15111,7 +15111,7 @@
 		 (const_int 4)))
    (use (reg:SI 19))]
   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
-  "stosl|stosd"
+  "stos{l|d}"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
    (set_attr "mode" "SI")])
@@ -15124,7 +15124,7 @@
 		 (const_int 4)))
    (use (reg:SI 19))]
   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
-  "stosl|stosd"
+  "stos{l|d}"
   [(set_attr "type" "str")
    (set_attr "memory" "store")
    (set_attr "mode" "SI")])
@@ -15193,7 +15193,7 @@
    (use (match_dup 4))
    (use (reg:SI 19))]
   "TARGET_64BIT"
-  "rep\;stosq|rep stosq"
+  "rep{\;| }stosq"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "store")
@@ -15211,7 +15211,7 @@
    (use (match_dup 4))
    (use (reg:SI 19))]
   "!TARGET_64BIT"
-  "rep\;stosl|rep stosd"
+  "{rep\;stosl|rep stosd}"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "store")
@@ -15229,7 +15229,7 @@
    (use (match_dup 4))
    (use (reg:SI 19))]
   "TARGET_64BIT"
-  "rep\;stosl|rep stosd"
+  "{rep\;stosl|rep stosd}"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "store")
@@ -15246,7 +15246,7 @@
    (use (match_dup 4))
    (use (reg:SI 19))]
   "!TARGET_64BIT"
-  "rep\;stosb|rep stosb"
+  "rep{\;| }stosb"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "store")
@@ -15263,7 +15263,7 @@
    (use (match_dup 4))
    (use (reg:DI 19))]
   "TARGET_64BIT"
-  "rep\;stosb|rep stosb"
+  "rep{\;| }stosb"
   [(set_attr "type" "str")
    (set_attr "prefix_rep" "1")
    (set_attr "memory" "store")
--- gcc/testsuite/gcc.dg/20011009-1.c.jj	Tue Oct  9 16:23:21 2001
+++ gcc/testsuite/gcc.dg/20011009-1.c	Tue Oct  9 16:22:59 2001
@@ -0,0 +1,16 @@
+/* { dg-do run { target i?86-*-* } } */
+/* { dg-options "-O2" } */
+
+extern void abort (void);
+extern void exit (int);
+
+int main ()
+{
+  int x;
+
+  asm ("movl $26, %0 # 26 |-> reg \n\t"
+       "movl $28, %0" : "=r" (x));
+  if (x != 28)
+    abort ();
+  exit (0);
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]