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]

[PATCH] Reduce RAM usage of floating point conversion functions


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


Noticed a significant use of RAM tables in floating point conversion
routines while reviewing some newlib code, and thought to submit a patch.

This patch does three things:
- - Adds a const qualifier to a couple of constant tables in strtod.c,
  this saves 40 bytes of RAM on microcontrollers. Note that this
  required to make the fpi parameter of gethex() and hexnan() const as
  well. Both functions appear to be used only inside newlib, so this
  should not be an issue.
- - Adds a const qualifier to many constant tables in ldtoa.c, this
  required to mark many pointer parameters to functions inside the same
  file const, as in fact those functions never modify the passed
  parameters. Since all modified functions are static, this should
  not be an issue as well. This results in saving around 600 bytes
  (considering both data and bss) moving those tables to rodata,
  however this only benefits targets built using
  --enable-newlib-io-long-double, since otherwise _ldtoa_r() is not used
- - 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.

Let me know what you think.

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

iQEcBAEBAgAGBQJRtJvXAAoJECkLFtN5Xr9fYQwH+QE3D6J7Wpl2IMuKRjCaCYCl
rXHSB9ITF/BzL3H8nKHacUWm2wB6owT/HBm1E27ED6kU5WTFIhL6CUFP80kOdLaR
hG5qCBySeblM84Jxvo0brjnQauticrSWcLRmAtNE1Pe6AiKLtPpBI/LP5hTWisj9
ntACkKGwchBWrtXyvFrzsKRhRUdrKLC8N+dSTFh/+c31Tbz8RoCPiKr+P5I1M04x
aVw+EXacpdWT6OzB8BGCsJrnKJBViEe+ZCEU62a35m9n4prMmKBe0+6X0bpvGCvQ
M6iV6fNMZMEw1AA4FuKPkI8X9pk33lmHVfnH6iN5kyoOwtoxZV2Dm1DZ/bjOrbo=
=+HbO
-----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-09 16:37:30.027146580 +0200
@@ -37,7 +37,8 @@
 #include "gd_qnan.h"
 #include "locale.h"
 
-unsigned char hexdig[256];
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG)
+unsigned char __hexdig[256];
 
 static void
 _DEFUN (htinit, (h, s, inc),
@@ -54,10 +55,21 @@
 _DEFUN_VOID (hexdig_init)
 {
 #define USC (unsigned char *)
-	htinit(hexdig, USC "0123456789", 0x10);
-	htinit(hexdig, USC "abcdef", 0x10 + 10);
-	htinit(hexdig, USC "ABCDEF", 0x10 + 10);
+	htinit(__hexdig, USC "0123456789", 0x10);
+	htinit(__hexdig, USC "abcdef", 0x10 + 10);
+	htinit(__hexdig, USC "ABCDEF", 0x10 + 10);
 }
+#else /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */
+unsigned char
+_DEFUN (__hexdig_fun, (c),
+		unsigned char c)
+{
+	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 +150,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 +165,10 @@
 	size_t decp_len = strlen ((const char *) decimalpoint);
 	unsigned char decp_end = decimalpoint[decp_len - 1];
 
-	if (!hexdig['0'])
+	#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG)
+	if (!__hexdig['0'])
 		hexdig_init();
+	#endif /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */
 	havedig = 0;
 	s0 = *(_CONST unsigned char **)sp + 2;
 	while(s0[havedig] == '0')
@@ -164,28 +178,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 +217,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 +250,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-09 16:37:30.027146580 +0200
@@ -64,15 +64,17 @@
 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'])
+	#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG)
+	if (!__hexdig['0'])
 		hexdig_init();
+	#endif /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */
 	nbits = fpi->nbits;
 	x = x0 + (nbits >> kshift);
 	if (nbits & kmask)
@@ -82,7 +84,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-09 16:37:30.031146603 +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-09 16:37:30.031146603 +0200
@@ -370,9 +370,13 @@
 #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 hexdig_init 	__hexdig_init
+#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 +399,17 @@
 _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));
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG)
 void		_EXFUN(hexdig_init,(void));
+#else /* !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 +417,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 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-09 16:37:30.031146603 +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-conversion.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]