This is the mail archive of the newlib@sourceware.org mailing list for the newlib 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]

Re: [PATCH] Reduce RAM usage of floating point conversion functions


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 06/10/2013 09:43 AM, Freddie Chopin wrote:
> W dniu 2013-06-09 17:14, Federico Terraneo pisze:
>> - - gethex() and hexnan(), which are use by both strtod() and 
>> _ldtoa_r() use a lookup table to test if a char is an hex digit, 
>> requiring 256 bytes of RAM. The patch replaces this table with a 
>> function. As this may result in a performance penalty, this 
>> change is only enabled if PREFER_SIZE_OVER_SPEED, 
>> __OPTIMIZE_SIZE__ or _SMALL_HEXDIG is defined. The last macro
>> was introduced to be able to selectively enable this change.
> 
> Couldn't this lookup table be made "static const" instead,
> removing the alleged speed penalty, but keeping the reduced RAM 
> requirement?

I did think about that, but this moves 256 bytes of .bss to 256 bytes
of .rodata, i.e. it would take up that amount of FLASH on a
microcontroller, and the table is mostly filled with zeros, which
still seems a waste.
Here is a patch that goes in that direction:
if PREFER_SIZE_OVER_SPEED, __OPTIMIZE_SIZE__ or _SMALL_HEXDIG are
defined, the table is still replaced with a function, otherwise the
table is made const (but not static, since it's used also in another
file). In this way in both cases 256 bytes of RAM are saved, and in
the former also 256 bytes of FLASH.

> 
> 4\/3!!
> 
> 

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQEcBAEBAgAGBQJRtZhjAAoJECkLFtN5Xr9fSlwH+QEwd2ZLUuDI59ny2Wvuyslf
bdAvyvNMU+/Hzsc7yWqoJmrrv8mn3smXE8l+BXzSpwo5rO8OEvVpL3OV7+ch7kLC
q9j1L8yfatwMTsDrB03igKC/1OBa16eqqlkqViN5NhDt3k6F+8kHE7OSLMQiNmU6
p0DGX/3KUlQRmrg3KaMqM31ITFRDmhQLWh86ZyozdePIgMIu2Gd2XzowSfHgNE18
gbUcpS8s27Nz1bJLQAvU1lGrbVTR+WCFiIpeHWuMHZDNT1z9BT7DZpPg5qdgXsf6
5/FIP2ORVO6UpkCqyBmdZbGGCAbI0fRF31wPE3fDEjakXOGcnzndwM3iBoZYHt0=
=UyQM
-----END PGP SIGNATURE-----
diff -ruN a/newlib/libc/stdlib/gdtoa-gethex.c b/newlib/libc/stdlib/gdtoa-gethex.c
--- a/newlib/libc/stdlib/gdtoa-gethex.c	2009-06-16 19:44:20.000000000 +0200
+++ b/newlib/libc/stdlib/gdtoa-gethex.c	2013-06-10 11:03:58.398456933 +0200
@@ -37,27 +37,37 @@
 #include "gd_qnan.h"
 #include "locale.h"
 
-unsigned char hexdig[256];
-
-static void
-_DEFUN (htinit, (h, s, inc),
-	unsigned char *h _AND
-	unsigned char *s _AND
-	int inc)
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG)
+_CONST unsigned char __hexdig[256]=
 {
-	int i, j;
-	for(i = 0; (j = s[i]) !=0; i++)
-		h[j] = i + inc;
-}
-
-void
-_DEFUN_VOID (hexdig_init)
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0,
+	0,26,27,28,29,30,31,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,26,27,28,29,30,31,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+#else /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */
+unsigned char
+_DEFUN (__hexdig_fun, (c),
+		unsigned char c)
 {
-#define USC (unsigned char *)
-	htinit(hexdig, USC "0123456789", 0x10);
-	htinit(hexdig, USC "abcdef", 0x10 + 10);
-	htinit(hexdig, USC "ABCDEF", 0x10 + 10);
+	if(c>='0' && c<='9') return c-'0'+0x10;
+	else if(c>='a' && c<='f') return c-'a'+0x10+10;
+	else if(c>='A' && c<='F') return c-'A'+0x10+10;
+	else return 0;
 }
