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]
Other format: [Raw text]

Patch to fix internal behavior of the asm_fprintf function


Looking at the internals of the asm_fprintf function, it's clear that
it needs updating.  Several standard specifiers are handled
incorrectly or not at all.  This patch attempts to correct that.

The fixes are:

1.  Update the comments.
2.  Handle "-+ #0" flags	(same as libiberty/vasprintf.c does it)
3.  Optimize a couple of single character output cases into putc.
4.  Add %c handling.
5.  Fix %p handling		(it was handled, but in the `int' clause!)
6.  Handle %ll specifiers	(long long case)

My test platforms (solaris2 and irix6) don't use asm_fprintf in their
backends.  So while I bootstrapped C-only on sparc-solaris2.7, that's
not much of a test but I did it to ensure the files compile okay.

To test the function behavior, I manually copied asm_fprintf into it's
own file and linked it with a series of hand written tests of the
various specifiers.  I verified that the checks failed the various
specifiers I mentioned above and worked when I added my patch.

Ok for mainline?

		Thanks,
		--Kaveh


2003-05-22  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>

	* final.c (asm_fprintf): Update comments, accept "-+ #0"
	flags, optimize '%' case, handle %c, fix handling of %p,
	handle %ll, optimize regular character case.

diff -rup orig/egcc-CVS20030529/gcc/final.c egcc-CVS20030529/gcc/final.c
--- orig/egcc-CVS20030529/gcc/final.c	Sat May 17 18:18:39 2003
+++ egcc-CVS20030529/gcc/final.c	Fri May 30 10:29:06 2003
@@ -3372,7 +3372,7 @@ output_addr_const (file, x)
    %U prints the value of USER_LABEL_PREFIX.
    %I prints the value of IMMEDIATE_PREFIX.
    %O runs ASM_OUTPUT_OPCODE to transform what follows in the string.
-   Also supported are %d, %x, %s, %e, %f, %g and %%.
+   Also supported are %d, %i, %u, %x, %X, %o, %c, %p, %s, %e, %f, %g and %%.
 
    We handle alternate assembler dialects here, just like output_asm_insn.  */
 
@@ -3421,6 +3421,11 @@ asm_fprintf (FILE *file, const char *p, 
       case '%':
 	c = *p++;
 	q = &buf[1];
+	while (strchr ("-+ #0", c))
+	  {
+	    *q++ = c;
+	    c = *p++;
+	  }
 	while (ISDIGIT (c) || c == '.')
 	  {
 	    *q++ = c;
@@ -3429,17 +3434,23 @@ asm_fprintf (FILE *file, const char *p, 
 	switch (c)
 	  {
 	  case '%':
-	    fprintf (file, "%%");
+	    putc ('%', file);
 	    break;
 
 	  case 'd':  case 'i':  case 'u':
-	  case 'x':  case 'p':  case 'X':
-	  case 'o':
+	  case 'x':  case 'X':  case 'o':
+	  case 'c':
 	    *q++ = c;
 	    *q = 0;
 	    fprintf (file, buf, va_arg (argptr, int));
 	    break;
 
+	  case 'p':
+	    *q++ = c;
+	    *q = 0;
+	    fprintf (file, buf, va_arg (argptr, void *));
+	    break;
+
 	  case 'w':
 	    /* This is a prefix to the 'd', 'i', 'u', 'x', 'p', and 'X' cases,
 	       but we do not check for those cases.  It means that the value
@@ -3462,9 +3473,22 @@ asm_fprintf (FILE *file, const char *p, 
 
 	  case 'l':
 	    *q++ = c;
-	    *q++ = *p++;
-	    *q = 0;
-	    fprintf (file, buf, va_arg (argptr, long));
+#ifdef HAVE_LONG_LONG
+	    if (*p == 'l')
+	      {
+		*q++ = *p++;
+		*q++ = *p++;
+		*q = 0;
+		fprintf (file, buf, va_arg (argptr, long long));
+	      }
+	    else
+#endif
+	      {
+		*q++ = *p++;
+		*q = 0;
+		fprintf (file, buf, va_arg (argptr, long));
+	      }
+	    
 	    break;
 
 	  case 'e':
@@ -3529,7 +3553,7 @@ asm_fprintf (FILE *file, const char *p, 
 	break;
 
       default:
-	fputc (c, file);
+	putc (c, file);
       }
   va_end (argptr);
 }


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