Skip to content

Commit dda0d14

Browse files
committed
libm: Handle 32-bit double/64-bit long double
There were lots of assumptions that doubles were 64-bits remaining in the library. Handle cases where float and double are 32-bits while long double is 64-bits. Signed-off-by: Keith Packard <[email protected]>
1 parent 5ced76b commit dda0d14

35 files changed

+307
-255
lines changed

newlib/libc/include/machine/ieeefp.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,14 @@ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8989
# endif
9090
#endif
9191

92+
#if __SIZEOF_DOUBLE__ == __SIZEOF_FLOAT__
93+
# define _DBL_EQ_FLT
94+
#endif
95+
96+
#if __SIZEOF_LONG_DOUBLE == __SIZEOF_DOUBLE__
97+
# define LDBL_EQ_DBL
98+
#endif
99+
92100
#if __SIZEOF_DOUBLE__ == 4
93101
# define _DOUBLE_IS_32BITS
94102
#endif
@@ -97,14 +105,6 @@ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
97105
# define _LONG_DOUBLE_IS_32BITS
98106
#endif
99107

100-
#if defined(__SIZEOF_FLOAT__) && defined(__SIZEOF_DOUBLE__)
101-
# if __SIZEOF_FLOAT__ == __SIZEOF_DOUBLE__
102-
# define _DBL_EQ_FLT
103-
# else
104-
# undef _DBL_EQ_FLT
105-
#endif
106-
#endif
107-
108108
#if (defined(__arm__) || defined(__thumb__)) && !defined(__MAVERICK__)
109109
/* arm with hard fp and soft dp cannot use new float code */
110110
# if (__ARM_FP & 4) && !(__ARM_FP & 8)
@@ -230,13 +230,14 @@ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
230230

231231

232232
#ifdef __sh__
233-
#ifdef __LITTLE_ENDIAN__
233+
#define _IEEE_754_2008_SNAN 0
234+
#if __FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__
234235
#define __IEEE_LITTLE_ENDIAN
235-
#else
236+
#elif __FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__
236237
#define __IEEE_BIG_ENDIAN
237238
#endif
238-
#if defined(__SH2E__) || defined(__SH3E__) || defined(__SH4_SINGLE_ONLY__) || defined(__SH2A_SINGLE_ONLY__)
239-
#define _DOUBLE_IS_32BITS
239+
#ifdef __SH_FPU_ANY__
240+
#define _SUPPORTS_ERREXCEPT
240241
#endif
241242
#endif
242243

newlib/libc/include/math.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -350,11 +350,7 @@ int __issignalingf(float f);
350350
int __issignaling(double d);
351351

