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: long double (was "strtold?")


On Thursday 12 March 2009 09:35:00 Ralf Corsepius wrote:
> >> Hi,
> >> What about mapping the long double functions to their
> >> counterparts on platforms where a double is as wide as a long
> >> double? The attached patch introduces a flag defined in
> >> sys/features.h. You mentioned HAVE_LONG_DOUBLE_WIDER but the
> >> user may not define this flag. Do you want to generate a
> >> header file that exposes this flag? Wouldn't that result in
> >> something like config.h to be shipped with newlib or am I
> >> missing something?
> >
> > Hi,
> >
> > may I suggest deriving the flag (_DOUBLE_EQUALS_LONG_DOUBLE) from macros
> > defined by <float.h>?
>
> It likely can be done even simpler:
>
> Modern GCC's have internal defines
> __SIZEOF_LONG_DOUBLE__
> and
> __SIZEOF_DOUBLE__
Hi,
Thank you for your suggestions. The attached patch uses the macro defined in 
float.h as Konrad described. The GCC builtin macros have been submitted in 2007 
(released with GCC 4.3) while our users might use older versions.

Regards
Ken
newlib/ChangeLog:

2009-03-12  Ken Werner  <ken.werner@de.ibm.com>

        * libc/include/stdlib.h: Include float.h.
        * libc/include/stdlib.h (strtold): Declare.
        * libc/include/math.h: Include float.h and machine/math.h.
          (atanl, cosl, sinl, tanl, tanhl, frexpl, modfl, ceill, fabsl, floorl,
          log1pl, expm1l, acosl, asinl, atan2l, coshl, sinhl, expl, ldexpl,
          logl, log10l, powl, sqrtl, fmodl, hypotl, copysignl, nanl, ilogbl,
          asinhl, cbrt, nextafterl, rintl, scalbnl, exp2l, scalblnl, tgammal,
          nearbyintl, lrintl, llrintl, roundl, lroundl, truncl, remquol, fdiml, 
          fmaxl, fminl, fmal, acoshl, atanhl, remainderl, lgammal, erfl, erfcl):
          Declare.
          Remove duplicate copysign prototype.
          Fix __math_68881 define typo.
        * libc/include/machine/math.h (llround, llroundl): Declare.

Index: src/newlib/libc/include/machine/math.h
===================================================================
--- /dev/null
+++ src/newlib/libc/include/machine/math.h
@@ -0,0 +1,20 @@
+#ifndef _MACHMATH_H_
+#define _MACHMATH_H_
+
+#include <_ansi.h>
+
+_BEGIN_STD_C
+
+/* This header allows platforms to add math.h extensions.  */
+
+#ifdef __SPU__
+/* The llround prototype is missing in math.h because the common code provides
+   no implementation. Since there is SPU code for that we declare it here.  */
+extern _LONG_LONG_TYPE int llround _PARAMS((double));
+extern _LONG_LONG_TYPE int llroundl _PARAMS((long double)) asm ("llround");
+#endif  /* __SPU__ */
+
+_END_STD_C
+
+#endif  /* _MACHMATH_H_ */
+
Index: src/newlib/libc/include/math.h
===================================================================
--- src.orig/newlib/libc/include/math.h
+++ src/newlib/libc/include/math.h
@@ -5,6 +5,8 @@
 #include <sys/reent.h>
 #include <machine/ieeefp.h>
 #include "_ansi.h"
+#include <float.h>
+#include <machine/math.h>
 
 _BEGIN_STD_C
 
@@ -97,7 +99,7 @@ extern double floor _PARAMS((double));
 /* Non reentrant ANSI C functions.  */
 
 #ifndef _REENT_ONLY
-#ifndef __math_6881
+#ifndef __math_68881
 extern double acos _PARAMS((double));
 extern double asin _PARAMS((double));
 extern double atan2 _PARAMS((double, double));
@@ -231,7 +233,6 @@ extern double round _PARAMS((double));
 extern long int lround _PARAMS((double));
 extern double trunc _PARAMS((double));
 extern double remquo _PARAMS((double, double, int *));
-extern double copysign _PARAMS((double, double));
 extern double fdim _PARAMS((double, double));
 extern double fmax _PARAMS((double, double));
 extern double fmin _PARAMS((double, double));
@@ -332,10 +333,88 @@ extern float erfcf _PARAMS((float));
 extern float hypotf _PARAMS((float, float));
 #endif /* ! defined (_REENT_ONLY) */
 
