diff --git a/src/cmd/ksh93/Mamfile b/src/cmd/ksh93/Mamfile index cb560713a..9f3174377 100644 --- a/src/cmd/ksh93/Mamfile +++ b/src/cmd/ksh93/Mamfile @@ -1216,6 +1216,7 @@ make install exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${KSH_RELFLAGS} ${KSH_SHOPTFLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/math.sh ${PACKAGEROOT}/src/cmd/ksh93/data/math.tab make ${PACKAGE_ast_INCLUDE}/ast_standards.h implicit done ${PACKAGE_ast_INCLUDE}/ast_standards.h dontcare + prev ${INSTALLROOT}/src/lib/libast/FEATURE/float implicit done FEATURE/math generated prev include/streval.h implicit prev FEATURE/options implicit diff --git a/src/lib/libast/Mamfile b/src/lib/libast/Mamfile index af0f66caa..0ce5ca321 100644 --- a/src/lib/libast/Mamfile +++ b/src/lib/libast/Mamfile @@ -3128,6 +3128,7 @@ make install prev include/tm.h implicit prev include/error.h implicit prev include/ast.h implicit + prev FEATURE/float implicit done comp/omitted.c meta omitted.o %.c>%.o comp/omitted.c omitted prev comp/omitted.c diff --git a/src/lib/libast/comp/omitted.c b/src/lib/libast/comp/omitted.c index 16d2db655..247aa52bf 100644 --- a/src/lib/libast/comp/omitted.c +++ b/src/lib/libast/comp/omitted.c @@ -15,6 +15,7 @@ __STDPP__directive pragma pp:hide utime utimes #include #include +#include "FEATURE/float" #include "FEATURE/omitted" #undef OMITTED @@ -1145,6 +1146,36 @@ __EXPORT__ double (*_imp__strtod)(const char*, char**) = strtod; #endif +/* Kludge to deal with GCC's overzealous optimizer breaking the pow functions. + * + * Removal of this will break IEEE floating point on the SVR4 platforms. + */ +#if _need_ast_pow_funs +# if _lib_powf +float (*volatile _ast_ppowf)(float,float) = &powf; +float _ast_powf(float x, float y) +{ + return x == 1.0F ? 1.0F : (*_ast_ppowf)(x,y); +} +# endif + +# if _lib_pow +double (*volatile _ast_ppow)(double,double) = &pow; +double _ast_pow(double x, double y) +{ + return x == 1.0 ? 1.0 : (*_ast_ppow)(x,y); +} +# endif + +# if _lib_powl +long double (*volatile _ast_ppowl)(long double,long double) = &powl; +long double _ast_powl(long double x, long double y) +{ + return x == 1.0L ? 1.0L : (*_ast_ppowl)(x,y); +} +# endif +#endif + #ifndef OMITTED NoN(omitted) diff --git a/src/lib/libast/features/float b/src/lib/libast/features/float index 0a65200e7..44ff12f92 100644 --- a/src/lib/libast/features/float +++ b/src/lib/libast/features/float @@ -2,7 +2,7 @@ set prototyped set nooptimize set stdio FEATURE/standards hdr float,limits,math,values -lib,npt frexp,frexpl,ldexp,ldexpl,finite,finitel,isinfl,isnanl,copysign,copysignl FEATURE/standards math.h -lm +lib,npt frexp,frexpl,ldexp,ldexpl,finite,finitel,isinfl,isnanl,copysign,copysignl,powf,pow,powl FEATURE/standards math.h -lm lib fpclassify -lm note{ fpclassify present and works }end link{ #include #include @@ -1231,15 +1231,33 @@ tst - -DSCAN=1 - -lm -DSTRTO=1 - -DMAC=1 - -DDIV=1 - -DEXP=1 - -DADD=1 - -DMPY=1 } }end -tst ast_pow_ieee -lm note{ pow(1,inf) is IEEE compliant }end execute{ +if need_ast_pow_macros -lm note{ are IEEE pow macro replacements needed }end execute{ #include #include #include #include #include - int main() { return pow(1.0, 1.0 / 0.0) != 1.0; } -}end fail{ - echo '#define powf(x,y) (((x)==1.0)?1.0:powf((x),(y)))' - echo '#define pow(x,y) (((x)==1.0)?1.0:pow((x),(y)))' - echo '#define powl(x,y) (((x)==1.0)?1.0:powl((x),(y)))' -}end + int main() { return pow(1.0, 1.0 / 0.0) == 1.0; } +}end { + #define powf(x,y) (((x)==1.0)?1.0:powf((x),(y))) + #define pow(x,y) (((x)==1.0)?1.0:pow((x),(y))) + #define powl(x,y) (((x)==1.0)?1.0:powl((x),(y))) +} +elif tst need_ast_pow_funs -lm note{ are IEEE pow function replacements needed }end execute{ + #include + #include + #include + #include + #include + /* This bit of obfuscation defeats GCC's code optimizer. */ + double (*volatile _ast_ppow)(double,double); + int main () { _ast_ppow = &pow; return (*_ast_ppow)(1.0, 1.0 / 0.0) == 1.0; } +}end { + float _ast_powf(float x, float y); + double _ast_pow(double x, double y); + long double _ast_powl(long double x, long double y); + #define powf(x,y) (_ast_powf((x),(y))) + #define pow(x,y) (_ast_pow((x),(y))) + #define powl(x,y) (_ast_powl((x),(y))) +} +endif