Commit 86c2f4b7 by Uros Bizjak Committed by Uros Bizjak

fpu-387.h (_FPU_MASK_ALL): New.

	* config/fpu-387.h (_FPU_MASK_ALL): New.
	(_FPU_EX_ALL): Ditto.
	(set_fpu): Use fstcw to store x87 FPU control word. Use fnclex to
	clear stalled exception flags.  Correctly clear stalled SSE
	exception flags.  Simplify code.
	(get_fpu_except_flags): Simplify code.

From-SVN: r200255
parent 1ef3b58e
2013-06-20 Uros Bizjak <ubizjak@gmail.com>
* config/fpu-387.h (_FPU_MASK_ALL): New.
(set_fpu): Use fstcw to store x87 FPU control word. Use fnclex to
clear stalled exception flags. Correctly clear stalled SSE
exception flags. Simplify code.
2013-06-20 Tobias Burnus <burnus@net-b.de> 2013-06-20 Tobias Burnus <burnus@net-b.de>
PR fortran/57633 PR fortran/57633
* io/list_read.c (next_char, eat_separator): Don't set EOL for \r. * io/list_read.c (next_char, eat_separator): Don't set EOL for \r.
2012-06-19 Uros Bizjak <ubizjak@gmail.com> 2013-06-19 Uros Bizjak <ubizjak@gmail.com>
* config/fpu-387.h: Use __asm__ and __volatile__ consistently. * config/fpu-387.h: Use __asm__ and __volatile__ consistently.
(get_fpu_except_flags): Initialize result. (get_fpu_except_flags): Initialize result.
......
...@@ -95,24 +95,28 @@ has_sse (void) ...@@ -95,24 +95,28 @@ has_sse (void)
#define _FPU_MASK_OM 0x08 #define _FPU_MASK_OM 0x08
#define _FPU_MASK_UM 0x10 #define _FPU_MASK_UM 0x10
#define _FPU_MASK_PM 0x20 #define _FPU_MASK_PM 0x20
#define _FPU_MASK_ALL 0x3f
#define _FPU_EX_ALL 0x3f
void set_fpu (void) void set_fpu (void)
{ {
int excepts = 0;
unsigned short cw; unsigned short cw;
__asm__ __volatile__ ("fnstcw\t%0" : "=m" (cw)); __asm__ __volatile__ ("fstcw\t%0" : "=m" (cw));
cw |= (_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM if (options.fpe & GFC_FPE_INVALID) excepts |= _FPU_MASK_IM;
| _FPU_MASK_UM | _FPU_MASK_PM); if (options.fpe & GFC_FPE_DENORMAL) excepts |= _FPU_MASK_DM;
if (options.fpe & GFC_FPE_ZERO) excepts |= _FPU_MASK_ZM;
if (options.fpe & GFC_FPE_OVERFLOW) excepts |= _FPU_MASK_OM;
if (options.fpe & GFC_FPE_UNDERFLOW) excepts |= _FPU_MASK_UM;
if (options.fpe & GFC_FPE_INEXACT) excepts |= _FPU_MASK_PM;
if (options.fpe & GFC_FPE_INVALID) cw &= ~_FPU_MASK_IM; cw |= _FPU_MASK_ALL;
if (options.fpe & GFC_FPE_DENORMAL) cw &= ~_FPU_MASK_DM; cw &= ~excepts;
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_INEXACT) cw &= ~_FPU_MASK_PM;
__asm__ __volatile__ ("fldcw\t%0" : : "m" (cw)); __asm__ __volatile__ ("fnclex\n\tfldcw\t%0" : : "m" (cw));
if (has_sse()) if (has_sse())
{ {
...@@ -120,45 +124,43 @@ void set_fpu (void) ...@@ -120,45 +124,43 @@ void set_fpu (void)
__asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse)); __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse));
cw_sse &= 0xffff0000; /* The SSE exception masks are shifted by 7 bits. */
cw_sse |= (_FPU_MASK_IM | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM cw_sse |= _FPU_MASK_ALL << 7;
| _FPU_MASK_UM | _FPU_MASK_PM ) << 7; cw_sse &= ~(excepts << 7);
if (options.fpe & GFC_FPE_INVALID) cw_sse &= ~(_FPU_MASK_IM << 7); /* Clear stalled exception flags. */
if (options.fpe & GFC_FPE_DENORMAL) cw_sse &= ~(_FPU_MASK_DM << 7); cw_sse &= ~_FPU_EX_ALL;
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_INEXACT) cw_sse &= ~(_FPU_MASK_PM << 7);
__asm__ __volatile__ ("%vldmxcsr\t%0" : : "m" (cw_sse)); __asm__ __volatile__ ("%vldmxcsr\t%0" : : "m" (cw_sse));
} }
} }
int int
get_fpu_except_flags (void) get_fpu_except_flags (void)
{ {
int result = 0;
unsigned short cw; unsigned short cw;
int excepts;
int result = 0;
__asm__ __volatile__ ("fnstsw\t%0" : "=a" (cw)); __asm__ __volatile__ ("fnstsw\t%0" : "=a" (cw));
excepts = cw;
if (has_sse()) if (has_sse())
{ {
unsigned int cw_sse; unsigned int cw_sse;
__asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse)); __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse));
excepts |= cw_sse;
cw |= cw_sse;
} }
if (cw & _FPU_MASK_IM) result |= GFC_FPE_INVALID; excepts &= _FPU_EX_ALL;
if (cw & _FPU_MASK_DM) result |= GFC_FPE_DENORMAL;
if (cw & _FPU_MASK_ZM) result |= GFC_FPE_ZERO; if (excepts & _FPU_MASK_IM) result |= GFC_FPE_INVALID;
if (cw & _FPU_MASK_OM) result |= GFC_FPE_OVERFLOW; if (excepts & _FPU_MASK_DM) result |= GFC_FPE_DENORMAL;
if (cw & _FPU_MASK_UM) result |= GFC_FPE_UNDERFLOW; if (excepts & _FPU_MASK_ZM) result |= GFC_FPE_ZERO;
if (cw & _FPU_MASK_PM) result |= GFC_FPE_INEXACT; if (excepts & _FPU_MASK_OM) result |= GFC_FPE_OVERFLOW;
if (excepts & _FPU_MASK_UM) result |= GFC_FPE_UNDERFLOW;
if (excepts & _FPU_MASK_PM) result |= GFC_FPE_INEXACT;
return result; return result;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment