X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fconfig%2Fi386%2Fcrtfastmath.c;h=fdff24723ac80aa8c544950fd0aac18392bea2f3;hb=55a2ce2fd41a7fe225e39f4a17033613aea9b656;hp=3412d6ceda6e943cd7e95063a5c2efd1ebf2d463;hpb=ccf6cedcb51aa64ac134b17e131615d319cda3f8;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/config/i386/crtfastmath.c b/gcc/config/i386/crtfastmath.c index 3412d6ceda6..fdff24723ac 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 }