+#endif /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */
 
 static void
 _DEFUN(rshift, (b, k),
@@ -138,7 +148,7 @@
 _DEFUN(gethex, (ptr, sp, fpi, exp, bp, sign),
 	struct _reent *ptr _AND
 	_CONST char **sp _AND
-	FPI *fpi _AND
+	_CONST FPI *fpi _AND
 	Long *exp _AND
 	_Bigint **bp _AND
 	int sign)
@@ -153,8 +163,6 @@
 	size_t decp_len = strlen ((const char *) decimalpoint);
 	unsigned char decp_end = decimalpoint[decp_len - 1];
 
-	if (!hexdig['0'])
-		hexdig_init();
 	havedig = 0;
 	s0 = *(_CONST unsigned char **)sp + 2;
 	while(s0[havedig] == '0')
@@ -164,28 +172,28 @@
 	decpt = 0;
 	zret = 0;
 	e = 0;
-	if (!hexdig[*s]) {
+	if (!__get_hexdig(*s)) {
 		zret = 1;
 		if (strncmp ((const char *) s, (const char *) decimalpoint,
 			     decp_len) != 0)
 			goto pcheck;
 		decpt = (s += decp_len);
-		if (!hexdig[*s])
+		if (!__get_hexdig(*s))
 			goto pcheck;
 		while(*s == '0')
 			s++;
-		if (hexdig[*s])
+		if (__get_hexdig(*s))
 			zret = 0;
 		havedig = 1;
 		s0 = s;
 		}
-	while(hexdig[*s])
+	while(__get_hexdig(*s))
 		s++;
 	if (strncmp ((const char *) s, (const char *) decimalpoint,
 		     decp_len) == 0
 	    && !decpt) {
 		decpt = (s += decp_len);
-		while(hexdig[*s])
+		while(__get_hexdig(*s))
 			s++;
 		}
 	if (decpt)
@@ -203,12 +211,12 @@
 		  case '+':
 			s++;
 		  }
-		if ((n = hexdig[*s]) == 0 || n > 0x19) {
+		if ((n = __get_hexdig(*s)) == 0 || n > 0x19) {
 			s = s1;
 			break;
 			}
 		e1 = n - 0x10;
-		while((n = hexdig[*++s]) !=0 && n <= 0x19)
+		while((n = __get_hexdig(*++s)) !=0 && n <= 0x19)
 			e1 = 10*e1 + n - 0x10;
 		if (esign)
 			e1 = -e1;
@@ -236,7 +244,7 @@
 			L = 0;
 			n = 0;
 			}
-		L |= (hexdig[*s1] & 0x0f) << n;
+		L |= (__get_hexdig(*s1) & 0x0f) << n;
 		n += 4;
 		}
 	*x++ = L;
