aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorH.J. Lu <hongjiu.lu@intel.com>2005-08-14 14:26:51 +0000
committerH.J. Lu <hjl@gcc.gnu.org>2005-08-14 07:26:51 -0700
commitadb7b76436a93a635cb93e72ec6e701f4b10d6f5 (patch)
tree6f393d450b806a9d1902b1a360c610790fe9a589 /gcc
parent1f400bbb8f014c3259d65d03a119a49589c76348 (diff)
downloadgcc-adb7b76436a93a635cb93e72ec6e701f4b10d6f5.zip
gcc-adb7b76436a93a635cb93e72ec6e701f4b10d6f5.tar.gz
gcc-adb7b76436a93a635cb93e72ec6e701f4b10d6f5.tar.bz2
re PR target/23360 (-ffast-math startup broken on i686 (maybe Athlon-xp))
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. From-SVN: r103078
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/crtfastmath.c46
2 files changed, 48 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 028dfc7..f112f1b 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 3412d6c..fdff247 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
}