Raymond Toy pushed to branch rtoy-setexception-inexact at cmucl / cmucl
Commits:
90b9651b by Raymond Toy at 2015-12-27T21:02:14Z
Clean up with-float-traps macro.
* Add some comments.
* Change x86 (setf floating-point-modes) to accept (unsigned-byte
32).
* Remove unneeded x86 conditionalization on the byte size.
- - - - -
1 changed file:
- src/code/float-trap.lisp
Changes:
=====================================
src/code/float-trap.lisp
=====================================
--- a/src/code/float-trap.lisp
+++ b/src/code/float-trap.lisp
@@ -104,7 +104,7 @@
final-mode))
(defun (setf floating-point-modes) (new-mode)
- (declare (type (unsigned-byte 24) new-mode))
+ (declare (type (unsigned-byte 32) new-mode))
;; Set the floating point modes for both X87 and SSE2. This
;; include the rounding control bits.
(let* ((rc (ldb float-rounding-mode new-mode))
@@ -117,8 +117,8 @@
;; is ok and would be the correct setting if we
;; ever support long-floats.
(ash 3 8))))
- (setf (vm::sse2-floating-point-modes) new-mode)
- (setf (vm::x87-floating-point-modes) x87-modes))
+ (setf (vm::sse2-floating-point-modes) (ldb (byte 24 0) new-mode))
+ (setf (vm::x87-floating-point-modes) (ldb (byte 24 0) x87-modes)))
new-mode)
)
@@ -365,12 +365,12 @@
(error _"SIGFPE with no exceptions currently enabled? (si-code = ~D)"
code)))))))
-;;; WITH-FLOAT-TRAPS-MASKED -- Public
-;;; WITH-FLOAT-TRAPS-ENABLED -- Public
-
-
(macrolet
((with-float-traps (name logical-op docstring)
+ ;; Define macros to enable or disable floating-point
+ ;; exceptions. Masked exceptions and enabled exceptions only
+ ;; differ whether we AND in the bits or OR them, respectively.
+ ;; Logical-op is the operation to use.
(let ((macro-name (symbolicate "WITH-FLOAT-TRAPS-" name)))
`(progn
(defmacro ,macro-name (traps &body body)
@@ -398,9 +398,7 @@
(unwind-protect
(progn
(setf (floating-point-modes)
- (ldb (byte #+x86 24
- #-x86 32
- 0)
+ (ldb (byte 32 0)
(,',logical-op ,orig-modes ,(logand trap-mask exception-mask))))
,@body)
;; Restore the original traps and exceptions.
@@ -411,8 +409,8 @@
#+ppc
,invalid-mask
#+mips ,(dpb 0 float-exceptions-byte #xffffffff))))))))))))
- ;; Masked and Enabled only differ whether we AND in the bits or OR
- ;; them.
+
+ ;; WITH-FLOAT-TRAPS-MASKED -- Public
(with-float-traps masked logand
_N"Execute BODY with the floating point exceptions listed in TRAPS
masked (disabled). TRAPS should be a list of possible exceptions
@@ -421,6 +419,7 @@
accrued exceptions are cleared at the start of the body to support
their testing within, and restored on exit.")
+ ;; WITH-FLOAT-TRAPS-ENABLED -- Public
(with-float-traps enabled logorc2
_N"Execute BODY with the floating point exceptions listed in TRAPS
enabled. TRAPS should be a list of possible exceptions which
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/commit/90b9651bf60a59800f76a6e7f…
Raymond Toy pushed to branch rtoy-setexception-inexact at cmucl / cmucl
Commits:
0fc0061b by Raymond Toy at 2015-12-27T10:16:45Z
Disable FP traps when printing arithmetic-error messages
Printing of FP numbers can signal some traps like overflow, underflow,
inexact, or denormalized-operand, so we need to disable these traps
when printing out the error message for arithmetic errors.
- - - - -
62acaf64 by Raymond Toy at 2015-12-27T10:36:59Z
Merge branch 'master' into rtoy-setexception-inexact
- - - - -
1 changed file:
- src/code/error.lisp
Changes:
=====================================
src/code/error.lisp
=====================================
--- a/src/code/error.lisp
+++ b/src/code/error.lisp
@@ -1138,9 +1138,14 @@
(format stream (intl:gettext "Arithmetic error ~S signalled.")
(type-of condition))
(when (arithmetic-error-operation condition)
- (format stream (intl:gettext "~%Operation was ~S, operands ~S.")
- (arithmetic-error-operation condition)
- (arithmetic-error-operands condition))))))
+ ;; Printing the operands can signal these FP traps, so
+ ;; disable them while we're printing out the error
+ ;; message.
+ (with-float-traps-masked (:overflow :underflow :inexact
+ #+x86 :denormalized-operand)
+ (format stream (intl:gettext "~%Operation was ~S, operands ~S.")
+ (arithmetic-error-operation condition)
+ (arithmetic-error-operands condition)))))))
(define-condition division-by-zero (arithmetic-error) ())
(define-condition floating-point-overflow (arithmetic-error) ())
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/compare/55b541e5fdac9794eae14859…
Raymond Toy pushed to branch master at cmucl / cmucl
Commits:
0fc0061b by Raymond Toy at 2015-12-27T10:16:45Z
Disable FP traps when printing arithmetic-error messages
Printing of FP numbers can signal some traps like overflow, underflow,
inexact, or denormalized-operand, so we need to disable these traps
when printing out the error message for arithmetic errors.
- - - - -
1 changed file:
- src/code/error.lisp
Changes:
=====================================
src/code/error.lisp
=====================================
--- a/src/code/error.lisp
+++ b/src/code/error.lisp
@@ -1138,9 +1138,14 @@
(format stream (intl:gettext "Arithmetic error ~S signalled.")
(type-of condition))
(when (arithmetic-error-operation condition)
- (format stream (intl:gettext "~%Operation was ~S, operands ~S.")
- (arithmetic-error-operation condition)
- (arithmetic-error-operands condition))))))
+ ;; Printing the operands can signal these FP traps, so
+ ;; disable them while we're printing out the error
+ ;; message.
+ (with-float-traps-masked (:overflow :underflow :inexact
+ #+x86 :denormalized-operand)
+ (format stream (intl:gettext "~%Operation was ~S, operands ~S.")
+ (arithmetic-error-operation condition)
+ (arithmetic-error-operands condition)))))))
(define-condition division-by-zero (arithmetic-error) ())
(define-condition floating-point-overflow (arithmetic-error) ())
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/commit/0fc0061b5302f516f051a5996…
Raymond Toy pushed to branch rtoy-setexception-inexact at cmucl / cmucl
Commits:
55b541e5 by Raymond Toy at 2015-12-26T09:49:25Z
Add shell script to run the test suite.
This makes it quite a bit easier to run the test suite instead of
trying to remember exactly how to invoke it from the command line.
- - - - -
1 changed file:
- + bin/run-tests.sh
Changes:
=====================================
bin/run-tests.sh
=====================================
--- /dev/null
+++ b/bin/run-tests.sh
@@ -0,0 +1,50 @@
+#! /bin/bash
+
+# Run the testsuite.
+#
+# By default, all the tests are run, but if additional args are given,
+# then just those tests are run.
+
+usage() {
+ echo "run-tests.sh [?] [-l lisp] [tests]"
+ echo " -l lisp Lisp to use for the tests; defaults to lisp"
+ echo " -? This help message"
+ echo ""
+ echo "Run the test suite"
+ echo ""
+ echo "Any remaining args are the names of the tests to run."
+ echo "These are basically the file names (without extension)"
+ echo "in the tests/ directory."
+ echo ""
+ echo "This script expects to be run from the top level of the"
+ echo "cmucl source tree. That is, is should be invoked as"
+ echo "bin/run-tests.sh"
+ exit 0;
+}
+
+LISP=lisp
+while getopts "h?l:" arg
+do
+ case $arg in
+ l) LISP=$OPTARG ;;
+ \?) usage ;;
+ esac
+done
+
+# Shift out the options
+shift $[$OPTIND - 1]
+
+if [ $# -eq 0 ]; then
+ # No args so run all the tests
+ $LISP -noinit -load tests/run-tests.lisp -eval '(cmucl-test-runner:run-all-tests)'
+else
+ # Run selected files. Convert each file name to uppercase and append "-TESTS"
+ result=""
+ for f in $*
+ do
+ new=`echo $f | tr '[a-z]' '[A-Z]'`
+ result="$result "\"$new-TESTS\"
+ done
+ $LISP -noinit -load tests/run-tests.lisp -eval "(progn (cmucl-test-runner:load-test-files) (cmucl-test-runner:run-test $result))"
+fi
+
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/commit/55b541e5fdac9794eae148597…
Raymond Toy pushed to branch rtoy-setexception-inexact at cmucl / cmucl
Commits:
6cc16b9b by Raymond Toy at 2015-12-26T09:11:40Z
Regenerated du to float-traps.lisp changes.
- - - - -
1 changed file:
- src/i18n/locale/cmucl.pot
Changes:
=====================================
src/i18n/locale/cmucl.pot
=====================================
--- a/src/i18n/locale/cmucl.pot
+++ b/src/i18n/locale/cmucl.pot
@@ -4797,6 +4797,16 @@ msgid ""
" their testing within, and restored on exit."
msgstr ""
+#: src/code/float-trap.lisp
+msgid ""
+"Execute BODY with the floating point exceptions listed in TRAPS\n"
+" enabled. TRAPS should be a list of possible exceptions which\n"
+" includes :UNDERFLOW, :OVERFLOW, :INEXACT, :INVALID and\n"
+" :DIVIDE-BY-ZERO and on the X86 :DENORMALIZED-OPERAND. The respective\n"
+" accrued exceptions are cleared at the start of the body to support\n"
+" their testing within, and restored on exit."
+msgstr ""
+
#: src/code/float.lisp
msgid "Return true if the float X is denormalized."
msgstr ""
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/commit/6cc16b9bcc660a2899a6205b6…
Raymond Toy pushed to branch rtoy-setexception-inexact at cmucl / cmucl
Commits:
38e8ce5c by Raymond Toy at 2015-12-26T09:09:56Z
Fix bug on sparc and clean up.
On sparc and ppc (setf vm:floating-point-modes) takes an
(unsigned-byte 32) arg, so adjust the ldb byte appopriately.
Clean up code by putting the docstring into the macro.
- - - - -
1 changed file:
- src/code/float-trap.lisp
Changes:
=====================================
src/code/float-trap.lisp
=====================================
--- a/src/code/float-trap.lisp
+++ b/src/code/float-trap.lisp
@@ -374,6 +374,7 @@
(let ((macro-name (symbolicate "WITH-FLOAT-TRAPS-" name)))
`(progn
(defmacro ,macro-name (traps &body body)
+ ,docstring
(let ((traps (dpb (float-trap-mask traps) float-traps-byte 0))
(exceptions (dpb (float-trap-mask traps) float-sticky-bits 0))
(trap-mask (dpb (lognot (float-trap-mask traps))
@@ -397,7 +398,9 @@
(unwind-protect
(progn
(setf (floating-point-modes)
- (ldb (byte 24 0)
+ (ldb (byte #+x86 24
+ #-x86 32
+ 0)
(,',logical-op ,orig-modes ,(logand trap-mask exception-mask))))
,@body)
;; Restore the original traps and exceptions.
@@ -407,25 +410,22 @@
,(logand trap-mask exception-mask)
#+ppc
,invalid-mask
- #+mips ,(dpb 0 float-exceptions-byte #xffffffff))))))))
- ;; Set the docstring appropriately
- (setf (c::info function documentation ',macro-name)
- ,docstring)))))
+ #+mips ,(dpb 0 float-exceptions-byte #xffffffff))))))))))))
;; Masked and Enabled only differ whether we AND in the bits or OR
;; them.
(with-float-traps masked logand
- "Execute BODY with the floating point exceptions listed in TRAPS
- disabled. TRAPS should be a list of possible exceptions which
- includes :UNDERFLOW, :OVERFLOW, :INEXACT, :INVALID and
+ _N"Execute BODY with the floating point exceptions listed in TRAPS
+ masked (disabled). TRAPS should be a list of possible exceptions
+ which includes :UNDERFLOW, :OVERFLOW, :INEXACT, :INVALID and
:DIVIDE-BY-ZERO and on the X86 :DENORMALIZED-OPERAND. The respective
accrued exceptions are cleared at the start of the body to support
their testing within, and restored on exit.")
+
(with-float-traps enabled logorc2
- "Execute BODY with the floating point exceptions listed in TRAPS
+ _N"Execute BODY with the floating point exceptions listed in TRAPS
enabled. TRAPS should be a list of possible exceptions which
includes :UNDERFLOW, :OVERFLOW, :INEXACT, :INVALID and
:DIVIDE-BY-ZERO and on the X86 :DENORMALIZED-OPERAND. The respective
accrued exceptions are cleared at the start of the body to support
their testing within, and restored on exit."))
-;; Set up the appropriate documentation for these macros
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/commit/38e8ce5c1084e1c55f9002882…
Raymond Toy pushed to branch rtoy-setexception-inexact at cmucl / cmucl
Commits:
5721ddd2 by Raymond Toy at 2015-12-24T11:46:36Z
Simplify WITH-FLOAT-TRAPS-MASKED and WITH-FLOAT-TRAPS-ENABLED.
Merge the body of both macros into one since they only differ in how
the bits are merged with the actual mode bits.
- - - - -
1 changed file:
- src/code/float-trap.lisp
Changes:
=====================================
src/code/float-trap.lisp
=====================================
--- a/src/code/float-trap.lisp
+++ b/src/code/float-trap.lisp
@@ -366,85 +366,52 @@
code)))))))
;;; WITH-FLOAT-TRAPS-MASKED -- Public
-;;;
-(defmacro with-float-traps-masked (traps &body body)
- "Execute BODY with the floating point exceptions listed in TRAPS
- masked (disabled). TRAPS should be a list of possible exceptions
- which includes :UNDERFLOW, :OVERFLOW, :INEXACT, :INVALID and
- :DIVIDE-BY-ZERO and on the X86 :DENORMALIZED-OPERAND. The respective
- accrued exceptions are cleared at the start of the body to support
- their testing within, and restored on exit."
- (let ((traps (dpb (float-trap-mask traps) float-traps-byte 0))
- (exceptions (dpb (float-trap-mask traps) float-sticky-bits 0))
- (trap-mask (dpb (lognot (float-trap-mask traps))
- float-traps-byte #xffffffff))
- (exception-mask (dpb (lognot (vm::float-trap-mask traps))
- float-sticky-bits #xffffffff))
- ;; On ppc if we are masking the invalid trap, we need to make
- ;; sure we wipe out the various individual sticky bits
- ;; representing the invalid operation. Otherwise, if we
- ;; enable the invalid trap later, these sticky bits will cause
- ;; an exception.
- #+ppc
- (invalid-mask (if (member :invalid traps)
- (dpb 0
- (byte 1 31)
- (dpb 0 vm::float-invalid-op-2-byte
- (dpb 0 vm:float-invalid-op-1-byte #xffffffff)))
- #xffffffff))
- (orig-modes (gensym)))
- `(let ((,orig-modes (floating-point-modes)))
- (unwind-protect
- (progn
- (setf (floating-point-modes)
- (logand ,orig-modes ,(logand trap-mask exception-mask)))
- ,@body)
- ;; Restore the original traps and exceptions.
- (setf (floating-point-modes)
- (logior (logand ,orig-modes ,(logior traps exceptions))
- (logand (floating-point-modes)
- ,(logand trap-mask exception-mask)
- #+ppc
- ,invalid-mask
- #+mips ,(dpb 0 float-exceptions-byte #xffffffff))))))))
-
-(defmacro with-float-traps-enabled (traps &body body)
- "Execute BODY with the floating point exceptions listed in TRAPS
+;;; WITH-FLOAT-TRAPS-ENABLED -- Public
+
+
+(macrolet
+ ((with-float-traps (name logical-op)
+ `(defmacro ,(symbolicate "WITH-FLOAT-TRAPS-" name) (traps &body body)
+ "Execute BODY with the floating point exceptions listed in TRAPS
enabled. TRAPS should be a list of possible exceptions which
includes :UNDERFLOW, :OVERFLOW, :INEXACT, :INVALID and
:DIVIDE-BY-ZERO and on the X86 :DENORMALIZED-OPERAND. The respective
accrued exceptions are cleared at the start of the body to support
their testing within, and restored on exit."
- (let ((traps (dpb (float-trap-mask traps) float-traps-byte 0))
- (exceptions (dpb (float-trap-mask traps) float-sticky-bits 0))
- (trap-mask (dpb (lognot (float-trap-mask traps))
- float-traps-byte #xffffffff))
- (exception-mask (dpb (lognot (vm::float-trap-mask traps))
- float-sticky-bits #xffffffff))
- ;; On ppc if we are masking the invalid trap, we need to make
- ;; sure we wipe out the various individual sticky bits
- ;; representing the invalid operation. Otherwise, if we
- ;; enable the invalid trap later, these sticky bits will cause
- ;; an exception.
- #+ppc
- (invalid-mask (if (member :invalid traps)
- (dpb 0
- (byte 1 31)
- (dpb 0 vm::float-invalid-op-2-byte
- (dpb 0 vm:float-invalid-op-1-byte #xffffffff)))
- #xffffffff))
- (orig-modes (gensym)))
- `(let ((,orig-modes (floating-point-modes)))
- (unwind-protect
- (progn
- (setf (floating-point-modes)
- (logorc2 ,orig-modes ,(logand trap-mask exception-mask)))
- ,@body)
- ;; Restore the original traps and exceptions.
- (setf (floating-point-modes)
- (logior (logand ,orig-modes ,(logior traps exceptions))
- (logand (floating-point-modes)
- ,(logand trap-mask exception-mask)
- #+ppc
- ,invalid-mask
- #+mips ,(dpb 0 float-exceptions-byte #xffffffff))))))))
+ (let ((traps (dpb (float-trap-mask traps) float-traps-byte 0))
+ (exceptions (dpb (float-trap-mask traps) float-sticky-bits 0))
+ (trap-mask (dpb (lognot (float-trap-mask traps))
+ float-traps-byte #xffffffff))
+ (exception-mask (dpb (lognot (vm::float-trap-mask traps))
+ float-sticky-bits #xffffffff))
+ ;; On ppc if we are masking the invalid trap, we need to make
+ ;; sure we wipe out the various individual sticky bits
+ ;; representing the invalid operation. Otherwise, if we
+ ;; enable the invalid trap later, these sticky bits will cause
+ ;; an exception.
+ #+ppc
+ (invalid-mask (if (member :invalid traps)
+ (dpb 0
+ (byte 1 31)
+ (dpb 0 vm::float-invalid-op-2-byte
+ (dpb 0 vm:float-invalid-op-1-byte #xffffffff)))
+ #xffffffff))
+ (orig-modes (gensym)))
+ `(let ((,orig-modes (floating-point-modes)))
+ (unwind-protect
+ (progn
+ (setf (floating-point-modes)
+ (,',logical-op ,orig-modes ,(logand trap-mask exception-mask)))
+ ,@body)
+ ;; Restore the original traps and exceptions.
+ (setf (floating-point-modes)
+ (logior (logand ,orig-modes ,(logior traps exceptions))
+ (logand (floating-point-modes)
+ ,(logand trap-mask exception-mask)
+ #+ppc
+ ,invalid-mask
+ #+mips ,(dpb 0 float-exceptions-byte #xffffffff))))))))))
+ ;; Masked and Enabled only differ whether we AND in the bits or OR
+ ;; them.
+ (with-float-traps masked logand)
+ (with-float-traps enabled logorc2))
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/commit/5721ddd2c71849c61c25bad61…
Raymond Toy pushed to branch rtoy-setexception-inexact at cmucl / cmucl
Commits:
97bd0eaa by Raymond Toy at 2015-12-24T10:37:57Z
Add WITH-FLOAT-TRAPS-ENABLED to enable specific traps.
This works like WITH-FLOAT-TRAPS-MASKED, except that the specified
traps are enabled.
Use this in fdlibm to enable the inexact trap.
- - - - -
2 changed files:
- src/code/exports.lisp
- src/code/float-trap.lisp
Changes:
=====================================
src/code/exports.lisp
=====================================
--- a/src/code/exports.lisp
+++ b/src/code/exports.lisp
@@ -1583,7 +1583,8 @@
"FLOAT-DENORMALIZED-P" "FLOAT-INFINITY-P"
"FLOAT-NAN-P" "FLOAT-TRAPPING-NAN-P"
"FLOAT-SIGNALING-NAN-P"
- "WITH-FLOAT-TRAPS-MASKED")
+ "WITH-FLOAT-TRAPS-MASKED"
+ "WITH-FLOAT-TRAPS-ENABLED")
;; More float extensions
#+double-double
(:export "LEAST-POSITIVE-NORMALIZED-DOUBLE-DOUBLE-FLOAT"
=====================================
src/code/float-trap.lisp
=====================================
--- a/src/code/float-trap.lisp
+++ b/src/code/float-trap.lisp
@@ -23,7 +23,8 @@
)
(in-package "EXTENSIONS")
(export '(set-floating-point-modes get-floating-point-modes
- with-float-traps-masked))
+ with-float-traps-masked
+ with-float-traps-enabled))
(in-package "VM")
(eval-when (compile load eval)
@@ -406,3 +407,44 @@
#+ppc
,invalid-mask
#+mips ,(dpb 0 float-exceptions-byte #xffffffff))))))))
+
+(defmacro with-float-traps-enabled (traps &body body)
+ "Execute BODY with the floating point exceptions listed in TRAPS
+ enabled. TRAPS should be a list of possible exceptions which
+ includes :UNDERFLOW, :OVERFLOW, :INEXACT, :INVALID and
+ :DIVIDE-BY-ZERO and on the X86 :DENORMALIZED-OPERAND. The respective
+ accrued exceptions are cleared at the start of the body to support
+ their testing within, and restored on exit."
+ (let ((traps (dpb (float-trap-mask traps) float-traps-byte 0))
+ (exceptions (dpb (float-trap-mask traps) float-sticky-bits 0))
+ (trap-mask (dpb (lognot (float-trap-mask traps))
+ float-traps-byte #xffffffff))
+ (exception-mask (dpb (lognot (vm::float-trap-mask traps))
+ float-sticky-bits #xffffffff))
+ ;; On ppc if we are masking the invalid trap, we need to make
+ ;; sure we wipe out the various individual sticky bits
+ ;; representing the invalid operation. Otherwise, if we
+ ;; enable the invalid trap later, these sticky bits will cause
+ ;; an exception.
+ #+ppc
+ (invalid-mask (if (member :invalid traps)
+ (dpb 0
+ (byte 1 31)
+ (dpb 0 vm::float-invalid-op-2-byte
+ (dpb 0 vm:float-invalid-op-1-byte #xffffffff)))
+ #xffffffff))
+ (orig-modes (gensym)))
+ `(let ((,orig-modes (floating-point-modes)))
+ (unwind-protect
+ (progn
+ (setf (floating-point-modes)
+ (logorc2 ,orig-modes ,(logand trap-mask exception-mask)))
+ ,@body)
+ ;; Restore the original traps and exceptions.
+ (setf (floating-point-modes)
+ (logior (logand ,orig-modes ,(logior traps exceptions))
+ (logand (floating-point-modes)
+ ,(logand trap-mask exception-mask)
+ #+ppc
+ ,invalid-mask
+ #+mips ,(dpb 0 float-exceptions-byte #xffffffff))))))))
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/commit/97bd0eaa99f355568b4d58886…