Raymond Toy pushed to branch issue-355-solaris-x86-fp-trap-handler at cmucl / cmucl
Commits: 4f48c6cb by Raymond Toy at 2024-08-29T07:36:36-07:00 Use os_set_sigcontext_fpu_modes to reset modes
x86-vm.lisp defines `(setf sigcontext-floating-point-modes)` to set the modes in the sigcontext. Use this in `sigfpe-handler` to reset trap bit for the exception that was signaled.
However, there's no implementation of `os_set_sigcontext_fpu_modes`, so implement one in solaris-os.c.
Works somewhat better than before in that we don't resignal the exception again when we restart. But still have problems with divide by zero and invalid. And we're left in a weird FP trap state where we can't read 1d300 anymore---an overflow?
- - - - -
2 changed files:
- src/code/float-trap.lisp - src/lisp/solaris-os.c
Changes:
===================================== src/code/float-trap.lisp ===================================== @@ -481,6 +481,7 @@ (type system-area-pointer scp)) (let* ((modes (sigcontext-floating-point-modes (alien:sap-alien scp (* unix:sigcontext))))) + (format t "Current modes: ~32,'0b~%" modes) (multiple-value-bind (fop operands) (let ((sym (find-symbol "GET-FP-OPERANDS" "VM"))) (if (fboundp sym) @@ -503,6 +504,7 @@ ;; ;; Clear out the status for any enabled traps. If we don't ;; then when we return, the exception gets signaled again. + #+nil (let* ((trap-bit (third (assoc code +fpe-code-info-alist+))) (current-x87-modes (vm::x87-floating-point-modes)) (current-sse2-modes (vm::sse2-floating-point-modes)) @@ -525,7 +527,16 @@ (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))))))) + (format t "new sse2 modes: ~32,'0b~%" (vm::sse2-floating-point-modes))) + (let* ((trap-bit (third (assoc code +fpe-code-info-alist+))) + (new-modes + (dpb (logandc2 (ldb float-exceptions-byte modes) + trap-bit) + float-exceptions-byte modes))) + (format t "New modes: ~32,'0b~%" new-modes) + (setf (sigcontext-floating-point-modes) + (alien:sap-alien scp (* unix:sigcontext)) + new-modes))))))
(macrolet ((with-float-traps (name merge-traps docstring)
===================================== src/lisp/solaris-os.c ===================================== @@ -637,6 +637,45 @@ os_sigcontext_fpu_modes(ucontext_t *scp) return modes; }
+unsigned int +os_set_sigcontext_fpu_modes(ucontext_t *scp, uint32_t modes) +{ + unsigned short cw, sw; + fpregset_t *fpr; + unsigned int state; + + fpr = &scp->uc_mcontext.fpregs; + + cw = modes & 0x3f; + sw = (modes >> 7) &0x3f; + + DPRINTF(1, (stderr, "modes = 0x%08x\n", modes)); + DPRINTF(1, (stderr, "cw = 0x%04x\n", cw)); + DPRINTF(1, (stderr, "sw = 0x%04x\n", sw)); + + fpr->fp_reg_set.fpchip_state.state[0] = cw; + fpr->fp_reg_set.fpchip_state.state[1] = sw; + +#ifdef FEATURE_SSE2 + /* + * Add in the SSE2 part, if we're running the sse2 core. + */ + if (fpu_mode == SSE2) { + unsigned long mxcsr = modes & 0xffff; + + DPRINTF(1, (stderr, "SSE2 modes = %08lx\n", mxcsr)); + fpr->fp_reg_set.fpchip_state.mxcsr = mxcsr; + + modes |= mxcsr; + } +#endif + + modes ^= (0x3f << 7); + return modes; +} + + + boolean os_support_sse2() {
View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/commit/4f48c6cb2fb01b3613c16d57...