]> granicus.if.org Git - gc/commitdiff
2011-02-09 Ivan Maidanski <ivmai@mail.ru> (mostly Jean-Claude Beaudoin)
authorivmai <ivmai>
Sat, 12 Feb 2011 14:43:27 +0000 (14:43 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 26 Jul 2011 17:06:56 +0000 (21:06 +0400)
* mach_dep.c (GC_with_callee_saves_pushed): Fix and improve code
introduced by the previous patch (if GETCONTEXT_FPU_EXCMASK_BUG
and X86_64).

ChangeLog
mach_dep.c

index 2c8dc557fcddbb152636c921ad07c73fdbe75b8d..42d3ff236298336ab0aa6587e9baa93ecf97198c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2011-02-09  Ivan Maidanski  <ivmai@mail.ru> (mostly Jean-Claude Beaudoin)
+
+       * mach_dep.c (GC_with_callee_saves_pushed): Fix and improve code
+       introduced by the previous patch (if GETCONTEXT_FPU_EXCMASK_BUG
+       and X86_64).
+
 2011-01-22  Ivan Maidanski  <ivmai@mail.ru> (mostly Jean-Claude Beaudoin)
 
        * darwin_stop_world.c (GC_FindTopOfStack): Prefix and suffix
index 0753d504243620359f62f54ac4fb0eb3ffa66846..15f8e4d95ceba14d037003adfeb6b487632334d5 100644 (file)
@@ -211,11 +211,10 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *),
         /* Workaround a bug (clearing the FPU exception mask) in        */
         /* getcontext on Linux/x86_64.                                  */
 #       ifdef X86_64
-          /* We inline fegetexcept and feenableexcept here just not to  */
-          /* force the client application to use -lm linker option.     */
-          unsigned short except_mask;
-          __asm__ __volatile__ ("fstcw %0" : "=m" (*&except_mask));
-          except_mask &= FE_ALL_EXCEPT;
+          /* We manipulate FPU control word here just not to force the  */
+          /* client application to use -lm linker option.               */
+          unsigned short old_fcw;
+          __asm__ __volatile__ ("fstcw %0" : "=m" (*&old_fcw));
 #       else
           int except_mask = fegetexcept();
 #       endif
@@ -224,18 +223,14 @@ GC_INNER void GC_with_callee_saves_pushed(void (*fn)(ptr_t, void *),
         ABORT ("getcontext failed: Use another register retrieval method?");
 #     ifdef GETCONTEXT_FPU_EXCMASK_BUG
 #       ifdef X86_64
+          __asm__ __volatile__ ("fldcw %0" : : "m" (*&old_fcw));
           {
-            unsigned short new_exc;
-            unsigned int new_exc_sse;
-            /* Get the current control word of the x87 FPU.     */
-            __asm__ __volatile__ ("fstcw %0" : "=m" (*&new_exc));
-            new_exc &= except_mask;
-            __asm__ __volatile__ ("fldcw %0" : : "m" (*&new_exc));
-            /* And now the same for the SSE MXCSR register. */
-            __asm__ __volatile__ ("stmxcsr %0" : "=m" (*&new_exc_sse));
-            /* The SSE exception masks are shifted by 7 bits. */
-            new_exc_sse &= except_mask << 7;
-            __asm__ __volatile__ ("ldmxcsr %0" : : "m" (*&new_exc_sse));
+            unsigned mxcsr;
+            /* And now correct the exception mask in SSE MXCSR. */
+            __asm__ __volatile__ ("stmxcsr %0" : "=m" (*&mxcsr));
+            mxcsr = (mxcsr & ~(ALL_EXCEPT << 7)) |
+                        ((old_fcw & ALL_EXCEPT) << 7);
+            __asm__ __volatile__ ("ldmxcsr %0" : : "m" (*&mxcsr));
           }
 #       else /* !X86_64 */
           if (feenableexcept(except_mask) < 0)