summaryrefslogtreecommitdiff
path: root/libgfortran/config
diff options
context:
space:
mode:
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2007-09-07 09:34:36 +0000
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2007-09-07 09:34:36 +0000
commit699b378669e11615a1ba6401313740fa87737af3 (patch)
treec3dbe04692829d5d6c7aa612624f074c72b9b5ae /libgfortran/config
parent2a4176f8f363bae9dd75aff0c0ccab9a9849b06f (diff)
downloadgcc-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.h61
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));
}
}