* De-cripple SB-INT:SET-FLOATING-POINT-MODES for this platform.
* Enable restoring the FPU control word during interrupt handling
on this platform (RESTORE_FP_CONTROL_FROM_CONTEXT).
* Implement restoring the FPU control word on this platform
(os_restore_fp_control).
* Update :FAILS-ON information for the now-passing tests.
* Insert an addtional copy of test float.pure.lisp /
(ADDITION-OVERFLOW BUG-372) to detect failure to restore the FPU
control word in signal handling, with appropriate commentary.
GETF, LOGBITP, LDB, and MASK-FIELD now arrange for non-primary values
of multiple-valued places to be set to NIL, instead of signalling an
error (per a careful reading of CLHS 5.1.2.3).
+ * bug fix: floating-point traps now work on darwin/x86-64.
changes in sbcl-1.0.52 relative to sbcl-1.0.51:
* enhancement: ASDF has been updated to version 2.017.
(or (cdr (assoc precision *precision-mode-alist*))
(error "unknown precision mode: ~S" precision))))
;; FIXME: This apparently doesn't work on Darwin
- #!-darwin (setf (floating-point-modes) modes))
+ #!-(and darwin (or ppc x86))
+ (setf (floating-point-modes) modes))
(values))
(defun get-floating-point-modes ()
#define es __es
#define fs __fs
+#define fpu_fcw __fpu_fcw
+#define fpu_mxcsr __fpu_mxcsr
+
#else
typedef struct ucontext darwin_ucontext;
return ret;
}
+void
+os_restore_fp_control(os_context_t *context)
+{
+ /* KLUDGE: The x87 FPU control word is some nasty bitfield struct
+ * thing. Rather than deal with that, just grab it as a 16-bit
+ * integer. */
+ unsigned short fpu_control_word =
+ *((unsigned short *)&context->uc_mcontext->fs.fpu_fcw);
+ /* reset exception flags and restore control flags on SSE2 FPU */
+ unsigned int temp = (context->uc_mcontext->fs.fpu_mxcsr) & ~0x3F;
+ asm ("ldmxcsr %0" : : "m" (temp));
+ /* same for x87 FPU. */
+ asm ("fldcw %0" : : "m" (fpu_control_word));
+}
+
#endif
#define CONTEXT_ADDR_FROM_STEM(stem) &context->uc_mcontext->ss.stem
#endif /* __DARWIN_UNIX03 */
+#define RESTORE_FP_CONTROL_FROM_CONTEXT
+void os_restore_fp_control(os_context_t *context);
+
#endif /* _X86_64_DARWIN_OS_H */
(assert (= 0.0d0 (scale-float 1.0d0 (1- most-negative-fixnum))))
(with-test (:name (:scale-float-overflow :bug-372)
- :fails-on :darwin) ;; bug 372
+ :fails-on '(and :darwin (or :ppc :x86))) ;; bug 372
(progn
(assert (raises-error? (scale-float 1.0 most-positive-fixnum)
floating-point-overflow))
(funcall (compile nil '(lambda () (tan (tan (round 0))))))
(with-test (:name (:addition-overflow :bug-372)
- :fails-on '(or (and :ppc :openbsd) :darwin (and :x86 :netbsd)))
+ :fails-on '(or (and :ppc :openbsd)
+ (and (or :ppc :x86) :darwin)
+ (and :x86 :netbsd)))
+ (assert (typep (nth-value
+ 1
+ (ignore-errors
+ (sb-sys:without-interrupts
+ (sb-int:set-floating-point-modes :current-exceptions nil
+ :accrued-exceptions nil)
+ (loop repeat 2 summing most-positive-double-float)
+ (sleep 2))))
+ 'floating-point-overflow)))
+
+;; This is the same test as above. Even if the above copy passes,
+;; this copy will fail if SIGFPE handling ends up clearing the FPU
+;; control word, which can happen if the kernel clears the FPU control
+;; (a reasonable thing for it to do) and the runtime fails to
+;; compensate for this (see RESTORE_FP_CONTROL_WORD in interrupt.c).
+(with-test (:name (:addition-overflow :bug-372 :take-2)
+ :fails-on '(or (and :ppc :openbsd)
+ (and (or :ppc :x86) :darwin)
+ (and :x86 :netbsd)))
(assert (typep (nth-value
1
(ignore-errors