diff --git a/dtool/src/dtoolbase/cmath.I b/dtool/src/dtoolbase/cmath.I index 194e6d24cf..03b03f5640 100644 --- a/dtool/src/dtoolbase/cmath.I +++ b/dtool/src/dtoolbase/cmath.I @@ -358,26 +358,68 @@ cpow(int x, int y) { } } +//////////////////////////////////////////////////////////////////// +// Function: cnan +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool +cnan(float v) { +#if __FINITE_MATH_ONLY__ + // GCC's isnan breaks when using -ffast-math. + union { float f; uint32_t x; } u = { v }; + return ((u.x << 1) > 0xff000000u); +#elif !defined(_WIN32) + return std::isnan(v); +#else + return (_isnan(v) != 0); +#endif +} + //////////////////////////////////////////////////////////////////// // Function: cnan // Description: //////////////////////////////////////////////////////////////////// INLINE bool cnan(double v) { -#ifndef _WIN32 +#if __FINITE_MATH_ONLY__ + // GCC's isnan breaks when using -ffast-math. + union { double d; uint64_t x; } u = { v }; + return ((u.x << 1) > 0xff70000000000000ull); +#elif !defined(_WIN32) return std::isnan(v); #else return (_isnan(v) != 0); #endif } +//////////////////////////////////////////////////////////////////// +// Function: cinf +// Description: +//////////////////////////////////////////////////////////////////// +INLINE bool +cinf(float v) { +#if __FINITE_MATH_ONLY__ + // GCC's isinf breaks when using -ffast-math. + union { float f; uint32_t x; } u = { v }; + return ((u.x << 1) == 0xff000000u); +#elif !defined(_WIN32) + return std::isinf(v); +#else + return (_isnan(v) == 0 && _finite(v) == 0); +#endif +} + //////////////////////////////////////////////////////////////////// // Function: cinf // Description: //////////////////////////////////////////////////////////////////// INLINE bool cinf(double v) { -#ifndef _WIN32 +#if __FINITE_MATH_ONLY__ + // GCC's isinf breaks when using -ffast-math. + union { double d; uint64_t x; } u = { v }; + return ((u.x << 1) == 0xff70000000000000ull); +#elif !defined(_WIN32) return std::isinf(v); #else return (_isnan(v) == 0 && _finite(v) == 0); diff --git a/dtool/src/dtoolbase/cmath.h b/dtool/src/dtoolbase/cmath.h index 6e5c1ef8e8..42d83f77d5 100644 --- a/dtool/src/dtoolbase/cmath.h +++ b/dtool/src/dtoolbase/cmath.h @@ -61,9 +61,11 @@ INLINE int cpow(int x, int y); // Returns true if the number is NaN, false if it's a genuine number // or infinity. +INLINE bool cnan(float v); INLINE bool cnan(double v); // Returns true if the number is infinity. +INLINE bool cinf(float v); INLINE bool cinf(double v); // Return NaN and infinity, respectively. diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 7de4d5c642..ac0a134a42 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -1104,6 +1104,8 @@ def CompileCxx(obj,src,opts): arch = GetTargetArch() if GetTarget() == "android": + # Most of the specific optimization flags here were + # just copied from the default Android Makefiles. cmd += ' -I%s/include' % (SDK["ANDROID_STL"]) cmd += ' -I%s/libs/%s/include' % (SDK["ANDROID_STL"], SDK["ANDROID_ABI"]) cmd += ' -ffunction-sections -funwind-tables' @@ -1158,6 +1160,12 @@ def CompileCxx(obj,src,opts): if PkgSkip("SSE2") == 0 and not arch.startswith("arm"): cmd += " -msse2" + if optlevel >= 3: + cmd += " -ffast-math" + if optlevel == 3: + # Fast math is nice, but we'd like to see NaN in dev builds. + cmd += " -fno-finite-math-only" + if (optlevel==1): cmd += " -ggdb -D_DEBUG" if (optlevel==2): cmd += " -O1 -D_DEBUG" if (optlevel==3): cmd += " -O2"