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