From: Nikodemus Siivola Date: Wed, 25 Oct 2006 16:24:43 +0000 (+0000) Subject: 0.9.18.1: Small floating point related tweaks X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=8c82cc1e67fe8116431a1d2d4e79005114ff1697;p=sbcl.git 0.9.18.1: Small floating point related tweaks * Introduce FLOAT-COLD-INIT-OR-REINIT fixing a couple of COLD-INIT/REINIT FIXME's for more OAOO. * Save floating point modes in core, and restore them on startup. * Move SET/GET-FLOATING-POINT-MODES documentation from comments to docstrings. --- diff --git a/NEWS b/NEWS index a984c1b..c6ebb72 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,8 @@ ;;;; -*- coding: utf-8; -*- +changes in sbcl-0.9.19 (1.0.0?) relative to sbcl-0.9.18: + * improvement: floating point modes in effect are now saved in + core, and restored on startup. + changes in sbcl-0.9.18 (1.0.beta?) relative to sbcl-0.9.17: * enhancement: SB-POSIX now supports cfsetispeed(3), cfsetospeed(3), cfgetispeed(3), cfgetospeed(3), and related constants. (thanks to diff --git a/package-data-list.lisp-expr b/package-data-list.lisp-expr index 507eae4..8dd35c9 100644 --- a/package-data-list.lisp-expr +++ b/package-data-list.lisp-expr @@ -1588,12 +1588,16 @@ is a good idea, but see SB-SYS re. blurring of boundaries." "!LATE-PROCLAIM-COLD-INIT" "!CLASS-FINALIZE" "!CONSTANTP-COLD-INIT" + "FLOAT-COLD-INIT-OR-REINIT" "GC-REINIT" "SIGNAL-COLD-INIT-OR-REINIT" "STREAM-COLD-INIT-OR-RESET" ;; Cleanups to run before saving a core - "DEBUG-DEINIT" "FOREIGN-DEINIT" "PROFILE-DEINIT" + "DEBUG-DEINIT" + "FLOAT-DEINIT" + "FOREIGN-DEINIT" + "PROFILE-DEINIT" ;; Note: These are out of lexicographical order ;; because in CMU CL they were defined as diff --git a/src/code/cold-init.lisp b/src/code/cold-init.lisp index eb223cb..69e0541 100644 --- a/src/code/cold-init.lisp +++ b/src/code/cold-init.lisp @@ -228,14 +228,7 @@ (/show0 "enabling internal errors") (setf (sb!alien:extern-alien "internal_errors_enabled" boolean) t) - ;; FIXME: This list of modes should be defined in one place and - ;; explicitly shared between here and REINIT. - - ;; FIXME: For some unknown reason, NetBSD/x86 won't run with the - ;; :invalid trap enabled. That should be fixed, but not today... - ;; PEM -- April 5, 2004 - (set-floating-point-modes - :traps '(:overflow #!-netbsd :invalid :divide-by-zero)) + (show-and-call float-cold-init-or-reinit) (show-and-call !class-finalize) @@ -297,17 +290,10 @@ UNIX-like systems, UNIX-STATUS is used as the status code." (os-cold-init-or-reinit) (thread-init-or-reinit) (stream-reinit) - #!-win32 (signal-cold-init-or-reinit) + #!-win32 + (signal-cold-init-or-reinit) (setf (sb!alien:extern-alien "internal_errors_enabled" boolean) t) - ;; PRINT seems not to like x86 NPX denormal floats like - ;; LEAST-NEGATIVE-SINGLE-FLOAT, so the :UNDERFLOW exceptions are - ;; disabled by default. Joe User can explicitly enable them if - ;; desired. - ;; - ;; see also comment at the previous SET-FLOATING-POINT-MODES - ;; call site. - (set-floating-point-modes - :traps '(:overflow #!-netbsd :invalid :divide-by-zero)))) + (float-cold-init-or-reinit))) (gc-reinit) ;; make sure TIME works correctly from saved cores (setf *internal-real-time-base-seconds* nil) diff --git a/src/code/error.lisp b/src/code/error.lisp index 6827435..e9092b9 100644 --- a/src/code/error.lisp +++ b/src/code/error.lisp @@ -171,3 +171,4 @@ (lambda (condition stream) (declare (ignore condition)) (format stream "memory fault")))) + diff --git a/src/code/float-trap.lisp b/src/code/float-trap.lisp index 4ba4d1b..0211aa7 100644 --- a/src/code/float-trap.lisp +++ b/src/code/float-trap.lisp @@ -55,44 +55,46 @@ (defun (setf floating-point-modes) (new) (setf (floating-point-modes) new))) -;;; This function sets options controlling the floating-point -;;; hardware. If a keyword is not supplied, then the current value is -;;; preserved. Possible keywords: -;;; :TRAPS -;;; A list of the exception conditions that should cause traps. -;;; Possible exceptions are :UNDERFLOW, :OVERFLOW, :INEXACT, :INVALID, -;;; :DIVIDE-BY-ZERO, and on the X86 :DENORMALIZED-OPERAND. -;;; -;;;:ROUNDING-MODE -;;; The rounding mode to use when the result is not exact. Possible -;;; values are :NEAREST, :POSITIVE-INFINITY, :NEGATIVE-INFINITY and -;;; :ZERO. Setting this away from :NEAREST is liable to upset SBCL's -;;; maths routines which depend on it. -;;; -;;;:CURRENT-EXCEPTIONS -;;;:ACCRUED-EXCEPTIONS -;;; These arguments allow setting of the exception flags. The main -;;; use is setting the accrued exceptions to NIL to clear them. -;;; -;;;:FAST-MODE -;;; Set the hardware's \"fast mode\" flag, if any. When set, IEEE -;;; conformance or debuggability may be impaired. Some machines don't -;;; have this feature, and some SBCL ports don't implement it anyway -;;; -- in such cases the value is always NIL. -;;; -;;;:PRECISION (x86 only) :24-bit, :53-bit and :64-bit, for the -;;;internal precision of the mantissa. -;;; -;;; GET-FLOATING-POINT-MODES may be used to find the floating point modes -;;; currently in effect. See cold-init.lisp for the list of initially -;;; enabled traps - -(defun set-floating-point-modes (&key (traps nil traps-p) - (rounding-mode nil round-p) - (current-exceptions nil current-x-p) - (accrued-exceptions nil accrued-x-p) - (fast-mode nil fast-mode-p) +(defun set-floating-point-modes (&key + (traps nil traps-p) + (rounding-mode nil round-p) + (current-exceptions nil current-x-p) + (accrued-exceptions nil accrued-x-p) + (fast-mode nil fast-mode-p) #!+x86 (precision nil precisionp)) + #!+sb-doc + "This function sets options controlling the floating-point +hardware. If a keyword is not supplied, then the current value is +preserved. Possible keywords: + + :TRAPS + A list of the exception conditions that should cause traps. + Possible exceptions are :UNDERFLOW, :OVERFLOW, :INEXACT, :INVALID, + :DIVIDE-BY-ZERO, and on the X86 :DENORMALIZED-OPERAND. + +:ROUNDING-MODE + The rounding mode to use when the result is not exact. Possible + values are :NEAREST, :POSITIVE-INFINITY, :NEGATIVE-INFINITY and + :ZERO. Setting this away from :NEAREST is liable to upset SBCL's + maths routines which depend on it. + +:CURRENT-EXCEPTIONS +:ACCRUED-EXCEPTIONS + These arguments allow setting of the exception flags. The main + use is setting the accrued exceptions to NIL to clear them. + +:FAST-MODE + Set the hardware's \"fast mode\" flag, if any. When set, IEEE + conformance or debuggability may be impaired. Some machines don't + have this feature, and some SBCL ports don't implement it anyway + -- in such cases the value is always NIL. + +:PRECISION (x86 only) + :24-bit, :53-bit and :64-bit, for the internal precision of the mantissa. + +GET-FLOATING-POINT-MODES may be used to find the floating point modes +currently in effect. SAVE-LISP-AND-DIE preserves the floating point modes +in effect." (let ((modes (floating-point-modes))) (when traps-p (setf (ldb float-traps-byte modes) (float-trap-mask traps))) @@ -117,16 +119,17 @@ (error "unknown precision mode: ~S" precision)))) ;; FIXME: This apparently doesn't work on Darwin #!-darwin (setf (floating-point-modes) modes)) - (values)) -;;; This function returns a list representing the state of the floating -;;; point modes. The list is in the same format as the &KEY arguments to -;;; SET-FLOATING-POINT-MODES, i.e. -;;; (apply #'set-floating-point-modes (get-floating-point-modes)) -;;; sets the floating point modes to their current values (and thus is a -;;; no-op). (defun get-floating-point-modes () + #!+sb-doc + "This function returns a list representing the state of the floating +point modes. The list is in the same format as the &KEY arguments to +SET-FLOATING-POINT-MODES, i.e. + + (apply #'set-floating-point-modes (get-floating-point-modes)) + +sets the floating point modes to their current values (and thus is a no-op)." (flet ((exc-keys (bits) (macrolet ((frob () `(collect ((res)) @@ -147,6 +150,24 @@ #!+x86 ,(car (rassoc (ldb float-precision-control modes) *precision-mode-alist*)))))) +;;; FIXME: For some unknown reason, NetBSD/x86 won't run with the +;;; :INVALID trap enabled. That should be fixed, but not today... +;;; +;;; PRINT seems not to like x86 NPX denormal floats like +;;; LEAST-NEGATIVE-SINGLE-FLOAT, so the :UNDERFLOW exceptions are +;;; disabled by default. Joe User can explicitly enable them if +;;; desired. +(defvar *saved-floating-point-modes* + '(:traps (:overflow #!-netbsd :invalid :divide-by-zero) + :rounding-mode :nearest :current-exceptions nil + :accrued-exceptions nil :fast-mode nil :precision :53-bit)) + +(defun float-cold-init-or-reinit () + (apply #'set-floating-point-modes *saved-floating-point-modes*)) + +(defun float-deinit () + (setf *saved-floating-point-modes* (get-floating-point-modes))) + ;;; Return true if any of the named traps are currently trapped, false ;;; otherwise. (defmacro current-float-trap (&rest traps) @@ -154,6 +175,7 @@ (floating-point-modes))))) ;;; Signal the appropriate condition when we get a floating-point error. +#!-win32 (defun sigfpe-handler (signal info context) (declare (ignore signal info)) (declare (type system-area-pointer context)) diff --git a/src/code/save.lisp b/src/code/save.lisp index 77a9f1c..246ff23 100644 --- a/src/code/save.lisp +++ b/src/code/save.lisp @@ -147,6 +147,7 @@ sufficiently motivated to do lengthy fixes." (funcall hook))) #!-win32 (when (fboundp 'cancel-finalization) (cancel-finalization sb!sys:*tty*)) + (float-deinit) (profile-deinit) (debug-deinit) (foreign-deinit)) diff --git a/version.lisp-expr b/version.lisp-expr index c72341e..f3d58a4 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,5 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"0.9.18" +"0.9.18.1" +