+/* On platforms where a long double is as wide as a double.  */
+#if (DBL_MANT_DIG == LDBL_MANT_DIG && \
+     LDBL_MIN_EXP == DBL_MIN_EXP && \
+     LDBL_MAX_EXP == DBL_MAX_EXP)
+/* Reentrant ANSI C functions.  */
+#ifndef __math_68881
+extern long double atanl _PARAMS((long double)) asm ("atan");
+extern long double cosl _PARAMS((long double)) asm ("cos");
+extern long double sinl _PARAMS((long double)) asm ("sin");
+extern long double tanl _PARAMS((long double)) asm ("tan");
+extern long double tanhl _PARAMS((long double)) asm ("tanh");
+extern long double frexpl _PARAMS((long double value, int *)) asm ("frexp");
+extern long double modfl _PARAMS((long double, long double *)) asm ("modf");
+extern long double ceill _PARAMS((long double)) asm ("ceil");
+extern long double fabsl _PARAMS((long double)) asm ("fabs");
+extern long double floorl _PARAMS((long double)) asm ("floor");
+extern long double log1pl _PARAMS((long double)) asm ("log1p");
+extern long double expm1l _PARAMS((long double)) asm ("expm1");
+#endif /* ! defined (__math_68881) */
+/* Non reentrant ANSI C functions.  */
+#ifndef _REENT_ONLY
+#ifndef __math_68881
+extern long double acosl _PARAMS((long double)) asm ("acos");
+extern long double asinl _PARAMS((long double)) asm ("asin");
+extern long double atan2l _PARAMS((long double, long double)) asm ("atan2");
+extern long double coshl _PARAMS((long double)) asm ("cosh");
+extern long double sinhl _PARAMS((long double)) asm ("sinh");
+extern long double expl _PARAMS((long double)) asm ("exp");
+extern long double ldexpl _PARAMS((long double, int)) asm ("ldexp");
+extern long double logl _PARAMS((long double)) asm ("log");
+extern long double log10l _PARAMS((long double)) asm ("log10");
+extern long double powl _PARAMS((long double, long double)) asm ("pow");
+extern long double sqrtl _PARAMS((long double)) asm ("sqrt");
+extern long double fmodl _PARAMS((long double, long double)) asm ("fmod");
+extern long double hypotl _PARAMS((long double, long double)) asm ("hypot");
+#endif /* ! defined (__math_68881) */
+#endif /* ! defined (_REENT_ONLY) */
+extern long double copysignl _PARAMS((long double, long double))
+  asm ("copysign");
+extern long double nanl _PARAMS((const char *)) asm ("nan");
+extern int ilogbl _PARAMS((long double)) asm ("ilogb");
+extern long double asinhl _PARAMS((long double)) asm ("asinh");
+extern long double cbrtl _PARAMS((long double)) asm ("cbrt");
+extern long double nextafterl _PARAMS((long double, long double))
+  asm ("nextafter");
+extern long double rintl _PARAMS((long double)) asm ("rint");
+extern long double scalbnl _PARAMS((long double, int)) asm ("scalbn");
+extern long double exp2l _PARAMS((long double)) asm ("exp2");
+extern long double scalblnl _PARAMS((long double, long)) asm ("scalbln");
+extern long double tgammal _PARAMS((long double)) asm ("tgamma");
+extern long double nearbyintl _PARAMS((long double)) asm ("nearbyint");
+extern long int lrintl _PARAMS((long double)) asm ("lrint");
+extern _LONG_LONG_TYPE int llrintl _PARAMS((long double)) asm ("llrint");
+extern long double roundl _PARAMS((long double)) asm ("round");
+extern long lroundl _PARAMS((long double)) asm ("lround");
+extern long double truncl _PARAMS((long double)) asm ("trunc");
+extern long double remquol _PARAMS((long double, long double, int *))
+  asm ("remquo");
+extern long double fdiml _PARAMS((long double, long double)) asm ("fdim");
+extern long double fmaxl _PARAMS((long double, long double)) asm ("fmax");
+extern long double fminl _PARAMS((long double, long double)) asm ("fmin");
+extern long double fmal _PARAMS((long double, long double, long double))
+  asm ("fma");
+#ifndef _REENT_ONLY
+extern long double acoshl _PARAMS((long double)) asm ("acosh");
+extern long double atanhl _PARAMS((long double)) asm ("atanh");
+extern long double remainderl _PARAMS((long double, long double))
+  asm ("remainder");
+extern long double lgammal _PARAMS((long double)) asm ("lgamma");
+extern long double erfl _PARAMS((long double)) asm ("erf");
+extern long double erfcl _PARAMS((long double)) asm ("erfc");
+#endif /* ! defined (_REENT_ONLY) */
+#else /* #if (DBL_MANT_DIG == LDBL_MANT_DIG && \
+              LDBL_MIN_EXP == DBL_MIN_EXP && \
+              LDBL_MAX_EXP == DBL_MAX_EXP) */
 /* Other long double precision functions.  */
 extern _LONG_DOUBLE rintl _PARAMS((_LONG_DOUBLE));
 extern long int lrintl _PARAMS((_LONG_DOUBLE));
 extern _LONG_LONG_TYPE llrintl _PARAMS((_LONG_DOUBLE));
+#endif /* #if (DBL_MANT_DIG == LDBL_MANT_DIG && \
+              LDBL_MIN_EXP == DBL_MIN_EXP && \
+              LDBL_MAX_EXP == DBL_MAX_EXP) */
 
 #endif /* !defined (__STRICT_ANSI__) || defined(__cplusplus) || __STDC_VERSION__ >= 199901L */
 
Index: src/newlib/libc/include/stdlib.h
===================================================================
--- src.orig/newlib/libc/include/stdlib.h
+++ src/newlib/libc/include/stdlib.h
@@ -12,6 +12,7 @@
 #define __need_size_t
 #define __need_wchar_t
 #include <stddef.h>
+#include <float.h>
 
 #include <sys/reent.h>
 #include <machine/stdlib.h>
@@ -196,6 +197,13 @@ int	_EXFUN(_system_r,(struct _reent *, c
 
 _VOID	_EXFUN(__eprintf,(const char *, const char *, unsigned int, const char *));
 
+/* On platforms where a long double is as wide as a double.  */
+#if (DBL_MANT_DIG == LDBL_MANT_DIG && \
+     LDBL_MIN_EXP == DBL_MIN_EXP && \
+     LDBL_MAX_EXP == DBL_MAX_EXP)
+extern long double strtold (const char *, char **) asm ("strtod");
+#endif
+
 _END_STD_C
 
 #endif /* _STDLIB_H_ */

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