Skip to content

Commit 9e35465

Browse files
committed
tinystdio: Support 32-bit double/64-bit long double configurations
Deal with using double or long double for the 64-bit datatype. Signed-off-by: Keith Packard <[email protected]>
1 parent 885f884 commit 9e35465

39 files changed

+1613
-735
lines changed

newlib/libc/include/stdlib.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,15 @@ int fcvtf_r (float, int, int*, int*, char *, size_t);
267267
#else
268268
char * fcvtfbuf (float, int, int*, int*, char *);
269269
#endif
270+
271+
#if defined(_HAVE_LONG_DOUBLE) && defined(TINY_STDIO)
272+
char * ecvtl(long double, int, int*, int*);
273+
int ecvtl_r(long double, int, int*, int*, char *, size_t);
274+
char * fcvtl(long double, int, int*, int*);
275+
int fcvtl_r(long double, int, int*, int*, char *, size_t);
276+
char * gcvtl(long double, int, char *);
277+
#endif
278+
270279
#endif
271280
char * __itoa (int, char *, int);
272281
char * __utoa (unsigned, char *, int);

newlib/libc/tinystdio/CMakeLists.txt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,20 @@ picolibc_sources(
3737
bufio.c
3838
clearerr.c
3939
compare_exchange.c
40+
dtox_engine.c
4041
ecvt_r.c
4142
ecvt.c
4243
ecvtf_r.c
4344
ecvtf.c
45+
ecvtl_r.c
46+
ecvtl.c
4447
exchange.c
4548
fcvt.c
4649
fcvt_r.c
4750
fcvtf.c
4851
fcvtf_r.c
49-
gcvt.c
50-
gcvtf.c
52+
fcvtl.c
53+
fcvtl_r.c
5154
fclose.c
5255
fdevopen.c
5356
feof.c
@@ -75,15 +78,21 @@ picolibc_sources(
7578
fseeko.c
7679
ftell.c
7780
ftello.c
81+
ftox_engine.c
7882
fwide.c
7983
fwrite.c
8084
fwprintf.c
8185
fwscanf.c
86+
gcvt.c
87+
gcvtf.c
88+
gcvtl.c
8289
getchar.c
8390
getdelim.c
8491
getline.c
8592
gets.c
8693
getwchar.c
94+
ldtoa_engine.c
95+
ldtox_engine.c
8796
matchcaseprefix.c
8897
mktemp.c
8998
perror.c

newlib/libc/tinystdio/atod_engine.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@
3030
POSSIBILITY OF SUCH DAMAGE.
3131
*/
3232

33-
#define _WANT_IO_DOUBLE
33+
#include "stdio_private.h"
3434

35-
typedef double FLOAT;
35+
#ifdef FLOAT64
3636

37-
#include "dtoa_engine.h"
37+
#define _NEED_IO_DOUBLE
38+
39+
#include "dtoa.h"
3840

3941
#if __GNUC__ == 12 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ == 1 && __OPTIMIZE_SIZE__
4042
/*
@@ -45,10 +47,10 @@ typedef double FLOAT;
4547
#pragma GCC optimize("O2")
4648
#endif
4749

48-
double
50+
FLOAT64
4951
__atod_engine(uint64_t u64, int exp)
5052
{
51-
double flt = u64;
53+
FLOAT64 flt = u64;
5254

5355
while (exp < 0) {
5456
flt *= 1e-1;
@@ -60,3 +62,5 @@ __atod_engine(uint64_t u64, int exp)
6062
}
6163
return flt;
6264
}
65+
66+
#endif

newlib/libc/tinystdio/atod_ryu.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@
2929
#include "ryu/common.h"
3030
#include "ryu/d2s_intrinsics.h"
3131

32+
#if __SIZEOF_DOUBLE__ == 8
33+
#define FLOAT64 double
34+
#elif __SIZEOF_LONG_DOUBLE__ == 8
35+
#define FLOAT64 long double
36+
#endif
37+
38+
#ifdef FLOAT64
39+
3240
#define DOUBLE_MANTISSA_BITS 52
3341
#define DOUBLE_EXPONENT_BITS 11
3442
#define DOUBLE_EXPONENT_BIAS 1023
@@ -54,13 +62,13 @@ static inline int32_t max32(int32_t a, int32_t b) {
5462
return a < b ? b : a;
5563
}
5664

57-
static inline double int64Bits2Double(uint64_t bits) {
58-
double f;
59-
memcpy(&f, &bits, sizeof(double));
65+
static inline FLOAT64 int64Bits2Double(uint64_t bits) {
66+
FLOAT64 f;
67+
memcpy(&f, &bits, sizeof(FLOAT64));
6068
return f;
6169
}
6270

63-
double
71+
FLOAT64
6472
__atod_engine(uint64_t m10, int e10)
6573
{
6674
#ifdef RYU_DEBUG
@@ -159,3 +167,4 @@ __atod_engine(uint64_t m10, int e10)
159167
return int64Bits2Double(ieee);
160168
}
161169

170+
#endif /* FLOAT64 */

newlib/libc/tinystdio/atof_engine.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,9 @@
3030
POSSIBILITY OF SUCH DAMAGE.
3131
*/
3232

33-
#define _WANT_IO_FLOAT
33+
#define _NEED_IO_FLOAT
3434

35-
typedef float FLOAT;
36-
37-
#include "dtoa_engine.h"
35+
#include "dtoa.h"
3836

3937
#if __GNUC__ == 12 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ == 1 && __OPTIMIZE_SIZE__
4038
/*
@@ -51,11 +49,11 @@ __atof_engine(uint32_t u32, int exp)
5149
float flt = u32;
5250

5351
while (exp < 0) {
54-
flt *= 1e-1f;
52+
flt *= (float) 1e-1f;
5553
exp++;
5654
}
5755
while (exp > 0) {
58-
flt *= 1e1f;
56+
flt *= (float) 1e1f;
5957
exp--;
6058
}
6159
return flt;

newlib/libc/tinystdio/atof_ryu.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include <stdlib.h>
2121
#include <string.h>
2222

23+
#include "stdio_private.h"
24+
2325
#ifdef RYU_DEBUG
2426
#include <inttypes.h>
2527
#include <stdio.h>
@@ -69,9 +71,9 @@ float
6971
__atof_engine(uint32_t m10, int e10)
7072
{
7173
#ifdef RYU_DEBUG
72-
printf("m10digits = %d\n", m10);
74+
printf("m10digits = %ld\n", m10);
7375
printf("e10digits = %d\n", e10);
74-
printf("m10 * 10^e10 = %u * 10^%d\n", m10, e10);
76+
printf("m10 * 10^e10 = %lu * 10^%d\n", m10, e10);
7577
#endif
7678

7779
// Convert to binary float m2 * 2^e2, while retaining information about whether the conversion
@@ -124,7 +126,7 @@ __atof_engine(uint32_t m10, int e10)
124126
}
125127

126128
#ifdef RYU_DEBUG
127-
printf("m2 * 2^e2 = %u * 2^%d\n", m2, e2);
129+
printf("m2 * 2^e2 = %lu * 2^%ld\n", m2, e2);
128130
#endif
129131

130132
// Compute the final IEEE exponent.
@@ -142,8 +144,8 @@ __atof_engine(uint32_t m10, int e10)
142144
int32_t shift = (ieee_e2 == 0 ? 1 : ieee_e2) - e2 - FLOAT_EXPONENT_BIAS - FLOAT_MANTISSA_BITS;
143145
assert(shift >= 0);
144146
#ifdef RYU_DEBUG
145-
printf("ieee_e2 = %d\n", ieee_e2);
146-
printf("shift = %d\n", shift);
147+
printf("ieee_e2 = %ld\n", ieee_e2);
148+
printf("shift = %ld\n", shift);
147149
#endif
148150

149151
// We need to round up if the exact value is more than 0.5 above the value we computed. That's
@@ -157,7 +159,7 @@ __atof_engine(uint32_t m10, int e10)
157159

158160
#ifdef RYU_DEBUG
159161
printf("roundUp = %d\n", roundUp);
160-
printf("ieee_m2 = %u\n", (m2 >> shift) + roundUp);
162+
printf("ieee_m2 = %lu\n", (m2 >> shift) + roundUp);
161163
#endif
162164
uint32_t ieee_m2 = (m2 >> shift) + roundUp;
163165
assert(ieee_m2 <= (1u << (FLOAT_MANTISSA_BITS + 1)));

0 commit comments

Comments
 (0)