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 11:29 AM, Freddie Chopin wrote:
> W dniu 2013-06-10 11:12, Federico Terraneo pisze:
>> 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.
> 
> Great!
> 
> But one thing - is the patch correct? You define a macro 
> __check_hexdig(), and in the code you use __get_hexdig(), which I 
> cannot find.

Thank you for noticing it. At one point I changed the function name,
thought I've changed the name everywhere but tried to compile the
individual files for errors to be double sure, relying on the compiler
to check for such errors. However I forgot that in C you can call a
function without having first declared it (I mostly write in C++), so
that slipped through anyway.

New patch attached.

> 
> BTW - could you check what's the size of the new function you 
> introduced (__hexdig_fun())? If it's not smaller than this 256B 
> array than this is not a size optimization (;

I've tested it compiling for the thumb2 intruction set (Cortex-M3) and
it's 52 bytes, while for the ARM instruction set is 64 bytes.

> 
> 4\/3!!
> 
> 




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

iQEcBAEBAgAGBQJRtaWQAAoJECkLFtN5Xr9f05oH/3zTFTsJWAhCp1+h9fCh/8YP
OSFqPbFk1eIA+AVFHcihyg0XlNyO7xfWAwh8jcU8FwZfGmMYDWjHnvspSxawAmOf
+MEBgaARLAsHCPX2/H0mrQ+JXnkxgcNM9QeTQbKn6JHcqaYfh9UkyzM28y2ljhC5
k7suR08K+++7yQGj38Hkb4TV594vF403VJkxlF7HU+D+9nuAUH41UYW5OlnSiGtt
NskUG3U71WUD9NHlGK4e1gkxklOI2/RRjxAv7rUqrjQcfnibnFgIHyjNTqMvYpuU
MaeBUB0/p47ZTNnxsHcHENsjlh52YAcCJdEp6+fGoxHceHS0egPZaSHdBkOfKRg=
=OTBe
-----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:42:55.102044022 +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:42:55.102044022 +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 11:42:55.106044044 +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:47:02.487270740 +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 __get_hexdig(x) __hexdig[x] /* NOTE: must evaluate arg only once */
+#else /* !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) */
+#define __get_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 11:42:55.110044069 +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]