diff -ruN a/newlib/libc/stdlib/gdtoa-hexnan.c b/newlib/libc/stdlib/gdtoa-hexnan.c
--- a/newlib/libc/stdlib/gdtoa-hexnan.c	2008-03-04 19:27:01.000000000 +0100
+++ b/newlib/libc/stdlib/gdtoa-hexnan.c	2013-06-10 11:02:44.318089591 +0200
@@ -64,15 +64,13 @@
 int
 _DEFUN (hexnan, (sp, fpi, x0),
 	_CONST char **sp _AND
-	FPI *fpi _AND
+	_CONST FPI *fpi _AND
 	__ULong *x0)
 {
 	__ULong c, h, *x, *x1, *xe;
 	_CONST char *s;
 	int havedig, hd0, i, nbits;
 
-	if (!hexdig['0'])
-		hexdig_init();
 	nbits = fpi->nbits;
 	x = x0 + (nbits >> kshift);
 	if (nbits & kmask)
@@ -82,7 +80,7 @@
 	havedig = hd0 = i = 0;
 	s = *sp;
 	while((c = *(_CONST unsigned char*)++s)) {
-		if (!(h = hexdig[c])) {
+		if (!(h = __get_hexdig(c))) {
 			if (c <= ' ') {
 				if (hd0 < havedig) {
 					if (x < x1 && i < 8)
diff -ruN a/newlib/libc/stdlib/ldtoa.c b/newlib/libc/stdlib/ldtoa.c
--- a/newlib/libc/stdlib/ldtoa.c	2008-12-11 18:27:56.000000000 +0100
+++ b/newlib/libc/stdlib/ldtoa.c	2013-06-10 10:56:00.236085802 +0200
@@ -60,10 +60,10 @@
   unsigned short equot[NI];
 } LDPARMS;
 
-static void esub(short unsigned int *a, short unsigned int *b, short unsigned int *c, LDPARMS *ldp);
-static void emul(short unsigned int *a, short unsigned int *b, short unsigned int *c, LDPARMS *ldp);
-static void ediv(short unsigned int *a, short unsigned int *b, short unsigned int *c, LDPARMS *ldp);
-static int ecmp(short unsigned int *a, short unsigned int *b);
+static void esub(_CONST short unsigned int *a, _CONST short unsigned int *b, short unsigned int *c, LDPARMS *ldp);
+static void emul(_CONST short unsigned int *a, _CONST short unsigned int *b, short unsigned int *c, LDPARMS *ldp);
+static void ediv(_CONST short unsigned int *a, _CONST short unsigned int *b, short unsigned int *c, LDPARMS *ldp);
+static int ecmp(_CONST short unsigned int *a, _CONST short unsigned int *b);
 static int enormlz(short unsigned int *x);
 static int eshift(short unsigned int *x, int sc);
 static void eshup1(register short unsigned int *x);
@@ -73,7 +73,7 @@
 static void eshdn8(register short unsigned int *x);
 static void eshdn6(register short unsigned int *x);
 static void eneg(short unsigned int *x);
-static void emov(register short unsigned int *a, register short unsigned int *b);
+static void emov(register _CONST short unsigned int *a, register short unsigned int *b);
 static void eclear(register short unsigned int *x);
 static void einfin(register short unsigned int *x, register LDPARMS *ldp);
 static void efloor(short unsigned int *x, short unsigned int *y, LDPARMS *ldp);
@@ -100,22 +100,22 @@
 
 #if NE == 10
 /* 0.0 */
-static unsigned short ezero[NE] =
+static _CONST unsigned short ezero[NE] =
  {0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,};
 
 /* 1.0E0 */
-static unsigned short eone[NE] =
+static _CONST unsigned short eone[NE] =
  {0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3fff,};
 
 #else
 
 /* 0.0 */
-static unsigned short ezero[NE] = {
+static _CONST unsigned short ezero[NE] = {
 0, 0000000,0000000,0000000,0000000,0000000,};
 /* 1.0E0 */
-static unsigned short eone[NE] = {
+static _CONST unsigned short eone[NE] = {
 0, 0000000,0000000,0000000,0100000,0x3fff,};
 
 #endif
@@ -126,7 +126,7 @@
  * messages is bound to the error codes defined
  * in mconf.h.
  */
-static char *ermsg[7] = {
+static _CONST char * _CONST ermsg[7] = {
 "unknown",      /* error code 0 */
 "domain",       /* error code 1 */
 "singularity",  /* et seq.      */
@@ -411,14 +411,14 @@
 static int ecmpm(register short unsigned int *a, register short unsigned int *b);
 static int edivm(short unsigned int *den, short unsigned int *num, LDPARMS *ldp);
 static int emulm(short unsigned int *a, short unsigned int *b, LDPARMS *ldp);
-static int eisneg(short unsigned int *x);
-static int eisinf(short unsigned int *x);
-static void emovi(short unsigned int *a, short unsigned int *b);
+static int eisneg(_CONST short unsigned int *x);
+static int eisinf(_CONST short unsigned int *x);
+static void emovi(_CONST short unsigned int *a, short unsigned int *b);
 static void emovo(short unsigned int *a, short unsigned int *b, LDPARMS *ldp);
 static void emovz(register short unsigned int *a, register short unsigned int *b);
 static void ecleaz(register short unsigned int *xi);
-static void eadd1(short unsigned int *a, short unsigned int *b, short unsigned int *c, int subflg, LDPARMS *ldp);
-static int eisnan(short unsigned int *x);
+static void eadd1(_CONST short unsigned int *a, _CONST short unsigned int *b, short unsigned int *c, int subflg, LDPARMS *ldp);
+static int eisnan(_CONST short unsigned int *x);
 static int eiisnan(short unsigned int *x);
 
 #ifdef DEC
@@ -447,7 +447,7 @@
  * emov( a, b );
  */
 
-static void emov(register short unsigned int *a, register short unsigned int *b)
+static void emov(register _CONST short unsigned int *a, register short unsigned int *b)
 {
 register int i;
 
@@ -478,7 +478,7 @@
 /* Return 1 if external format number is negative,
  * else return zero.
  */
-static int eisneg(short unsigned int *x)
+static int eisneg(_CONST short unsigned int *x)
 {
 
 #ifdef NANS
@@ -495,7 +495,7 @@
 /* Return 1 if external format number has maximum possible exponent,
  * else return zero.
  */
-static int eisinf(short unsigned int *x)
+static int eisinf(_CONST short unsigned int *x)
 {
 
 if( (x[NE-1] & 0x7fff) == 0x7fff )
@@ -512,7 +512,7 @@
 
 /* Check if e-type number is not a number.
  */
-static int eisnan(short unsigned int *x)
+static int eisnan(_CONST short unsigned int *x)
 {
 
 #ifdef NANS
@@ -580,9 +580,10 @@
 /* Move in external format number,
  * converting it to internal format.
  */
-static void emovi(short unsigned int *a, short unsigned int *b)
+static void emovi(_CONST short unsigned int *a, short unsigned int *b)
 {
-register unsigned short *p, *q;
+register _CONST unsigned short *p;
+register unsigned short *q;
 int i;
 
 q = b;
@@ -1368,7 +1369,7 @@
 ;	esub( a, b, c, ldp );	 c = b - a
 */
 
-static void esub(short unsigned int *a, short unsigned int *b, short unsigned int *c, LDPARMS *ldp)
+static void esub(_CONST short unsigned int *a, _CONST short unsigned int *b, short unsigned int *c, LDPARMS *ldp)
 {
 
 #ifdef NANS
@@ -1397,7 +1398,7 @@
 
 
 
-static void eadd1(short unsigned int *a, short unsigned int *b, short unsigned int *c, int subflg, LDPARMS *ldp)
+static void eadd1(_CONST short unsigned int *a, _CONST short unsigned int *b, short unsigned int *c, int subflg, LDPARMS *ldp)
 {
 unsigned short ai[NI], bi[NI], ci[NI];
 int i, lost, j, k;
@@ -1506,7 +1507,7 @@
 ;       LDPARMS *ldp;
 ;	ediv( a, b, c, ldp );	c = b / a
 */
-static void ediv(short unsigned int *a, short unsigned int *b, short unsigned int *c, LDPARMS *ldp)
+static void ediv(_CONST short unsigned int *a, _CONST short unsigned int *b, short unsigned int *c, LDPARMS *ldp)
 {
 unsigned short ai[NI], bi[NI];
 int i;
@@ -1610,7 +1611,7 @@
 ;       LDPARMS *ldp
 ;	emul( a, b, c, ldp );	c = b * a
 */
-static void emul(short unsigned int *a, short unsigned int *b, short unsigned int *c, LDPARMS *ldp)
+static void emul(_CONST short unsigned int *a, _CONST short unsigned int *b, short unsigned int *c, LDPARMS *ldp)
 {
 unsigned short ai[NI], bi[NI];
 int i, j;
@@ -2344,7 +2345,7 @@
  *          -1 if a < b
  *          -2 if either a or b is a NaN.
  */
-static int ecmp(short unsigned int *a, short unsigned int *b)
+static int ecmp(_CONST short unsigned int *a, _CONST short unsigned int *b)
 {
 unsigned short ai[NI], bi[NI];
 register unsigned short *p, *q;
@@ -2554,7 +2555,7 @@
 #define MAXP 4096
 
 #if NE == 10
-static unsigned short etens[NTEN + 1][NE] =
+static _CONST unsigned short etens[NTEN + 1][NE] =
 {
   {0x6576, 0x4a92, 0x804a, 0x153f,
    0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,},	/* 10**4096 */
@@ -2584,7 +2585,7 @@
    0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,},	/* 10**1 */
 };
 
-static unsigned short emtens[NTEN + 1][NE] =
+static _CONST unsigned short emtens[NTEN + 1][NE] =
 {
   {0x2030, 0xcffc, 0xa1c3, 0x8123,
    0x2de3, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,},	/* 10**-4096 */
@@ -2614,7 +2615,7 @@
    0xcccc, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3ffb,},	/* 10**-1 */
 };
 #else
-static unsigned short etens[NTEN+1][NE] = {
+static _CONST unsigned short etens[NTEN+1][NE] = {
 {0xc94c,0x979a,0x8a20,0x5202,0xc460,0x7525,},/* 10**4096 */
 {0xa74d,0x5de4,0xc53d,0x3b5d,0x9e8b,0x5a92,},/* 10**2048 */
 {0x650d,0x0c17,0x8175,0x7586,0xc976,0x4d48,},
@@ -2630,7 +2631,7 @@
 {0x0000,0x0000,0x0000,0x0000,0xa000,0x4002,}, /* 10**1 */
 };
 
-static unsigned short emtens[NTEN+1][NE] = {
+static _CONST unsigned short emtens[NTEN+1][NE] = {
 {0x2de4,0x9fde,0xd2ce,0x04c8,0xa6dd,0x0ad8,}, /* 10**-4096 */
 {0x4925,0x2de4,0x3436,0x534f,0xceae,0x256b,}, /* 10**-2048 */
 {0x87a6,0xc0bd,0xda57,0x82a5,0xa2a6,0x32b5,},
@@ -2898,7 +2899,7 @@
 {
 long digit;
 unsigned short y[NI], t[NI], u[NI], w[NI];
-unsigned short *p, *r, *ten;
+_CONST unsigned short *p, *r, *ten;
 unsigned short sign;
 int i, j, k, expon, rndsav, ndigs;
 char *s, *ss;
@@ -3251,7 +3252,8 @@
 int esign, decflg, sgnflg, nexp, exp, prec, lost;
 int k, trail, c, rndsav;
 long lexp;
-unsigned short nsign, *p;
+unsigned short nsign;
+_CONST unsigned short *p;
 char *sp, *s, *lstr;
 int lenldstr;
 int mflag = 0;
@@ -3578,7 +3580,7 @@
  *
  * efloor( x, y, ldp );
  */
-static unsigned short bmask[] = {
+static _CONST unsigned short bmask[] = {
 0xffff,
 0xfffe,
 0xfffc,
@@ -3677,23 +3679,23 @@
 /* NaN bit patterns
  */
 #ifdef MIEEE
-static unsigned short nan113[8] = {
+static _CONST unsigned short nan113[8] = {
   0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
-static unsigned short nan64[6] = {0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
-static unsigned short nan53[4] = {0x7fff, 0xffff, 0xffff, 0xffff};
-static unsigned short nan24[2] = {0x7fff, 0xffff};
+static _CONST unsigned short nan64[6] = {0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};
+static _CONST unsigned short nan53[4] = {0x7fff, 0xffff, 0xffff, 0xffff};
+static _CONST unsigned short nan24[2] = {0x7fff, 0xffff};
 #else /* !MIEEE */
-static unsigned short nan113[8] = {0, 0, 0, 0, 0, 0, 0x8000, 0x7fff};
-static unsigned short nan64[6] = {0, 0, 0, 0, 0xc000, 0x7fff};
-static unsigned short nan53[4] = {0, 0, 0, 0x7ff8};
-static unsigned short nan24[2] = {0, 0x7fc0};
+static _CONST unsigned short nan113[8] = {0, 0, 0, 0, 0, 0, 0x8000, 0x7fff};
+static _CONST unsigned short nan64[6] = {0, 0, 0, 0, 0xc000, 0x7fff};
+static _CONST unsigned short nan53[4] = {0, 0, 0, 0x7ff8};
+static _CONST unsigned short nan24[2] = {0, 0x7fc0};
 #endif /* !MIEEE */
 
 
 static void enan (short unsigned int *nan, int size)
 {
 int i, n;
-unsigned short *p;
+_CONST unsigned short *p;
 
 switch( size )
 	{
diff -ruN a/newlib/libc/stdlib/mprec.h b/newlib/libc/stdlib/mprec.h
--- a/newlib/libc/stdlib/mprec.h	2012-08-07 19:52:51.000000000 +0200
+++ b/newlib/libc/stdlib/mprec.h	2013-06-10 11:06:26.255190120 +0200
@@ -370,9 +370,12 @@
 #define gethex  __gethex
 #define copybits 	__copybits
 #define hexnan	__hexnan
-#define hexdig_init 	__hexdig_init
 
-#define hexdig  __hexdig
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG)
+#define __check_hexdig(x) __hexdig[x] /* NOTE: must evaluate arg only once */
+#else /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */
+#define __check_hexdig(x) __hexdig_fun(x)
+#endif /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */
 
 #define tens __mprec_tens
 #define bigtens __mprec_bigtens
@@ -395,13 +398,15 @@
 _Bigint *	_EXFUN(lshift,(struct _reent *p, _Bigint *b, int k));
 _Bigint *	_EXFUN(diff,(struct _reent *p, _Bigint *a, _Bigint *b));
 int		_EXFUN(cmp,(_Bigint *a, _Bigint *b));
-int		_EXFUN(gethex,(struct _reent *p, _CONST char **sp, struct FPI *fpi, Long *exp, _Bigint **bp, int sign));     
+int		_EXFUN(gethex,(struct _reent *p, _CONST char **sp, _CONST struct FPI *fpi, Long *exp, _Bigint **bp, int sign));     
 double		_EXFUN(ratio,(_Bigint *a, _Bigint *b));
 __ULong		_EXFUN(any_on,(_Bigint *b, int k));
 void		_EXFUN(copybits,(__ULong *c, int n, _Bigint *b));
-void		_EXFUN(hexdig_init,(void));
+#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) || defined(_SMALL_HEXDIG)
+unsigned char _EXFUN(__hexdig_fun,(unsigned char));
+#endif /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */
 #ifdef INFNAN_CHECK
-int		_EXFUN(hexnan,(_CONST char **sp, struct FPI *fpi, __ULong *x0));
+int		_EXFUN(hexnan,(_CONST char **sp, _CONST struct FPI *fpi, __ULong *x0));
 #endif
 
 #define Bcopy(x,y) memcpy((char *)&x->_sign, (char *)&y->_sign, y->_wds*sizeof(__Long) + 2*sizeof(int))
@@ -409,7 +414,9 @@
 extern _CONST double tinytens[];
 extern _CONST double bigtens[];
 extern _CONST double tens[];
-extern unsigned char hexdig[];
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG)
+extern _CONST unsigned char __hexdig[];
+#endif /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */
 
 
 double _EXFUN(_mprec_log10,(int));
diff -ruN a/newlib/libc/stdlib/strtod.c b/newlib/libc/stdlib/strtod.c
--- a/newlib/libc/stdlib/strtod.c	2013-04-24 12:21:16.000000000 +0200
+++ b/newlib/libc/stdlib/strtod.c	2013-06-10 10:56:00.240085881 +0200
@@ -287,7 +287,7 @@
 	if (*s == '0') {
 #ifndef NO_HEX_FP
 		{
-		static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
+		static _CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
 		Long exp;
 		__ULong bits[2];
 		switch(s[1]) {
@@ -415,7 +415,7 @@
 #ifdef INFNAN_CHECK
 			/* Check for Nan and Infinity */
 			__ULong bits[2];
-			static FPI fpinan =	/* only 52 explicit bits */
+			static _CONST FPI fpinan =	/* only 52 explicit bits */
 				{ 52, 1-1023-53+1, 2046-1023-53+1, 1, SI };
 			if (!decpt)
 			 switch(c) {

Attachment: float-conversion2.patch.sig
Description: Binary data


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