352352
#if defined(_HAVE_LONG_DOUBLE)
353-
#if __SIZEOF_LONG_DOUBLE__ == __SIZEOF_DOUBLE__ && __SIZEOF_DOUBLE__ > 0
354-
static inline int __issignalingl(long double d) { return __issignaling((double) d); }
355-
#else
356353
int __issignalingl(long double d);
357-
#endif
358354
#define issignaling(__x) \
359355
((sizeof(__x) == sizeof(float)) ? __issignalingf(__x) : \
360356
(sizeof(__x) == sizeof(double)) ? __issignaling ((double) (__x)) : \

newlib/libm/common/exp.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,13 @@ specialcase (double_t tmp, uint64_t sbits, uint64_t ki)
6161
{
6262
/* k > 0, the exponent of scale might have overflowed by <= 460. */
6363
sbits -= 1009ull << 52;
64-
scale = asdouble (sbits);
64+
scale = asfloat64 (sbits);
6565
y = 0x1p1009 * (scale + scale * tmp);
6666
return check_oflow (y);
6767
}
6868
/* k < 0, need special care in the subnormal range. */
6969
sbits += 1022ull << 52;
70-
scale = asdouble (sbits);
70+
scale = asfloat64 (sbits);
7171
y = scale + scale * tmp;
7272
if (y < 1.0)
7373
{
@@ -148,7 +148,7 @@ exp (double x)
148148
/* 2^(k/N) ~= scale * (1 + tail). */
149149
idx = 2 * (ki % N);
150150
top = ki << (52 - EXP_TABLE_BITS);
151-
tail = asdouble (T[idx]);
151+
tail = asfloat64 (T[idx]);
152152
/* This is only a valid scale when -1023*N < k < 1024*N. */
153153
sbits = T[idx + 1] + top;
154154
/* exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1). */
@@ -165,7 +165,7 @@ exp (double x)
165165
#endif
166166
if (unlikely (abstop == 0))
167167
return specialcase (tmp, sbits, ki);
168-
scale = asdouble (sbits);
168+
scale = asfloat64 (sbits);
169169
/* Note: tmp == 0 or |tmp| > 2^-65 and scale > 2^-739, so there
170170
is no spurious underflow here even without fma. */
171171
return scale + scale * tmp;

newlib/libm/common/exp2.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ specialcase (double_t tmp, uint64_t sbits, uint64_t ki)
5959
{
6060
/* k > 0, the exponent of scale might have overflowed by 1. */
6161
sbits -= 1ull << 52;
62-
scale = asdouble (sbits);
62+
scale = asfloat64 (sbits);
6363
y = 2 * (scale + scale * tmp);
6464
return check_oflow (y);
6565
}
6666
/* k < 0, need special care in the subnormal range. */
6767
sbits += 1022ull << 52;
68-
scale = asdouble (sbits);
68+
scale = asfloat64 (sbits);
6969
y = scale + scale * tmp;
7070
if (y < 1.0)
7171
{
@@ -135,7 +135,7 @@ exp2 (double x)
135135
/* 2^(k/N) ~= scale * (1 + tail). */
136136
idx = 2 * (ki % N);
137137
top = ki << (52 - EXP_TABLE_BITS);
138-
tail = asdouble (T[idx]);
138+
tail = asfloat64 (T[idx]);
139139
/* This is only a valid scale when -1023*N < k < 1024*N. */
140140
sbits = T[idx + 1] + top;
141141
/* exp2(x) = 2^(k/N) * 2^r ~= scale + scale * (tail + 2^r - 1). */
@@ -152,7 +152,7 @@ exp2 (double x)
152152
#endif
153153
if (unlikely (abstop == 0))
154154
return specialcase (tmp, sbits, ki);
155-
scale = asdouble (sbits);
155+
scale = asfloat64 (sbits);
156156
/* Note: tmp == 0 or |tmp| > 2^-65 and scale > 2^-928, so there
157157
is no spurious underflow here even without fma. */
158158
return scale + scale * tmp;

newlib/libm/common/fdlibm.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,13 +168,15 @@
168168

169169
#define X_TLOSS 1.41484755040568800000e+16
170170

171+
#ifdef _NEED_FLOAT64
171172
extern __int32_t __rem_pio2 (__float64,__float64*);
172173

173174
/* fdlibm kernel function */
174175
extern __float64 __kernel_sin (__float64,__float64,int);
175176
extern __float64 __kernel_cos (__float64,__float64);
176177
extern __float64 __kernel_tan (__float64,__float64,int);
177178
extern int __kernel_rem_pio2 (__float64*,__float64*,int,int,int,const __int32_t*);
179+
#endif
178180

179181
extern __int32_t __rem_pio2f (float,float*);
180182

@@ -267,7 +269,7 @@ do { \
267269
ieee_double_shape_type iw_u; \
268270
iw_u.parts.msw = (ix0); \
269271
iw_u.parts.lsw = (ix1); \
270-
(d) = asdouble(iw_u.bits); \
272+
(d) = asfloat64(iw_u.bits); \
271273
} while (0)
272274

273275
/* Set the more significant 32 bits of a double from an int. */
@@ -277,7 +279,7 @@ do { \
277279
ieee_double_shape_type sh_u; \
278280
sh_u.bits = asuint64(d); \
279281
sh_u.parts.msw = (v); \
280-
(d) = asdouble(sh_u.bits); \
282+
(d) = asfloat64(sh_u.bits); \
281283
} while (0)
282284

283285
/* Set the less significant 32 bits of a double from an int. */
@@ -287,7 +289,7 @@ do { \
287289
ieee_double_shape_type sl_u; \
288290
sl_u.bits = asuint64(d); \
289291
sl_u.parts.lsw = (v); \
290-
(d) = asdouble(sl_u.bits); \
292+
(d) = asfloat64(sl_u.bits); \
291293
} while (0)
292294

293295
/* A union which permits us to convert between a float and a 32 bit

newlib/libm/common/log.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ log (double x)
142142
iz = ix - (tmp & 0xfffULL << 52);
143143
invc = T[i].invc;
144144
logc = T[i].logc;
145-
z = asdouble (iz);
145+
z = asfloat64 (iz);
146146

147147
/* log(x) = log1p(z/c-1) + log(c) + k*Ln2. */
148148
/* r ~= z/c - 1, |r| < 1/(2*N). */

newlib/libm/common/log2.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ double
7777
lo = r * InvLn2lo + fma (r, InvLn2hi, -hi);
7878
#else
7979
double_t rhi, rlo;
80-
rhi = asdouble (asuint64 (r) & -1ULL << 32);
80+
rhi = asfloat64 (asuint64 (r) & -1ULL << 32);
8181
rlo = r - rhi;
8282
hi = rhi * InvLn2hi;
8383
lo = rlo * InvLn2hi + r * InvLn2lo;
@@ -118,7 +118,7 @@ double
118118
iz = ix - (tmp & 0xfffULL << 52);
119119
invc = T[i].invc;
120120
logc = T[i].logc;
121-
z = asdouble (iz);
121+
z = asfloat64 (iz);
122122
kd = (double_t) k;
123123

124124
/* log2(x) = log2(z/c) + log2(c) + k. */
@@ -132,7 +132,7 @@ double
132132
double_t rhi, rlo;
133133
/* rounding error: 0x1p-55/N + 0x1p-65. */
134134
r = (z - T2[i].chi - T2[i].clo) * invc;
135-
rhi = asdouble (asuint64 (r) & -1ULL << 32);
135+
rhi = asfloat64 (asuint64 (r) & -1ULL << 32);
136136
rlo = r - rhi;
137137
t1 = rhi * InvLn2hi;
138138
t2 = rlo * InvLn2hi + r * InvLn2lo;

0 commit comments

Comments
 (0)