Raymond Toy pushed to branch issue-355-solaris-x86-fp-trap-handler at cmucl / cmucl
Commits: a1a6bf10 by Raymond Toy at 2024-08-29T06:18:10-07:00 Ignore errors when setting the modes and more cleanups
When resetting the mode bits ignore any errors that might happen if some traps are still enabled. Also, only update the exception part of the mode bits.
Document what FPE_FLTSUB means. Make a note that the fpe code info alist only contains the relevant info for FP traps that we're interested in handling.
With this change, an overflow and underflow are signaled as expected and when we restart, we don't get signaled again. But according to the debugging prints, we do enter the sigfpe handler twice. Divide by zero is not handled correctly, though.
More testing needed.
- - - - - 46e1190c by Raymond Toy at 2024-08-29T06:48:03-07:00 Refactor cleanup of handler a bit
Make debugging prints line up neatly. Add vars to hold the new modes so there's less duplication in debugging prints.
Remove old code about clearing out the traps which we've replaced.
- - - - -
1 changed file:
- src/code/float-trap.lisp
Changes:
===================================== src/code/float-trap.lisp ===================================== @@ -450,11 +450,15 @@ "Signal code for FP inexact result") (defconstant +fpe-fltinv+ 7 "Signal code for FP invalid operation") - ;; Not sure what this means. + ;; On FreeBSD (and maybe other OSes), this happens when the x86 + ;; BOUND instruction detects an index out of bounds. Linux + ;; apparently generates a SIGSEGV instead. See + ;; https://stackoverflow.com/questions/27051428/what-is-a-fpe-fltsub-subscript-... (defconstant +fpe-fltsub+ 8 "Signal code for subscript out of range") (defconstant +fpe-fltden+ 9 "Signal code for FP denormalize") + ;; We only include the values that FP operations can trap on. (defconstant +fpe-code-info-alist+ (list (cons +fpe-fltdiv+ (list 'division-by-zero float-divide-by-zero-trap-bit )) @@ -489,50 +493,39 @@ ;; This means we need to restore the fpu state ourselves. (unwind-protect (let ((fpe-info (second (assoc code +fpe-code-info-alist+)))) + (format t "fpe code = ~D~%" code) (if fpe-info (error fpe-info :operation fop :operands operands) (error _"SIGFPE code ~D not handled" code))) ;; Cleanup + ;; + ;; Clear out the status for any enabled traps. If we don't + ;; then when we return, the exception gets signaled again. (let* ((trap-bit (third (assoc code +fpe-code-info-alist+))) - (new-x87-modes (vm::x87-floating-point-modes)) - (new-sse2-modes (vm::sse2-floating-point-modes))) + (current-x87-modes (vm::x87-floating-point-modes)) + (current-sse2-modes (vm::sse2-floating-point-modes)) + (new-x87-modes + (dpb (logandc2 (ldb float-exceptions-byte current-sse2-modes) + trap-bit) + float-exceptions-byte current-sse2-modes)) + (new-sse2-modes + (dpb (logandc2 (ldb float-exceptions-byte current-x87-modes) + trap-bit) + float-exceptions-byte current-x87-modes))) (format t "Trap bit: ~D~%" trap-bit) - (format t "Current modes: ~16,'0b~%" (vm::floating-point-modes)) - (format t "Current x87 modes: ~16,'0b~%" new-x87-modes) - (format t "Current sse2 modes: ~16,'0b~%" new-sse2-modes) - (format t "Setting sse2 modes to: ~16,'0b~%" - (logandc2 (ldb float-exceptions-byte new-sse2-modes) - trap-bit)) - (setf (vm::sse2-floating-point-modes) - (logandc2 (ldb float-exceptions-byte new-sse2-modes) - trap-bit)) - (format t "Setting x87 modes to: ~16,'0b~%" - (logandc2 (ldb float-exceptions-byte new-x87-modes) - trap-bit)) - (setf (vm::x87-floating-point-modes) - (logandc2 (ldb float-exceptions-byte new-x87-modes) - trap-bit)) - - (format t "new x87 modes: ~16,'0b~%" (vm::x87-floating-point-modes)) - (format t "new sse2 modes: ~16,'0b~%" (vm::sse2-floating-point-modes)) - #+nil - (progn - ;; Clear out the status for any enabled traps. With SSE2, if - ;; the current exception is enabled, the next FP instruction - ;; will cause the exception to be signaled again. Hence, we - ;; need to clear out the exceptions that we are handling here. - (setf (ldb float-exceptions-byte new-modes) new-exceptions) - ;;#+nil - (progn - (format *debug-io* "sigcontext modes: #x~4x (~A)~%" - modes (decode-floating-point-modes modes)) - (format *debug-io* "current modes: #x~4x (~A)~%" - (vm:floating-point-modes) (get-floating-point-modes)) - (format *debug-io* "new modes: #x~x (~A)~%" - new-modes (decode-floating-point-modes new-modes))) - (setf (vm:floating-point-modes) new-modes))))))) + (format t "Current modes: ~32,'0b~%" (vm::floating-point-modes)) + (format t "Current x87 modes: ~32,'0b~%" current-x87-modes) + (format t "Current sse2 modes: ~32,'0b~%" current-sse2-modes) + (format t "Setting sse2 modes to: ~32,'0b~%" new-x87-modes) + (format t "Setting x87 modes to: ~32,'0b~%" new-sse2-modes) + (ignore-errors + (setf (vm::sse2-floating-point-modes) new-sse2-modes) + (setf (vm::x87-floating-point-modes) new-x87-modes)) + + (format t "new x87 modes: ~32,'0b~%" (vm::x87-floating-point-modes)) + (format t "new sse2 modes: ~32,'0b~%" (vm::sse2-floating-point-modes)))))))
(macrolet ((with-float-traps (name merge-traps docstring)
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/649d84d625d2d673d63685f...