From 55a2ce2fd41a7fe225e39f4a17033613aea9b656 Mon Sep 17 00:00:00 2001
From: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Sun, 14 Aug 2005 14:26:51 +0000
Subject: [PATCH] 2005-08-14  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.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103078 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                 |  6 +++++
 gcc/config/i386/crtfastmath.c | 46 ++++++++++++++++++++++++++++++++---
 2 files changed, 48 insertions(+), 4 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 028dfc748489..f112f1ba291e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-08-14  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.
+
 2005-08-14  Ira Rosen  <irar@il.ibm.com>
 
 	PR tree-optimization/23320
diff --git a/gcc/config/i386/crtfastmath.c b/gcc/config/i386/crtfastmath.c
index 3412d6ceda6e..fdff24723ac8 100644
--- a/gcc/config/i386/crtfastmath.c
+++ b/gcc/config/i386/crtfastmath.c
@@ -34,11 +34,15 @@
 #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 +66,45 @@ set_fast_math (void)
 		: "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
 		: "0" (1));
 
-  if (edx & (1 << 25))
-#endif
+  if (edx & SSE)
     {
       unsigned int mxcsr = __builtin_ia32_stmxcsr ();
-      mxcsr |= MXCSR_DAZ | MXCSR_FTZ;
+  
+      mxcsr |= MXCSR_FTZ;
+
+      if (edx & FXSAVE)
+	{
+	  /* 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;
+
+	  __builtin_memset (&fxsave, 0, sizeof (fxsave));
+
+	  asm volatile ("fxsave %0" : : "m" (fxsave));
+
+	  if (fxsave.mxcsr_mask & MXCSR_DAZ)
+	    mxcsr |= MXCSR_DAZ;
+	}
+
       __builtin_ia32_ldmxcsr (mxcsr);
     }
+#else
+  unsigned int mxcsr = __builtin_ia32_stmxcsr ();
+  mxcsr |= MXCSR_DAZ | MXCSR_FTZ;
+  __builtin_ia32_ldmxcsr (mxcsr);
+#endif
 }
-- 
GitLab