Browse Source

We use /fp:fast on Windows, let's be consistent and use -ffast-math on other platforms in release builds

rdb 11 years ago
parent
commit
bd7d86ba9e
3 changed files with 54 additions and 2 deletions
  1. 44 2
      dtool/src/dtoolbase/cmath.I
  2. 2 0
      dtool/src/dtoolbase/cmath.h
  3. 8 0
      makepanda/makepanda.py

+ 44 - 2
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);

+ 2 - 0
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.

+ 8 - 0
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"