From c9e54dd7a2a3264225cb788546e923bbebc44d6e Mon Sep 17 00:00:00 2001
From: dtc <dtc>
Date: Thu, 11 Nov 1999 16:14:16 +0000
Subject: [PATCH] For Linux i386, restore the FPU control word in the SIGTRAP
 handler, otherwise the set of masked exceptions may be lost. Further, when
 restoring the FPU control word restore the rounding mode to its required
 default of round-to-nearest.

---
 lisp/interrupt.c | 26 +++++++++++++++++---------
 lisp/x86-arch.c  | 10 +++++++++-
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/lisp/interrupt.c b/lisp/interrupt.c
index 8461295cb..7edc5ff8c 100644
--- a/lisp/interrupt.c
+++ b/lisp/interrupt.c
@@ -1,4 +1,4 @@
-/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interrupt.c,v 1.20 1999/09/16 15:26:01 dtc Exp $ */
+/* $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/interrupt.c,v 1.21 1999/11/11 16:14:16 dtc Exp $ */
 
 /* Interrupt handing magic. */
 
@@ -259,15 +259,19 @@ interrupt_handle_pending(struct sigcontext *context)
 void 
 interrupt_handle_now(HANDLER_ARGS)
 {
-#if ( defined( __linux__ ) && defined( i386 ) )
-  GET_CONTEXT
+#if defined(__linux__) && defined(i386)
+    GET_CONTEXT
 #endif
 
     int were_in_lisp;
     union interrupt_handler handler;
 
-#if ( defined( __linux__ ) && defined( i386 ) )
-    setfpucw(contextstruct.fpstate->cw);
+#if defined(__linux__) && defined(i386)
+    /*
+     * Restore the FPU control word, setting the rounding mode to nearest.
+     */
+
+    setfpucw(contextstruct.fpstate->cw & ~0xc00);
 #endif
 
     handler = interrupt_handlers[signal];
@@ -349,14 +353,18 @@ interrupt_handle_now(HANDLER_ARGS)
 static void 
 maybe_now_maybe_later(HANDLER_ARGS)
 {
-#if ( defined( __linux__ ) && defined( i386 ) )
-  GET_CONTEXT
+#if defined(__linux__) && defined(i386)
+    GET_CONTEXT
 #endif
 
     SAVE_CONTEXT(); /**/
 
-#if ( defined( __linux__ ) && defined( i386 ) )
-    setfpucw(contextstruct.fpstate->cw);
+#if defined(__linux__) && defined(i386)
+    /*
+     * Restore the FPU control word, setting the rounding mode to nearest.
+     */
+
+    setfpucw(contextstruct.fpstate->cw & ~0xc00);
 #endif
 
     if (SymbolValue(INTERRUPTS_ENABLED) == NIL) {
diff --git a/lisp/x86-arch.c b/lisp/x86-arch.c
index 97b10264b..cda357d13 100644
--- a/lisp/x86-arch.c
+++ b/lisp/x86-arch.c
@@ -1,6 +1,6 @@
 /* x86-arch.c -*- Mode: C; comment-column: 40 -*-
  *
- * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/x86-arch.c,v 1.10 1998/02/19 18:58:20 dtc Exp $ 
+ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/x86-arch.c,v 1.11 1999/11/11 16:14:16 dtc Exp $ 
  *
  */
 
@@ -201,6 +201,14 @@ sigtrap_handler(HANDLER_ARGS)
   /* this is just for info in case monitor wants to print an approx */
   current_control_stack_pointer = (unsigned long*)context->sc_sp;
 
+#if defined(__linux__) && defined(i386)
+  /*
+   * Restore the FPU control word, setting the rounding mode to nearest.
+   */
+
+  setfpucw(contextstruct.fpstate->cw & ~0xc00);
+#endif
+
  /* On entry %eip points just after the INT3 byte and aims at the
   * 'kind' value (eg trap_Cerror). For error-trap and Cerror-trap a
   * number of bytes will follow, the first is the length of the byte
-- 
GitLab