diff options
author | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-07-23 09:45:30 +0000 |
---|---|---|
committer | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-07-23 09:45:30 +0000 |
commit | c44e7bbcfedc31f3477c652fbb6ac5ae0a720d2e (patch) | |
tree | 66075d6c03d929790aa9ef04762111706d295821 /libgfortran/config | |
parent | 558c90bd94b2926d672f9af47e343c7670258ba5 (diff) | |
download | gcc-c44e7bbcfedc31f3477c652fbb6ac5ae0a720d2e.tar.gz |
* config/fpu-387.h (get_fpu_rounding_mode): Read rounding mode
from SSE mxcsr register on x86_64.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201161 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgfortran/config')
-rw-r--r-- | libgfortran/config/fpu-387.h | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/libgfortran/config/fpu-387.h b/libgfortran/config/fpu-387.h index 62f1e935b53..b35c315445c 100644 --- a/libgfortran/config/fpu-387.h +++ b/libgfortran/config/fpu-387.h @@ -102,11 +102,11 @@ has_sse (void) /* i387 rounding modes. */ #define _FPU_RC_NEAREST 0x0 -#define _FPU_RC_DOWN 0x400 -#define _FPU_RC_UP 0x800 -#define _FPU_RC_ZERO 0xc00 +#define _FPU_RC_DOWN 0x1 +#define _FPU_RC_UP 0x2 +#define _FPU_RC_ZERO 0x3 -#define _FPU_RC_MASK 0xc00 +#define _FPU_RC_MASK 0x3 void @@ -202,8 +202,9 @@ set_fpu_rounding_mode (int round) __asm__ __volatile__ ("fnstcw\t%0" : "=m" (cw)); - cw &= ~_FPU_RC_MASK; - cw |= round_mode; + /* The x87 round control bits are shifted by 10 bits. */ + cw &= ~(_FPU_RC_MASK << 10); + cw |= round_mode << 10; __asm__ __volatile__ ("fldcw\t%0" : : "m" (cw)); @@ -213,9 +214,9 @@ set_fpu_rounding_mode (int round) __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw_sse)); - /* The SSE round control bits are shifted by 3 bits. */ - cw_sse &= ~(_FPU_RC_MASK << 3); - cw_sse |= round_mode << 3; + /* The SSE round control bits are shifted by 13 bits. */ + cw_sse &= ~(_FPU_RC_MASK << 13); + cw_sse |= round_mode << 13; __asm__ __volatile__ ("%vldmxcsr\t%0" : : "m" (cw_sse)); } @@ -224,13 +225,27 @@ set_fpu_rounding_mode (int round) int get_fpu_rounding_mode (void) { + int round_mode; + +#ifdef __x86_64__ + unsigned int cw; + + __asm__ __volatile__ ("%vstmxcsr\t%0" : "=m" (cw)); + + /* The SSE round control bits are shifted by 13 bits. */ + round_mode = cw >> 13; +#else unsigned short cw; __asm__ __volatile__ ("fnstcw\t%0" : "=m" (cw)); - cw &= _FPU_RC_MASK; + /* The x87 round control bits are shifted by 10 bits. */ + round_mode = cw >> 10; +#endif + + round_mode &= _FPU_RC_MASK; - switch (cw) + switch (round_mode) { case _FPU_RC_NEAREST: return GFC_FPE_TONEAREST; |