Message ID | 20200826170357.2551683-3-keithp@keithp.com |
---|---|
State | New |
Headers | show |
Series |
|
Related | show |
Hi Keith, On Aug 26 10:03, Keith Packard via Newlib wrote: > Gamma should consume the sign reported by lgamma internally instead of > providing it back to the application. This removes the need to have _r > variants as there is no longer any re-entrancy issues with the API. You can't do that. gamma_r/gammaf_r/lgamma_r/lgammaf_r are BSD functions. They have been exported by Cygwin since 2001. The entry points need to be kept available with unchanged semantics. Corinna
Corinna Vinschen via Newlib <newlib@sourceware.org> writes: > You can't do that. gamma_r/gammaf_r/lgamma_r/lgammaf_r are BSD > functions. They have been exported by Cygwin since 2001. The entry > points need to be kept available with unchanged semantics. They changed on accident in 2002 -- gamma_r *used* to be an alias for lgamma_r and was changed to be a (broken) alias for tgamma. -- -keith
On Aug 26 12:10, Keith Packard via Newlib wrote: > Corinna Vinschen via Newlib <newlib@sourceware.org> writes: > > > You can't do that. gamma_r/gammaf_r/lgamma_r/lgammaf_r are BSD > > functions. They have been exported by Cygwin since 2001. The entry > > points need to be kept available with unchanged semantics. > > They changed on accident in 2002 -- gamma_r *used* to be an alias for > lgamma_r and was changed to be a (broken) alias for tgamma. Nevertheless, the symbols have to be exported for backward compatibility. So you're saying aliasing gamma_r to lgamma_r and gammaf_r to lgammaf_r in the DLLs export table would be sufficient? Thanks, Corinna
Corinna Vinschen via Newlib <newlib@sourceware.org> writes: > Nevertheless, the symbols have to be exported for backward compatibility. > So you're saying aliasing gamma_r to lgamma_r and gammaf_r to lgammaf_r > in the DLLs export table would be sufficient? It depends if you want the pre-2002 functionality or the post-2002 functionality. Before 2002, gamma_r and gammaf_r were as BSD originally specified them, returning the log of gamma (ln(|Γ(x)|)) with the sign of gamma stored through the second, int *, argument. In 2002, this patch was made to er_gamma.c: $ git show 0953fe640f177b565578ed7ecc77169ec1a914fa er_gamma.c diff --git a/newlib/libm/math/er_gamma.c b/newlib/libm/math/er_gamma.c index a7183c50f..3c0e241e5 100644 @@ -28,5 +28,5 @@ double x; int *signgamp; #endif { - return __ieee754_lgamma_r(x,signgamp); + return __ieee754_exp (__ieee754_lgamma_r(x,signgamp)); } Before this patch, __ieee754_gamma_r was simply another name for __ieee754_lgamma_r. After this patch, __ieee754_gamma_r became something that doesn't exist in any other math library: it returns |Γ(x)| and stores the sign through the second, int *, argument. Internally, this is used in w_gamma.c, w_tgamma.c, wr_gamma.c. w_tgamma.c uses it correctly: y = __ieee754_gamma_r(x,&local_signgam); if (local_signgam < 0) y = -y; w_gamma.c, which exports the 'gamma' function uses it *incorrectly* -- it didn't change after the above patch, and so it unexpectedly changed from returning ln(|Γ(x)|) to returning |Γ(x)|. Applications using 'gamma' instead of 'tgamma' will be getting the wrong answer for some parameters. I have to assume this was just an oversight. In 2009, another patch to w_gamma.c adds a comment explicitly stating that gamma and gamma_r return ln(|Γ(x)|), when in fact they had been changed to |Γ(x)| due to the change to __ieee754_gamma_r in the above patch. Even today, wr_gamma.c says: double gamma_r(double x, int *signgamp) /* wrapper lgamma_r */ which is incorrect, as it calls __ieee754_gamma_r. I see a couple of options here: 1) Leave things as they are. This makes the 'gamma' family of functions incompatible with all other libc implementations and creates a trap for applications expecting either lgamma or tgamma values. 2) Finish the work started in 2002 and make the 'gamma' family compatible with their 'tgamma' equivalents. This is what my patch does. This makes newlib compatible with 4.4 BSD libc, and leaves 'gamma' returning the same value anytime that value is non-negative. 3) Revert the 2002 change so that all of the 'gamma' family return the same value as their lgamma equivalents. That would make gamma_r useful again, as an alias for lgamma_r. This would make newlib compatible with glibc. 4) Remove the 'gamma' family completely. Given that the meaning of 'gamma' differs between 4.4 BSD and glibc, it would be safest to force applications to select between tgamma and lgamma. I chose option 2 because that offers the best API compatibility -- the gamma functions return the same value for most arguments (any positive arguments, and half of negative arguments). Any code using the gamma_r functions are likely expecting that to return lgamma_r (as documented in several places). I can't see how we can leave that function in the library as-is responsibly. -- -keith
On Aug 27 10:05, Keith Packard via Newlib wrote: > Corinna Vinschen via Newlib <newlib@sourceware.org> writes: > > > Nevertheless, the symbols have to be exported for backward compatibility. > > So you're saying aliasing gamma_r to lgamma_r and gammaf_r to lgammaf_r > > in the DLLs export table would be sufficient? > > It depends if you want the pre-2002 functionality or the post-2002 > functionality. The important point is that gamma_r and gammaf_r are exported by Cygwin and must be kept available, otherwise building the DLL fails. If they returned the wrong vaslue, that's a bug and needs fixing. Whether gamma_r and gammaf_r are still functions on their own, or if they are just defined as aliases to lgamma_r and lgammaf_r in winsup/cygwin/common.din, as in gamma_r = lgamma_r NOSIGFE gammaf_r = lgammaf_r NOSIGFE is up to you. Corinna
On Aug 28 10:19, Corinna Vinschen via Newlib wrote: > On Aug 27 10:05, Keith Packard via Newlib wrote: > > Corinna Vinschen via Newlib <newlib@sourceware.org> writes: > > > > > Nevertheless, the symbols have to be exported for backward compatibility. > > > So you're saying aliasing gamma_r to lgamma_r and gammaf_r to lgammaf_r > > > in the DLLs export table would be sufficient? > > > > It depends if you want the pre-2002 functionality or the post-2002 > > functionality. > > The important point is that gamma_r and gammaf_r are exported by Cygwin > and must be kept available, otherwise building the DLL fails. If they > returned the wrong vaslue, that's a bug and needs fixing. > > Whether gamma_r and gammaf_r are still functions on their own, or if > they are just defined as aliases to lgamma_r and lgammaf_r in > winsup/cygwin/common.din, as in > > gamma_r = lgamma_r NOSIGFE > gammaf_r = lgammaf_r NOSIGFE > > is up to you. On second thought, given gamma_r and gammaf_r are BSD functions, it might be a good idea to keep the wrapper functions for other targets as well. Any input from the RTEMS guys, perhaps? Thanks, Corinna
Hi Keith, We welcome your efforts to clean up - and correct the error return values of - the gamma/lgamma/tgamma families. Regarding Corinna's concern with lgamma_r/gamma_r being BSD-functions: > You can't do that. gamma_r/gammaf_r/lgamma_r/lgammaf_r are BSD > functions. They have been exported by Cygwin since 2001. The entry > points need to be kept available with unchanged semantics. We would favor the removal of all non C/POSIX(+XSI)-standard functions from the interface. The reason to regard lgamma_r and gamma_r as "BSD-functions" comes from the fact that BSD (same as newlib) took fdlibm as the base for its libm back in the early 90s when some non-standard functions were part of that library. We would encourage the use of only the C/POSIX(+XSI)-standard functions as the only way to get rid of the confusing semantics of the historical function interfaces otherwise the problem will only perpetuate into the future. If something was changed in 2002, that is working incorrectly and no one found out until now, that is also not part of any standard, it suggests that no one is actually using it and should be able to be safely removed. Does Newlib have a policy to remove elements? An interesting discussion about the standard lgamma/tgamma functions would be to discuss accuracy improvements in line with the glibc improvements from Joseph Myers (see https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=050f29c18873ec05ba04a4034bed8cb3f6ae4463). Best regards, Fabian
Fabian Schriever <fabian.schriever@gtd-gmbh.de> writes: > Hi Keith, > > We welcome your efforts to clean up - and correct the error return > values of - the gamma/lgamma/tgamma families. Thanks! I'm doing continuous integration testing as a part of embedded toolchain support for RISC-V as part of my SiFive dayjob; fixing bugs like this is part of that process. > We would favor the removal of all non C/POSIX(+XSI)-standard functions > from the interface. Oh, that's probably the best idea of all. Applications should not be using 'gamma' at all given the different definitions over time and space. Any thoughts about the newlib __ieee754 interfaces? Those are essentially the same as the C/POSIX interfaces but do not use errno or other global variables, reporting exceptions only through the fenv API. > If something was changed in 2002, that is working incorrectly and no one > found out until now, that is also not part of any standard, it suggests > that no one is actually using it and should be able to be safely > removed. Does Newlib have a policy to remove elements? I don't think it's 'newlib' which would need any policy; newlib is used downstream in a wide variety of projects, including cygwin and picolibc, which may have separate policies. Cygwin has binary interface definitions, changing those could affect applications there. I'm using newlib as part of picolibc which is used for embedded toolchains where removing things from the ABI to fix bugs would be just fine. > An interesting discussion about the standard lgamma/tgamma functions > would be to discuss accuracy improvements in line with the glibc > improvements from Joseph Myers (see > https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=050f29c18873ec05ba04a4034bed8cb3f6ae4463). I read through that patch and agree that it would be nice to incorporate something similar. We need to be cautious as code cannot be directly brought in from glibc due to licensing differences. -- -keith
On Sep 1 10:23, Keith Packard via Newlib wrote: > Fabian Schriever <fabian.schriever@gtd-gmbh.de> writes: > > > Hi Keith, > > > > We welcome your efforts to clean up - and correct the error return > > values of - the gamma/lgamma/tgamma families. > > Thanks! I'm doing continuous integration testing as a part of embedded > toolchain support for RISC-V as part of my SiFive dayjob; fixing bugs > like this is part of that process. > > > We would favor the removal of all non C/POSIX(+XSI)-standard functions > > from the interface. > > Oh, that's probably the best idea of all. Applications should not be > using 'gamma' at all given the different definitions over time and > space. > > Any thoughts about the newlib __ieee754 interfaces? Those are > essentially the same as the C/POSIX interfaces but do not use errno or > other global variables, reporting exceptions only through the fenv API. > > > If something was changed in 2002, that is working incorrectly and no one > > found out until now, that is also not part of any standard, it suggests > > that no one is actually using it and should be able to be safely > > removed. Does Newlib have a policy to remove elements? > > I don't think it's 'newlib' which would need any policy; newlib is used > downstream in a wide variety of projects, including cygwin and picolibc, > which may have separate policies. Cygwin has binary interface > definitions, changing those could affect applications there. Removing interfaces is not an option for Cygwin. If you remove functions from newlib exported as symbols in Cygwin, you must provide replacement interfaces for Cygwin alone, otherwise Cygwin won't build anymore. And one step further, removing interfaces from the list of exported symbols of the Cygwin DLL will break user space and that's simply a no-no. Corinna
Corinna Vinschen via Newlib <newlib@sourceware.org> writes: > Removing interfaces is not an option for Cygwin. If you remove > functions from newlib exported as symbols in Cygwin, you must provide > replacement interfaces for Cygwin alone, otherwise Cygwin won't build > anymore. And one step further, removing interfaces from the list of > exported symbols of the Cygwin DLL will break user space and that's > simply a no-no. Then tell us what you want gamma and gamma_r to do for Cygwin. They're non-standard interfaces for POSIX, C99 and C17, so you get to pick. Removing them for non-Cygwin uses appears to be the safest choice as that will (intentionally) break applications which were expecting them to implement either the BSD or Linux behavior, when in fact they do neither (!). -- -keith
On Sep 2 13:37, Keith Packard via Newlib wrote: > Corinna Vinschen via Newlib <newlib@sourceware.org> writes: > > > Removing interfaces is not an option for Cygwin. If you remove > > functions from newlib exported as symbols in Cygwin, you must provide > > replacement interfaces for Cygwin alone, otherwise Cygwin won't build > > anymore. And one step further, removing interfaces from the list of > > exported symbols of the Cygwin DLL will break user space and that's > > simply a no-no. > > Then tell us what you want gamma and gamma_r to do for Cygwin. I did: https://sourceware.org/pipermail/newlib/2020/017946.html Thanks, Corinna
On 2020-09-03 02:04, Corinna Vinschen via Newlib wrote: > On Sep 2 13:37, Keith Packard via Newlib wrote: >> Corinna Vinschen via Newlib <newlib@sourceware.org> writes: >> >>> Removing interfaces is not an option for Cygwin. If you remove >>> functions from newlib exported as symbols in Cygwin, you must provide >>> replacement interfaces for Cygwin alone, otherwise Cygwin won't build >>> anymore. And one step further, removing interfaces from the list of >>> exported symbols of the Cygwin DLL will break user space and that's >>> simply a no-no. >> >> Then tell us what you want gamma and gamma_r to do for Cygwin. > > I did: https://sourceware.org/pipermail/newlib/2020/017946.html FYI docs/spec: https://sca.uwaterloo.ca/coldfire/gcc-doc/docs/libm_21.html#SEC21 http://www.ece.ualberta.ca/~cmpe401/docs/coldfire/libm.pdf#page=20 https://ftp.rtems.org/pub/rtems/docs/3.2.0/libm-3.2.0.ps - see p.18 -- Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada This email may be disturbing to some readers as it contains too much technical detail. Reader discretion is advised. [Data in IEC units and prefixes, physical quantities in SI.]
Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes: >>> Then tell us what you want gamma and gamma_r to do for Cygwin. >> >> I did: https://sourceware.org/pipermail/newlib/2020/017946.html Oops! I appear to have missed that mail. > FYI docs/spec: > https://sca.uwaterloo.ca/coldfire/gcc-doc/docs/libm_21.html#SEC21 > http://www.ece.ualberta.ca/~cmpe401/docs/coldfire/libm.pdf#page=20 > https://ftp.rtems.org/pub/rtems/docs/3.2.0/libm-3.2.0.ps - see p.18 That's quite helpful actually and says that cygwin's gamma matches glibc, which makes the change from 2002 just a bug. Switching gamma back to lgamma is quite simple. Here's what I did: 1. Remove the gamma* function implementations and make them explicit aliases to lgamma*. 2. Change the name of the __ieee754_gamma* functions to __ieee754_tgamma* and remove the _ieee754_gamma*_r variants I've sent a patch doing this to the list. -- -keith
On 2020-09-03 15:25, Keith Packard wrote: > Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes: > >>>> Then tell us what you want gamma and gamma_r to do for Cygwin. >>> >>> I did: https://sourceware.org/pipermail/newlib/2020/017946.html > > Oops! I appear to have missed that mail. > >> FYI docs/spec: >> https://sca.uwaterloo.ca/coldfire/gcc-doc/docs/libm_21.html#SEC21 >> http://www.ece.ualberta.ca/~cmpe401/docs/coldfire/libm.pdf#page=20 >> https://ftp.rtems.org/pub/rtems/docs/3.2.0/libm-3.2.0.ps - see p.18 > > That's quite helpful actually and says that cygwin's gamma matches > glibc, which makes the change from 2002 just a bug. Switching gamma back > to lgamma is quite simple. > > Here's what I did: > > 1. Remove the gamma* function implementations and make them explicit > aliases to lgamma*. > > 2. Change the name of the __ieee754_gamma* functions to > __ieee754_tgamma* and remove the _ieee754_gamma*_r variants > > I've sent a patch doing this to the list. I don't think you can "remove the _ieee754_gamma*_r variants" as I believe Cygwin has to keep these: $ nm --defined-only --extern-only /bin/cygwin1.dll | fgrep gamma 00000001801a76c0 T __ieee754_gamma_r 00000001801a7f90 T __ieee754_gammaf_r 00000001801a76e0 T __ieee754_lgamma_r 00000001801a7fb0 T __ieee754_lgammaf_r 000000018018a8c0 T __lgammal_r 000000018018ce10 T __tgammal_r 000000018019f690 T gamma 00000001801a0a40 T gamma_r 00000001801a0200 T gammaf 00000001801a0b80 T gammaf_r 000000018019fb00 T lgamma 00000001801a0ae0 T lgamma_r 00000001801a0660 T lgammaf 00000001801a0c20 T lgammaf_r 000000018018ae10 T lgammal 000000018018ae90 T lgammal_r 000000018019fe50 T tgamma 00000001801a0970 T tgammaf 000000018018d290 T tgammal although I don't have the Windows utilities to check the exports directly. -- Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada This email may be disturbing to some readers as it contains too much technical detail. Reader discretion is advised. [Data in IEC units and prefixes, physical quantities in SI.]
Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes: > I don't think you can "remove the _ieee754_gamma*_r variants" as I believe > Cygwin has to keep these: I added a note to that effect in my patch email; if someone can let me know, I'll add them back in. I'd prefer to leave them out if they aren't needed though. -- -keith
On 2020-09-03 18:01, Keith Packard wrote: > Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes: > >> I don't think you can "remove the _ieee754_gamma*_r variants" as I believe >> Cygwin has to keep these: > > I added a note to that effect in my patch email; if someone can let me > know, I'll add them back in. I'd prefer to leave them out if they aren't > needed though. $ fgrep gamma newlib-cygwin/winsup/cygwin/common.din and $ fgrep gamma newlib-cygwin/x86_64-pc-cygwin/winsup/cygwin/cygwin.def have the same 13 function names: gamma gamma_r gammaf gammaf_r lgamma lgamma_r lgammaf lgammaf_r lgammal lgammal_r tgamma tgammaf tgammal so these may be the official ABI, and the others don't matter? -- Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada This email may be disturbing to some readers as it contains too much technical detail. Reader discretion is advised. [Data in IEC units and prefixes, physical quantities in SI.]
Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes: > gamma > gamma_r > gammaf > gammaf_r > lgamma > lgamma_r > lgammaf > lgammaf_r > lgammal > lgammal_r > tgamma > tgammaf > tgammal > > so these may be the official ABI, and the others don't matter? I would hope so -- the __ieee754 functions seem mostly like an internal implementation detail, but it's hard to know. If this is true, then I think the patch as posted should be what we want. -- -keith
On Sep 3 18:37, Keith Packard via Newlib wrote: > Brian Inglis <Brian.Inglis@SystematicSw.ab.ca> writes: > > > gamma > > gamma_r > > gammaf > > gammaf_r > > lgamma > > lgamma_r > > lgammaf > > lgammaf_r > > lgammal > > lgammal_r > > tgamma > > tgammaf > > tgammal > > > > so these may be the official ABI, and the others don't matter? > > I would hope so -- the __ieee754 functions seem mostly like an internal > implementation detail, but it's hard to know. > > If this is true, then I think the patch as posted should be what we want. The ieee functions can go away. The symbols from cygwin1.dll don't count, the ones exported from /usr/lib/libcygwin.a do. These are defined in winsup/cygwin/{common.din,i686.din,x86_64.din} Corinna
Corinna Vinschen via Newlib <newlib@sourceware.org> writes: > The ieee functions can go away. The symbols from cygwin1.dll don't > count, the ones exported from /usr/lib/libcygwin.a do. These are > defined in winsup/cygwin/{common.din,i686.din,x86_64.din} Which matches what we had guessed. -- -keith
diff --git a/newlib/libc/include/math.h b/newlib/libc/include/math.h index 3399d3649..28d4df10f 100644 --- a/newlib/libc/include/math.h +++ b/newlib/libc/include/math.h @@ -515,9 +515,7 @@ extern float dremf (float, float); #ifdef __CYGWIN__ extern float dreml (long double, long double); #endif /* __CYGWIN__ */ -extern double gamma_r (double, int *); extern double lgamma_r (double, int *); -extern float gammaf_r (float, int *); extern float lgammaf_r (float, int *); #endif diff --git a/newlib/libc/sys/linux/cmath/math_private.h b/newlib/libc/sys/linux/cmath/math_private.h index 3e32b29ba..f5792f7fa 100644 --- a/newlib/libc/sys/linux/cmath/math_private.h +++ b/newlib/libc/sys/linux/cmath/math_private.h @@ -178,7 +178,6 @@ extern double __ieee754_cosh (double); extern double __ieee754_fmod (double,double); extern double __ieee754_pow (double,double); extern double __ieee754_lgamma_r (double,int *); -extern double __ieee754_gamma_r (double,int *); extern double __ieee754_lgamma (double); extern double __ieee754_gamma (double); extern double __ieee754_log10 (double); @@ -241,7 +240,6 @@ extern float __ieee754_coshf (float); extern float __ieee754_fmodf (float,float); extern float __ieee754_powf (float,float); extern float __ieee754_lgammaf_r (float,int *); -extern float __ieee754_gammaf_r (float,int *); extern float __ieee754_lgammaf (float); extern float __ieee754_gammaf (float); extern float __ieee754_log10f (float); diff --git a/newlib/libm/common/fdlibm.h b/newlib/libm/common/fdlibm.h index 8dffc832d..5226c2e13 100644 --- a/newlib/libm/common/fdlibm.h +++ b/newlib/libm/common/fdlibm.h @@ -159,7 +159,7 @@ extern double __ieee754_cosh __P((double)); extern double __ieee754_fmod __P((double,double)); extern double __ieee754_pow __P((double,double)); extern double __ieee754_lgamma_r __P((double,int *)); -extern double __ieee754_gamma_r __P((double,int *)); +extern double __ieee754_gamma __P((double)); extern double __ieee754_log10 __P((double)); extern double __ieee754_sinh __P((double)); extern double __ieee754_hypot __P((double,double)); @@ -205,7 +205,7 @@ extern float __ieee754_coshf __P((float)); extern float __ieee754_fmodf __P((float,float)); extern float __ieee754_powf __P((float,float)); extern float __ieee754_lgammaf_r __P((float,int *)); -extern float __ieee754_gammaf_r __P((float,int *)); +extern float __ieee754_gammaf __P((float)); extern float __ieee754_log10f __P((float)); extern float __ieee754_sinhf __P((float)); extern float __ieee754_hypotf __P((float,float)); diff --git a/newlib/libm/math/Makefile.am b/newlib/libm/math/Makefile.am index e745159ae..87e47dbd5 100644 --- a/newlib/libm/math/Makefile.am +++ b/newlib/libm/math/Makefile.am @@ -14,7 +14,7 @@ src = k_standard.c k_rem_pio2.c \ e_scalb.c e_sinh.c e_sqrt.c \ w_acos.c w_acosh.c w_asin.c w_atan2.c \ w_atanh.c w_cosh.c w_exp.c w_fmod.c \ - w_gamma.c wr_gamma.c w_hypot.c w_j0.c \ + w_gamma.c w_hypot.c w_j0.c \ w_j1.c w_jn.c w_lgamma.c wr_lgamma.c \ w_log.c w_log10.c w_pow.c w_remainder.c \ w_scalb.c w_sinh.c w_sqrt.c \ @@ -37,7 +37,7 @@ fsrc = kf_rem_pio2.c \ ef_scalb.c ef_sinh.c ef_sqrt.c \ wf_acos.c wf_acosh.c wf_asin.c wf_atan2.c \ wf_atanh.c wf_cosh.c wf_exp.c wf_fmod.c \ - wf_gamma.c wrf_gamma.c wf_hypot.c wf_j0.c \ + wf_gamma.c wf_hypot.c wf_j0.c \ wf_j1.c wf_jn.c wf_lgamma.c wrf_lgamma.c \ wf_log.c wf_log10.c wf_pow.c wf_remainder.c \ wf_scalb.c wf_sinh.c wf_sqrt.c \ diff --git a/newlib/libm/math/Makefile.in b/newlib/libm/math/Makefile.in index 0ac2b1668..9ba1be8ca 100644 --- a/newlib/libm/math/Makefile.in +++ b/newlib/libm/math/Makefile.in @@ -90,7 +90,7 @@ am__objects_1 = lib_a-k_standard.$(OBJEXT) lib_a-k_rem_pio2.$(OBJEXT) \ lib_a-w_atan2.$(OBJEXT) lib_a-w_atanh.$(OBJEXT) \ lib_a-w_cosh.$(OBJEXT) lib_a-w_exp.$(OBJEXT) \ lib_a-w_fmod.$(OBJEXT) lib_a-w_gamma.$(OBJEXT) \ - lib_a-wr_gamma.$(OBJEXT) lib_a-w_hypot.$(OBJEXT) \ + lib_a-w_hypot.$(OBJEXT) \ lib_a-w_j0.$(OBJEXT) lib_a-w_j1.$(OBJEXT) lib_a-w_jn.$(OBJEXT) \ lib_a-w_lgamma.$(OBJEXT) lib_a-wr_lgamma.$(OBJEXT) \ lib_a-w_log.$(OBJEXT) lib_a-w_log10.$(OBJEXT) \ @@ -122,7 +122,7 @@ am__objects_2 = lib_a-kf_rem_pio2.$(OBJEXT) lib_a-kf_cos.$(OBJEXT) \ lib_a-wf_asin.$(OBJEXT) lib_a-wf_atan2.$(OBJEXT) \ lib_a-wf_atanh.$(OBJEXT) lib_a-wf_cosh.$(OBJEXT) \ lib_a-wf_exp.$(OBJEXT) lib_a-wf_fmod.$(OBJEXT) \ - lib_a-wf_gamma.$(OBJEXT) lib_a-wrf_gamma.$(OBJEXT) \ + lib_a-wf_gamma.$(OBJEXT) \ lib_a-wf_hypot.$(OBJEXT) lib_a-wf_j0.$(OBJEXT) \ lib_a-wf_j1.$(OBJEXT) lib_a-wf_jn.$(OBJEXT) \ lib_a-wf_lgamma.$(OBJEXT) lib_a-wrf_lgamma.$(OBJEXT) \ @@ -151,7 +151,7 @@ am__objects_4 = k_standard.lo k_rem_pio2.lo k_cos.lo k_sin.lo k_tan.lo \ e_jn.lo er_lgamma.lo e_log.lo e_log10.lo e_pow.lo \ e_rem_pio2.lo e_remainder.lo e_scalb.lo e_sinh.lo e_sqrt.lo \ w_acos.lo w_acosh.lo w_asin.lo w_atan2.lo w_atanh.lo w_cosh.lo \ - w_exp.lo w_fmod.lo w_gamma.lo wr_gamma.lo w_hypot.lo w_j0.lo \ + w_exp.lo w_fmod.lo w_gamma.lo w_hypot.lo w_j0.lo \ w_j1.lo w_jn.lo w_lgamma.lo wr_lgamma.lo w_log.lo w_log10.lo \ w_pow.lo w_remainder.lo w_scalb.lo w_sinh.lo w_sqrt.lo \ w_sincos.lo w_drem.lo s_asinh.lo s_atan.lo s_ceil.lo s_cos.lo \ @@ -164,7 +164,7 @@ am__objects_5 = kf_rem_pio2.lo kf_cos.lo kf_sin.lo kf_tan.lo \ ef_pow.lo ef_rem_pio2.lo ef_remainder.lo ef_scalb.lo \ ef_sinh.lo ef_sqrt.lo wf_acos.lo wf_acosh.lo wf_asin.lo \ wf_atan2.lo wf_atanh.lo wf_cosh.lo wf_exp.lo wf_fmod.lo \ - wf_gamma.lo wrf_gamma.lo wf_hypot.lo wf_j0.lo wf_j1.lo \ + wf_gamma.lo wf_hypot.lo wf_j0.lo wf_j1.lo \ wf_jn.lo wf_lgamma.lo wrf_lgamma.lo wf_log.lo wf_log10.lo \ wf_pow.lo wf_remainder.lo wf_scalb.lo wf_sinh.lo wf_sqrt.lo \ wf_sincos.lo wf_drem.lo sf_asinh.lo sf_atan.lo sf_ceil.lo \ @@ -339,7 +339,7 @@ src = k_standard.c k_rem_pio2.c \ e_scalb.c e_sinh.c e_sqrt.c \ w_acos.c w_acosh.c w_asin.c w_atan2.c \ w_atanh.c w_cosh.c w_exp.c w_fmod.c \ - w_gamma.c wr_gamma.c w_hypot.c w_j0.c \ + w_gamma.c w_hypot.c w_j0.c \ w_j1.c w_jn.c w_lgamma.c wr_lgamma.c \ w_log.c w_log10.c w_pow.c w_remainder.c \ w_scalb.c w_sinh.c w_sqrt.c \ @@ -362,7 +362,7 @@ fsrc = kf_rem_pio2.c \ ef_scalb.c ef_sinh.c ef_sqrt.c \ wf_acos.c wf_acosh.c wf_asin.c wf_atan2.c \ wf_atanh.c wf_cosh.c wf_exp.c wf_fmod.c \ - wf_gamma.c wrf_gamma.c wf_hypot.c wf_j0.c \ + wf_gamma.c wf_hypot.c wf_j0.c \ wf_j1.c wf_jn.c wf_lgamma.c wrf_lgamma.c \ wf_log.c wf_log10.c wf_pow.c wf_remainder.c \ wf_scalb.c wf_sinh.c wf_sqrt.c \ @@ -690,12 +690,6 @@ lib_a-w_gamma.o: w_gamma.c lib_a-w_gamma.obj: w_gamma.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-w_gamma.obj `if test -f 'w_gamma.c'; then $(CYGPATH_W) 'w_gamma.c'; else $(CYGPATH_W) '$(srcdir)/w_gamma.c'; fi` -lib_a-wr_gamma.o: wr_gamma.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wr_gamma.o `test -f 'wr_gamma.c' || echo '$(srcdir)/'`wr_gamma.c - -lib_a-wr_gamma.obj: wr_gamma.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wr_gamma.obj `if test -f 'wr_gamma.c'; then $(CYGPATH_W) 'wr_gamma.c'; else $(CYGPATH_W) '$(srcdir)/wr_gamma.c'; fi` - lib_a-w_hypot.o: w_hypot.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-w_hypot.o `test -f 'w_hypot.c' || echo '$(srcdir)/'`w_hypot.c @@ -1086,12 +1080,6 @@ lib_a-wf_gamma.o: wf_gamma.c lib_a-wf_gamma.obj: wf_gamma.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wf_gamma.obj `if test -f 'wf_gamma.c'; then $(CYGPATH_W) 'wf_gamma.c'; else $(CYGPATH_W) '$(srcdir)/wf_gamma.c'; fi` -lib_a-wrf_gamma.o: wrf_gamma.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wrf_gamma.o `test -f 'wrf_gamma.c' || echo '$(srcdir)/'`wrf_gamma.c - -lib_a-wrf_gamma.obj: wrf_gamma.c - $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wrf_gamma.obj `if test -f 'wrf_gamma.c'; then $(CYGPATH_W) 'wrf_gamma.c'; else $(CYGPATH_W) '$(srcdir)/wrf_gamma.c'; fi` - lib_a-wf_hypot.o: wf_hypot.c $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-wf_hypot.o `test -f 'wf_hypot.c' || echo '$(srcdir)/'`wf_hypot.c diff --git a/newlib/libm/math/er_gamma.c b/newlib/libm/math/er_gamma.c index 3c0e241e5..9252e2d04 100644 --- a/newlib/libm/math/er_gamma.c +++ b/newlib/libm/math/er_gamma.c @@ -22,11 +22,15 @@ #include "fdlibm.h" #ifdef __STDC__ - double __ieee754_gamma_r(double x, int *signgamp) + double __ieee754_gamma(double x) #else - double __ieee754_gamma_r(x,signgamp) - double x; int *signgamp; + double __ieee754_gamma(x) + double x; #endif { - return __ieee754_exp (__ieee754_lgamma_r(x,signgamp)); + int local_signgam = 1; + double y = __ieee754_exp (__ieee754_lgamma_r(x, &local_signgam)); + if (local_signgam < 0) + y = -y; + return y; } diff --git a/newlib/libm/math/erf_gamma.c b/newlib/libm/math/erf_gamma.c index 9e529dce0..bddac60c7 100644 --- a/newlib/libm/math/erf_gamma.c +++ b/newlib/libm/math/erf_gamma.c @@ -24,11 +24,15 @@ #include "fdlibm.h" #ifdef __STDC__ - float __ieee754_gammaf_r(float x, int *signgamp) + float __ieee754_gammaf(float x) #else - float __ieee754_gammaf_r(x,signgamp) - float x; int *signgamp; + float __ieee754_gammaf(x) + float x; #endif { - return __ieee754_expf (__ieee754_lgammaf_r(x,signgamp)); + int local_signgam = 1; + float y = __ieee754_expf (__ieee754_lgammaf_r(x,&local_signgam)); + if (local_signgam < 0) + y = -y; + return y; } diff --git a/newlib/libm/math/w_gamma.c b/newlib/libm/math/w_gamma.c index b65d5cc4b..bb47fab31 100644 --- a/newlib/libm/math/w_gamma.c +++ b/newlib/libm/math/w_gamma.c @@ -148,18 +148,7 @@ in terms of the base return values, although the <[signgam]> global for double x; #endif { -#ifdef _IEEE_LIBM - return __ieee754_gamma_r(x,&(_REENT_SIGNGAM(_REENT))); -#else - double y; - y = __ieee754_gamma_r(x,&(_REENT_SIGNGAM(_REENT))); - if(_LIB_VERSION == _IEEE_) return y; - if(!finite(y)&&finite(x)) { - /* gamma(finite) overflow */ - errno = ERANGE; - } - return y; -#endif -} + return tgamma(x); +} #endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/newlib/libm/math/w_tgamma.c b/newlib/libm/math/w_tgamma.c index c0c011dd0..cbb3e7f7f 100644 --- a/newlib/libm/math/w_tgamma.c +++ b/newlib/libm/math/w_tgamma.c @@ -27,9 +27,7 @@ #endif { double y; - int local_signgam; - y = __ieee754_gamma_r(x,&local_signgam); - if (local_signgam < 0) y = -y; + y = __ieee754_gamma(x); #ifdef _IEEE_LIBM return y; #else diff --git a/newlib/libm/math/wf_gamma.c b/newlib/libm/math/wf_gamma.c index f0284a282..4e961c864 100644 --- a/newlib/libm/math/wf_gamma.c +++ b/newlib/libm/math/wf_gamma.c @@ -25,19 +25,8 @@ float x; #endif { -#ifdef _IEEE_LIBM - return __ieee754_gammaf_r(x,&(_REENT_SIGNGAM(_REENT))); -#else - float y; - y = __ieee754_gammaf_r(x,&(_REENT_SIGNGAM(_REENT))); - if(_LIB_VERSION == _IEEE_) return y; - if(!finitef(y)&&finitef(x)) { - /* gammaf(finite) overflow */ - errno = ERANGE; - } - return y; -#endif -} + return tgammaf(x); +} #ifdef _DOUBLE_IS_32BITS diff --git a/newlib/libm/math/wf_tgamma.c b/newlib/libm/math/wf_tgamma.c index 92df39648..8f0c501b8 100644 --- a/newlib/libm/math/wf_tgamma.c +++ b/newlib/libm/math/wf_tgamma.c @@ -24,9 +24,7 @@ #endif { float y; - int local_signgam; - y = __ieee754_gammaf_r(x,&local_signgam); - if (local_signgam < 0) y = -y; + y = __ieee754_gammaf(x); #ifdef _IEEE_LIBM return y; #else diff --git a/newlib/libm/math/wr_gamma.c b/newlib/libm/math/wr_gamma.c deleted file mode 100644 index c4c2a829e..000000000 --- a/newlib/libm/math/wr_gamma.c +++ /dev/null @@ -1,49 +0,0 @@ - -/* @(#)wr_gamma.c 5.1 93/09/24 */ -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * wrapper double gamma_r(double x, int *signgamp) - */ - -#include "fdlibm.h" -#include <errno.h> - -#ifndef _DOUBLE_IS_32BITS - -#ifdef __STDC__ - double gamma_r(double x, int *signgamp) /* wrapper lgamma_r */ -#else - double gamma_r(x,signgamp) /* wrapper lgamma_r */ - double x; int *signgamp; -#endif -{ -#ifdef _IEEE_LIBM - return __ieee754_gamma_r(x,signgamp); -#else - double y; - y = __ieee754_gamma_r(x,signgamp); - if(_LIB_VERSION == _IEEE_) return y; - if(!finite(y)&&finite(x)) { - if(floor(x)==x&&x<=0.0) - /* gamma(-integer) or gamma(0) */ - errno = EDOM; - else - /* gamma(finite) overflow */ - errno = ERANGE; - return HUGE_VALF; - } else - return y; -#endif -} - -#endif /* defined(_DOUBLE_IS_32BITS) */ diff --git a/newlib/libm/math/wrf_gamma.c b/newlib/libm/math/wrf_gamma.c deleted file mode 100644 index d43c7f03d..000000000 --- a/newlib/libm/math/wrf_gamma.c +++ /dev/null @@ -1,48 +0,0 @@ -/* wrf_gamma.c -- float version of wr_gamma.c. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. - */ - -/* - * ==================================================== - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. - * - * Developed at SunPro, a Sun Microsystems, Inc. business. - * Permission to use, copy, modify, and distribute this - * software is freely granted, provided that this notice - * is preserved. - * ==================================================== - */ - -/* - * wrapper float gammaf_r(float x, int *signgamp) - */ - -#include "fdlibm.h" -#include <errno.h> - -#ifdef __STDC__ - float gammaf_r(float x, int *signgamp) /* wrapper lgammaf_r */ -#else - float gammaf_r(x,signgamp) /* wrapper lgammaf_r */ - float x; int *signgamp; -#endif -{ -#ifdef _IEEE_LIBM - return __ieee754_gammaf_r(x,signgamp); -#else - float y; - y = __ieee754_gammaf_r(x,signgamp); - if(_LIB_VERSION == _IEEE_) return y; - if(!finitef(y)&&finitef(x)) { - if(floorf(x)==x&&x<=0.0f) { - /* gammaf(-integer) or gamma(0) */ - errno = EDOM; - } else { - /* gammaf(finite) overflow */ - errno = ERANGE; - } - return HUGE_VALF; - } else - return y; -#endif -}
Gamma should consume the sign reported by lgamma internally instead of providing it back to the application. This removes the need to have _r variants as there is no longer any re-entrancy issues with the API. Signed-off-by: Keith Packard <keithp@keithp.com> --- newlib/libc/include/math.h | 2 - newlib/libc/sys/linux/cmath/math_private.h | 2 - newlib/libm/common/fdlibm.h | 4 +- newlib/libm/math/Makefile.am | 4 +- newlib/libm/math/Makefile.in | 24 +++-------- newlib/libm/math/er_gamma.c | 12 ++++-- newlib/libm/math/erf_gamma.c | 12 ++++-- newlib/libm/math/w_gamma.c | 15 +------ newlib/libm/math/w_tgamma.c | 4 +- newlib/libm/math/wf_gamma.c | 15 +------ newlib/libm/math/wf_tgamma.c | 4 +- newlib/libm/math/wr_gamma.c | 49 ---------------------- newlib/libm/math/wrf_gamma.c | 48 --------------------- 13 files changed, 32 insertions(+), 163 deletions(-) delete mode 100644 newlib/libm/math/wr_gamma.c delete mode 100644 newlib/libm/math/wrf_gamma.c -- 2.28.0