This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to fix internal behavior of the asm_fprintf function
- From: "Kaveh R. Ghazi" <ghazi at caip dot rutgers dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 30 May 2003 11:31:28 -0400 (EDT)
- Subject: 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);
}