diff options
author | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-09-07 09:34:36 +0000 |
---|---|---|
committer | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-09-07 09:34:36 +0000 |
commit | 699b378669e11615a1ba6401313740fa87737af3 (patch) | |
tree | c3dbe04692829d5d6c7aa612624f074c72b9b5ae /libgfortran/config | |
parent | 2a4176f8f363bae9dd75aff0c0ccab9a9849b06f (diff) | |
download | gcc-699b378669e11615a1ba6401313740fa87737af3.tar.gz |
* config/fpu-387.h: Include cpuid.h.
(set_fpu): Use __get_cpuid to check for SSE.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128234 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran/config')
-rw-r--r-- | libgfortran/config/fpu-387.h | 61 |
1 files changed, 25 insertions, 36 deletions
diff --git a/libgfortran/config/fpu-387.h b/libgfortran/config/fpu-387.h index cc2ef4f0f25..f96f7156619 100644 --- a/libgfortran/config/fpu-387.h +++ b/libgfortran/config/fpu-387.h @@ -28,79 +28,68 @@ License along with libgfortran; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#define SSE (1 << 25) +#ifndef __x86_64__ +#include "cpuid.h" +#endif static int has_sse (void) { -#ifdef __x86_64__ - return 1; -#else +#ifndef __x86_64__ unsigned int eax, ebx, ecx, edx; - /* See if we can use cpuid. */ - asm volatile ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;" - "pushl %0; popfl; pushfl; popl %0; popfl" - : "=&r" (eax), "=&r" (ebx) - : "i" (0x00200000)); - - if (((eax ^ ebx) & 0x00200000) == 0) - return 0; - - /* Check the highest input value for eax. */ - asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" - : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) - : "0" (0)); - - if (eax == 0) + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) return 0; - asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" - : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) - : "0" (1)); - - if (edx & SSE) - return 1; - - return 0; + return edx & bit_SSE; +#else + return 1; #endif } -void set_fpu (void) -{ - unsigned short cw; - unsigned int cw_sse; - - /* i387 -- see linux <fpu_control.h> header file for details. */ +/* i387 -- see linux <fpu_control.h> header file for details. */ #define _FPU_MASK_IM 0x01 #define _FPU_MASK_DM 0x02 #define _FPU_MASK_ZM 0x04 #define _FPU_MASK_OM 0x08 #define _FPU_MASK_UM 0x10 #define _FPU_MASK_PM 0x20 + +void set_fpu (void) +{ + unsigned short cw; + asm volatile ("fnstcw %0" : "=m" (cw)); - cw |= _FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_PM; + + cw |= (_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM + | _FPU_MASK_UM | _FPU_MASK_PM); + if (options.fpe & GFC_FPE_INVALID) cw &= ~_FPU_MASK_IM; if (options.fpe & GFC_FPE_DENORMAL) cw &= ~_FPU_MASK_DM; if (options.fpe & GFC_FPE_ZERO) cw &= ~_FPU_MASK_ZM; if (options.fpe & GFC_FPE_OVERFLOW) cw &= ~_FPU_MASK_OM; if (options.fpe & GFC_FPE_UNDERFLOW) cw &= ~_FPU_MASK_UM; if (options.fpe & GFC_FPE_PRECISION) cw &= ~_FPU_MASK_PM; + asm volatile ("fldcw %0" : : "m" (cw)); if (has_sse()) { - /* SSE */ + unsigned int cw_sse; + asm volatile ("stmxcsr %0" : "=m" (cw_sse)); - cw_sse &= 0xFFFF0000; + + cw_sse &= 0xffff0000; cw_sse |= (_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM | _FPU_MASK_PM ) << 7; + if (options.fpe & GFC_FPE_INVALID) cw_sse &= ~(_FPU_MASK_IM << 7); if (options.fpe & GFC_FPE_DENORMAL) cw_sse &= ~(_FPU_MASK_DM << 7); if (options.fpe & GFC_FPE_ZERO) cw_sse &= ~(_FPU_MASK_ZM << 7); if (options.fpe & GFC_FPE_OVERFLOW) cw_sse &= ~(_FPU_MASK_OM << 7); if (options.fpe & GFC_FPE_UNDERFLOW) cw_sse &= ~(_FPU_MASK_UM << 7); if (options.fpe & GFC_FPE_PRECISION) cw_sse &= ~(_FPU_MASK_PM << 7); + asm volatile ("ldmxcsr %0" : : "m" (cw_sse)); } } |