Hello,

On Thu, Apr 24, 2008 at 05:22:28PM +0200, Freddy Spierenburg wrote:
> The attached patch does add this support.

Unfortunately the yesterday patch featured a grave bug. I
overlooked the _ulong variable. Hence my patch could not handle
the MSB part of the long long, pretty pointless.

In solving this bug I could take two directions. Make _ulong a
long long or invent an extra _ulonglong. For performance reason I
chose the last route. I think those few extra conditional jumps
are worth not having to do 64-bit arithmetic on all integers,
please correct me if I'm wrong. Or perhaps you all think I'm
braindead anyway, trying to do 64-bit arithmetic on a simple
16-bit CPU. :)

Next I stumbled upon a gcc problem. I got the error below, while
compiling vuprintf.c:

        stdlib/vuprintf.c: In function `vuprintf':
        stdlib/vuprintf.c:605: internal error: Segmentation fault

A little bit of investigation showed me the line below was
causing the trouble:

        notlastdigit=(_ulonglong>=base);

For some strange reason gcc has trouble comparing the long long
variable _ulonglong to the base. Unfortunately I do not have the
guts (yet) to dive into the gcc source. Does anybody have an idea
what is going on?

I changed the line into the line below and that works without
trouble:

        notlastdigit=((_ulonglong>>32)>0)||((unsigned long)_ulonglong>=base);

But the elegant department is probably raising an eyebrow or two.

Anyway, please find attached a patch that this time correctly
adds the long long support to the printf() family. Any comments
are appreciated.


-- 
$ cat ~/.signature
Freddy Spierenburg <[email protected]>  http://freddy.snarl.nl/
GnuPG: 0x7941D1E1=C948 5851 26D2 FA5C 39F1  E588 6F17 FD5D 7941 D1E1
$ # Please read http://www.ietf.org/rfc/rfc2015.txt before complain!
diff -Naur msp430-libc-20071026-orig/mspgcc-libc/src/stdlib/vuprintf.c msp430-libc-20071026/mspgcc-libc/src/stdlib/vuprintf.c
--- msp430-libc-20071026-orig/mspgcc-libc/src/stdlib/vuprintf.c	2007-10-26 22:33:50.000000000 +0000
+++ msp430-libc-20071026/mspgcc-libc/src/stdlib/vuprintf.c	2008-04-25 13:49:37.000000000 +0000
@@ -155,7 +155,7 @@
 #define	LADJUST		0x10		/* left adjustment */
 #define	ZEROPAD		0x20		/* zero (as opposed to blank) pad */
 #define	HEXPREFIX	0x40		/* add 0x or 0X prefix */
-
+#define	LONGLONGINT	0x80		/* long long integer */
 
 int vuprintf(int (*func)(int), const char *fmt0, va_list ap)
 {
@@ -169,6 +169,7 @@
     signed char prec;		/* precision from format (%.3d), or -1 */
     char sign;				/* sign prefix (' ', '+', '-', or \0) */
     unsigned long _ulong=0;	/* integer arguments %[diouxX] */
+    unsigned long long _ulonglong=0;	/* integer arguments %[diouxX] */
 #define OCT 8
 #define DEC 10
 #define HEX 16
@@ -216,7 +217,10 @@
         {
             if (flags&LONGINT)
             {
-                _ulong=va_arg(ap, unsigned long);
+                if (flags&LONGLONGINT)
+                    _ulonglong=va_arg(ap, unsigned long long);
+                else
+                    _ulong=va_arg(ap, unsigned long);
             }
             else
             {
@@ -312,7 +316,10 @@
         }
         else if (ch=='l')
         {
-            flags |= LONGINT;
+            if (flags & LONGINT)
+              flags |= LONGLONGINT;
+            else
+              flags |= LONGINT;
             goto rflag;
         }
         else if (ch=='c')
@@ -327,7 +334,10 @@
                 flags |= LONGINT;
             if (flags&LONGINT)
             {
-                _ulong=va_arg(ap, long);
+                if (flags&LONGLONGINT)
+                    _ulonglong=va_arg(ap, long long);
+                else
+                    _ulong=va_arg(ap, long);
             }
             else
             {
@@ -336,10 +346,21 @@
                 _ulong = flags&SHORTINT ? (long)(short)_d : (long)_d;
             }
 
-            if ((long)_ulong < 0)
+            if (flags&LONGLONGINT)
+            {
+              if ((long long)_ulonglong < 0)
+              {
+                  _ulonglong = -_ulonglong;
+                  sign = '-';
+              }
+            }
+            else
             {
-                _ulong = -_ulong;
-                sign = '-';
+              if ((long)_ulong < 0)
+              {
+                  _ulong = -_ulong;
+                  sign = '-';
+              }
             }
             base = DEC;
             goto number;
@@ -412,7 +433,7 @@
         {
             base = HEX;
             /* leading 0x/X only if non-zero */
-            if (flags & ALT && _ulong != 0)
+            if (flags & ALT && ((_ulong != 0) || (_ulonglong != 0)))
                 flags |= HEXPREFIX;
 
             /* unsigned conversions */
@@ -433,13 +454,27 @@
              *	-- ANSI X3J11
              */
             cp = buf + BUF;
-            if (_ulong != 0 || prec != 0)
+            if (((_ulong != 0) || (_ulonglong != 0)) || prec != 0)
             {
                 register unsigned char _d, notlastdigit;
                 do
                 {
-                    notlastdigit=(_ulong>=base);
-                    _d = _ulong % base;
+                    if (flags & LONGLONGINT)
+                    {
+                      /* This commented code line below causes an internal gcc
+                       * error: Segmentation fault. The rather awkward line
+                       * below is a temporarily work-around to this problem. */
+                      /* notlastdigit=(_ulonglong>=base); */
+                      notlastdigit=((_ulonglong>>32)>0)||((unsigned long)_ulonglong>=base);
+                      _d = _ulonglong % base;
+                      _ulonglong /= base;
+                    }
+                    else
+                    {
+                      notlastdigit=(_ulong>=base);
+                      _d = _ulong % base;
+                      _ulong /= base;
+                    }
 
                     if (_d<10)
                     {
@@ -451,7 +486,6 @@
                         if (ch=='X') _d&=~0x20;
                     }
                     *--cp=_d;
-                    _ulong /= base;
                 }
                 while (notlastdigit);
 

Attachment: signature.asc
Description: Digital signature

Reply via email to