diff options
author | H.J. Lu <hongjiu.lu@intel.com> | 2005-08-14 14:26:51 +0000 |
---|---|---|
committer | H.J. Lu <hjl@gcc.gnu.org> | 2005-08-14 07:26:51 -0700 |
commit | adb7b76436a93a635cb93e72ec6e701f4b10d6f5 (patch) | |
tree | 6f393d450b806a9d1902b1a360c610790fe9a589 /gcc | |
parent | 1f400bbb8f014c3259d65d03a119a49589c76348 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/i386/crtfastmath.c | 46 |
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 } |