summaryrefslogtreecommitdiffstats
path: root/libgfortran
diff options
context:
space:
mode:
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2013-07-23 09:45:30 +0000
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2013-07-23 09:45:30 +0000
commitc44e7bbcfedc31f3477c652fbb6ac5ae0a720d2e (patch)
tree66075d6c03d929790aa9ef04762111706d295821 /libgfortran
parent558c90bd94b2926d672f9af47e343c7670258ba5 (diff)
downloadppe42-gcc-c44e7bbcfedc31f3477c652fbb6ac5ae0a720d2e.tar.gz
ppe42-gcc-c44e7bbcfedc31f3477c652fbb6ac5ae0a720d2e.zip
* 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')
-rw-r--r--libgfortran/ChangeLog7
-rw-r--r--libgfortran/config/fpu-387.h37
2 files changed, 32 insertions, 12 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 0a035ebb238..940d41444a5 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,4 +1,9 @@
-2013-07-21 Ondřej Bílka <neleai@seznam.cz>
+2013-07-23 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/fpu-387.h (get_fpu_rounding_mode): Read rounding mode
+ from SSE mxcsr register on x86_64.
+
+2013-07-21 Ondřej Bílka <neleai@seznam.cz>
* io/transfer.c: Fix comment typos.
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;
OpenPOWER on IntegriCloud