summaryrefslogtreecommitdiffstats
path: root/lang/sbcl/files/patch-floating-point
diff options
context:
space:
mode:
Diffstat (limited to 'lang/sbcl/files/patch-floating-point')
-rw-r--r--lang/sbcl/files/patch-floating-point207
1 files changed, 207 insertions, 0 deletions
diff --git a/lang/sbcl/files/patch-floating-point b/lang/sbcl/files/patch-floating-point
new file mode 100644
index 0000000..35e1787
--- /dev/null
+++ b/lang/sbcl/files/patch-floating-point
@@ -0,0 +1,207 @@
+Index: src/code/float-trap.lisp
+===================================================================
+RCS file: /cvsroot/sbcl/sbcl/src/code/float-trap.lisp,v
+retrieving revision 1.18
+diff -u -r1.18 float-trap.lisp
+--- src/code/float-trap.lisp 14 Jul 2005 16:30:34 -0000 1.18
++++ src/code/float-trap.lisp 27 Sep 2005 22:36:42 -0000
+@@ -153,10 +153,28 @@
+ `(not (zerop (logand ,(dpb (float-trap-mask traps) float-traps-byte 0)
+ (floating-point-modes)))))
+
++;;; SIGFPE code to floating-point error
++#+freebsd
++(defparameter *sigfpe-code-error-alist*
++ (list (cons sb!unix::fpe-intovf 'floating-point-overflow)
++ (cons sb!unix::fpe-intdiv 'division-by-zero)
++ (cons sb!unix::fpe-fltdiv 'division-by-zero)
++ (cons sb!unix::fpe-fltovf 'floating-point-overflow)
++ (cons sb!unix::fpe-fltund 'floating-point-underflow)
++ (cons sb!unix::fpe-fltres 'floating-point-inexact)
++ (cons sb!unix::fpe-fltinv 'floating-point-invalid-operation)
++ (cons sb!unix::fpe-fltsub 'floating-point-exception)))
++
+ ;;; Signal the appropriate condition when we get a floating-point error.
+ (defun sigfpe-handler (signal info context)
+- (declare (ignore signal info))
++ (declare (ignore signal #!-freebsd info))
++ #!+freebsd
++ (declare (type system-area-pointer info))
+ (declare (type system-area-pointer context))
++ #!+freebsd
++ (let ((code (sb!unix::siginfo-code info)))
++ (error (or (cdr (assoc code *sigfpe-code-error-alist*))
++ 'floating-point-exception)))
+ (let* ((modes (context-floating-point-modes
+ (sb!alien:sap-alien context (* os-context-t))))
+ (traps (logand (ldb float-exceptions-byte modes)
+Index: src/code/target-signal.lisp
+===================================================================
+RCS file: /cvsroot/sbcl/sbcl/src/code/target-signal.lisp,v
+retrieving revision 1.28
+diff -u -r1.28 target-signal.lisp
+--- src/code/target-signal.lisp 4 Sep 2005 20:14:49 -0000 1.28
++++ src/code/target-signal.lisp 27 Sep 2005 22:36:42 -0000
+@@ -149,6 +149,10 @@
+
+ ;;;; etc.
+
++;;; extract si_code from siginfo_t
++(sb!alien:define-alien-routine ("siginfo_code" siginfo-code) sb!alien:int
++ (info system-area-pointer))
++
+ ;;; CMU CL comment:
+ ;;; Magically converted by the compiler into a break instruction.
+ (defun receive-pending-interrupt ()
+Index: src/runtime/interrupt.c
+===================================================================
+RCS file: /cvsroot/sbcl/sbcl/src/runtime/interrupt.c,v
+retrieving revision 1.94
+diff -u -r1.94 interrupt.c
+--- src/runtime/interrupt.c 13 Sep 2005 12:28:41 -0000 1.94
++++ src/runtime/interrupt.c 27 Sep 2005 22:36:42 -0000
+@@ -426,7 +426,7 @@
+ if (sigismember(&deferrable_sigset,signal))
+ check_interrupts_enabled_or_lose(context);
+
+-#ifdef LISP_FEATURE_LINUX
++#if defined(LISP_FEATURE_LINUX) || defined(__FreeBSD__)
+ /* Under Linux on some architectures, we appear to have to restore
+ the FPU control word from the context, as after the signal is
+ delivered we appear to have a null FPU control word. */
+@@ -606,7 +606,7 @@
+ os_context_t *context = arch_os_get_context(&void_context);
+ struct thread *thread=arch_os_get_current_thread();
+ struct interrupt_data *data=thread->interrupt_data;
+-#ifdef LISP_FEATURE_LINUX
++#if defined(LISP_FEATURE_LINUX) || defined(__FreeBSD__)
+ os_restore_fp_control(context);
+ #endif
+ if(maybe_defer_handler(interrupt_handle_now,data,signal,info,context))
+@@ -623,7 +623,7 @@
+ {
+ os_context_t *context = (os_context_t*)void_context;
+
+-#ifdef LISP_FEATURE_LINUX
++#if defined(LISP_FEATURE_LINUX) || defined(__FreeBSD__)
+ os_restore_fp_control(context);
+ #endif
+ check_blockables_blocked_or_lose();
+@@ -641,7 +641,7 @@
+ os_context_t *context = arch_os_get_context(&void_context);
+ struct thread *thread=arch_os_get_current_thread();
+ struct interrupt_data *data=thread->interrupt_data;
+-#ifdef LISP_FEATURE_LINUX
++#if defined(LISP_FEATURE_LINUX) || defined(__FreeBSD__)
+ os_restore_fp_control(context);
+ #endif
+ if(maybe_defer_handler(low_level_interrupt_handle_now,data,
+@@ -1139,3 +1139,9 @@
+
+ SHOW("returning from interrupt_init()");
+ }
++
++int
++siginfo_code(siginfo_t *info)
++{
++ return info->si_code;
++}
+Index: src/runtime/x86-arch.c
+===================================================================
+RCS file: /cvsroot/sbcl/sbcl/src/runtime/x86-arch.c,v
+retrieving revision 1.32
+diff -u -r1.32 x86-arch.c
+--- src/runtime/x86-arch.c 27 Sep 2005 15:52:50 -0000 1.32
++++ src/runtime/x86-arch.c 27 Sep 2005 22:36:42 -0000
+@@ -229,7 +229,7 @@
+ single-stepping (as far as I can tell) this is somewhat moot,
+ but it might be worth either moving this code up or deleting
+ the single-stepping code entirely. -- CSR, 2002-07-15 */
+-#ifdef LISP_FEATURE_LINUX
++#if defined(LISP_FEATURE_LINUX) || defined(__FreeBSD__)
+ os_restore_fp_control(context);
+ #endif
+
+Index: src/runtime/x86-bsd-os.c
+===================================================================
+RCS file: /cvsroot/sbcl/sbcl/src/runtime/x86-bsd-os.c,v
+retrieving revision 1.7
+diff -u -r1.7 x86-bsd-os.c
+--- src/runtime/x86-bsd-os.c 14 Jul 2005 15:41:21 -0000 1.7
++++ src/runtime/x86-bsd-os.c 27 Sep 2005 22:36:42 -0000
+@@ -85,6 +85,52 @@
+ #endif /* __NetBSD__ */
+
+
++#ifdef __FreeBSD__
++#if __FreeBSD_version >= 500000
++/*
++ * FreeBSD 5.0 or later initializes FPU control word for signal
++ * handler.
++ */
++#include <machine/npx.h>
++
++static __inline__ void
++fldcw(unsigned short cw)
++{
++ __asm__ __volatile__ ("fldcw %0" : : "m" (cw));
++}
++
++void
++os_restore_fp_control(os_context_t *context)
++{
++ union savefpu *addr;
++
++ addr = (union savefpu *)context->uc_mcontext.mc_fpstate;
++ switch (context->uc_mcontext.mc_fpformat) {
++ case _MC_FPFMT_387:
++ /* FPU state is saved by fnsave */
++ fldcw((unsigned short)addr->sv_87.sv_env.en_cw);
++ break;
++ case _MC_FPFMT_XMM:
++ /* FPU/SSE state is saved by fxsave */
++ fldcw(addr->sv_xmm.sv_env.en_cw);
++ break;
++ default:
++ /* No FPU state is saved. */
++ break;
++ }
++}
++#else /* __FreeBSD_version < 500000 */
++/*
++ * FreeBSD befoer 5.0 does not touch FPU control word for signal
++ * handler.
++ */
++void
++os_restore_fp_control(os_context_t *context)
++{
++ /* DO NOTHING */
++}
++#endif /* __FreeBSD_version */
++#endif /* __FreeBSD__ */
+
+ /* FIXME: If this can be a no-op on BSD/x86, then it
+ * deserves a more precise name.
+Index: tools-for-build/grovel-headers.c
+===================================================================
+RCS file: /cvsroot/sbcl/sbcl/tools-for-build/grovel-headers.c,v
+retrieving revision 1.10
+diff -u -r1.10 grovel-headers.c
+--- tools-for-build/grovel-headers.c 14 Jul 2005 20:24:19 -0000 1.10
++++ tools-for-build/grovel-headers.c 27 Sep 2005 22:36:42 -0000
+@@ -223,5 +223,15 @@
+ defsignal("sigxcpu", SIGXCPU);
+ defsignal("sigxfsz", SIGXFSZ);
+ #endif
++#ifdef __FreeBSD__
++ defconstant("fpe-intovf", FPE_INTOVF);
++ defconstant("fpe-intdiv", FPE_INTDIV);
++ defconstant("fpe-fltdiv", FPE_FLTDIV);
++ defconstant("fpe-fltovf", FPE_FLTOVF);
++ defconstant("fpe-fltund", FPE_FLTUND);
++ defconstant("fpe-fltres", FPE_FLTRES);
++ defconstant("fpe-fltinv", FPE_FLTINV);
++ defconstant("fpe-fltsub", FPE_FLTSUB);
++#endif
+ return 0;
+ }
OpenPOWER on IntegriCloud