This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

PATCH: target/23360: -ffast-math startup broken on i686 (maybe Athlon-xp)


This patch checks if DAZ is available for setting it.


H.J.
---
2005-08-12  H.J. Lu  <hongjiu.lu@intel.com>

	PR target/23360
	* config/i386/crtfastmath.c (set_fast_math): Check if DAZ is
	available for setting it.

--- gcc/config/i386/crtfastmath.c.daz	2005-08-10 08:47:24.000000000 -0700
+++ gcc/config/i386/crtfastmath.c	2005-08-12 16:31:06.646125740 -0700
@@ -31,14 +31,20 @@
  *    the executable file might be covered by the GNU General Public License.
  */
 
+#include <string.h>
+
 #define MXCSR_DAZ (1 << 6)	/* Enable denormals are zero mode */
 #define MXCSR_FTZ (1 << 15)	/* Enable flush to zero mode */
 
+#define FXSAVE	(1 << 24)
+#define SSE	(1 << 25)
+
 static void __attribute__((constructor))
 set_fast_math (void)
 {
 #ifndef __x86_64__
-  /* SSE is the part of 64bit. Only need to check it for 32bit.  */
+  /* All 64-bit targets have SSE and DAZ; only check them explicitly
+     for 32-bit ones. */
   unsigned int eax, ebx, ecx, edx;
 
   /* See if we can use cpuid.  */
@@ -62,11 +68,40 @@ set_fast_math (void)
 		: "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
 		: "0" (1));
 
-  if (edx & (1 << 25))
-#endif
+  if ((edx & (SSE | FXSAVE)) == (SSE | FXSAVE))
     {
-      unsigned int mxcsr = __builtin_ia32_stmxcsr ();
-      mxcsr |= MXCSR_DAZ | MXCSR_FTZ;
-      __builtin_ia32_ldmxcsr (mxcsr);
+      /* Check if DAZ is available.  */
+      struct
+	{
+	  unsigned short int cwd;
+	  unsigned short int swd;
+	  unsigned short int twd;
+	  unsigned short int fop;
+	  long int fip;
+	  long int fcs;
+	  long int foo;
+	  long int fos;
+	  long int mxcsr;
+	  long int mxcsr_mask;
+	  long int st_space[32];
+	  long int xmm_space[32];
+	  long int padding[56];
+	} __attribute__ ((aligned (16))) fxsave;
+
+      memset (&fxsave, 0, sizeof (fxsave));
+
+      asm volatile ("fxsave %0" : : "m" (fxsave));
+
+      if (fxsave.mxcsr_mask & MXCSR_DAZ)
+	{
+	  unsigned int mxcsr = __builtin_ia32_stmxcsr ();
+	  mxcsr |= MXCSR_DAZ | MXCSR_FTZ;
+	  __builtin_ia32_ldmxcsr (mxcsr);
+	}
     }
+#else
+  unsigned int mxcsr = __builtin_ia32_stmxcsr ();
+  mxcsr |= MXCSR_DAZ | MXCSR_FTZ;
+  __builtin_ia32_ldmxcsr (mxcsr);
+#endif
 }


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