- For MIPS/HPPA, the NaN signalling bit's meaning is inverted.
- Implement FLOATING-POINT-MODES and SET-FLOATING-POINT-MODES in C.
- Delete the corresponding VOPs.
- Document the MIPS special "unimplemented" floating point trap.
- Add handling of the floating point control word in C signal handlers.
- Mark NAN-COMPARISIONS as expected failure on MIPS. (It still doesn't
work due to a kernel bug, siginfo_t's si_code field doesn't get
updated properly.)
;;; interpreter stubs for floating point modes get/setters for the
;;; alpha have been removed to alpha-vm.lisp, as they are implemented
;;; in C rather than as VOPs.
-#!-(or alpha x86-64)
+#!-(or alpha x86-64 mips)
(progn
(defun floating-point-modes ()
(floating-point-modes))
(!define-float-dispatching-function float-nan-p
"Return true if the float X is a NaN (Not a Number)."
+ #!-(or mips hppa)
(not (zerop (ldb sb!vm:single-float-significand-byte bits)))
+ #!+(or mips hppa)
+ (zerop (logand (ldb sb!vm:single-float-significand-byte bits)
+ sb!vm:single-float-trapping-nan-bit))
+ #!-(or mips hppa)
(or (not (zerop (ldb sb!vm:double-float-significand-byte hi)))
(not (zerop lo)))
+ #!+(or mips hppa)
+ (zerop (logand (ldb sb!vm:double-float-significand-byte hi)
+ sb!vm:double-float-trapping-nan-bit))
#!+(and long-float x86)
(or (not (zerop (ldb sb!vm:long-float-significand-byte hi)))
(not (zerop lo))))
(!define-float-dispatching-function float-trapping-nan-p
"Return true if the float X is a trapping NaN (Not a Number)."
+ #!-(or mips hppa)
(zerop (logand (ldb sb!vm:single-float-significand-byte bits)
sb!vm:single-float-trapping-nan-bit))
+ #!+(or mips hppa)
+ (not (zerop (ldb sb!vm:single-float-significand-byte bits)))
+ #!-(or mips hppa)
(zerop (logand (ldb sb!vm:double-float-significand-byte hi)
sb!vm:double-float-trapping-nan-bit))
+ #!+(or mips hppa)
+ (or (not (zerop (ldb sb!vm:double-float-significand-byte hi)))
+ (not (zerop lo)))
#!+(and long-float x86)
(zerop (logand (ldb sb!vm:long-float-significand-byte hi)
sb!vm:long-float-trapping-nan-bit)))
(when (zerop (logior y-ihi y-lo))
(return-from real-expt (coerce 1d0 rtype)))
;; +-NaN return x+y
+ ;; FIXME: Hardcoded qNaN/sNaN values are not portable.
(when (or (> x-ihi #x7ff00000)
(and (= x-ihi #x7ff00000) (/= x-lo 0))
(> y-ihi #x7ff00000)
(declare (type (alien (* os-context-register-t)) addr))
(setf (deref addr) (coerce new format))))
+(define-alien-routine
+ ("arch_get_fp_control" floating-point-modes) unsigned-int)
+
+(define-alien-routine
+ ("arch_set_fp_control" %floating-point-modes-setter) void (fp unsigned-int))
+
+(defun (setf floating-point-modes) (val) (%floating-point-modes-setter val))
+
;;; Given a signal context, return the floating point modes word in
;;; the same format as returned by FLOATING-POINT-MODES.
(define-alien-routine ("os_context_fp_control" context-floating-point-modes)
(inst nop)))
\f
-;;;; Float mode hackery:
-
-;#|
-(sb!xc:deftype float-modes () '(unsigned-byte 32))
-(defknown floating-point-modes () float-modes (flushable))
-(defknown ((setf floating-point-modes)) (float-modes)
- float-modes)
-
-(define-vop (floating-point-modes)
- (:results (res :scs (unsigned-reg)))
- (:result-types unsigned-num)
- (:translate floating-point-modes)
- (:policy :fast-safe)
- (:generator 3
- (inst cfc1 res 31)
- (inst nop)))
-
-(define-vop (set-floating-point-modes)
- (:args (new :scs (unsigned-reg) :target res))
- (:results (res :scs (unsigned-reg)))
- (:arg-types unsigned-num)
- (:result-types unsigned-num)
- (:translate (setf floating-point-modes))
- (:policy :fast-safe)
- (:generator 3
- (inst ctc1 new 31)
- (move res new)))
-;|#
-\f
;;;; Complex float VOPs
(define-vop (make-complex-single-float)
(def!constant float-overflow-trap-bit (ash 1 2))
(def!constant float-divide-by-zero-trap-bit (ash 1 3))
(def!constant float-invalid-trap-bit (ash 1 4))
+(def!constant float-unimplemented-trap-bit (ash 1 5))
(def!constant float-round-to-nearest 0)
(def!constant float-round-to-zero 1)
(defconstant-eqx float-rounding-mode (byte 2 0) #'equalp)
(defconstant-eqx float-sticky-bits (byte 5 2) #'equalp)
(defconstant-eqx float-traps-byte (byte 5 7) #'equalp)
-(defconstant-eqx float-exceptions-byte (byte 5 12) #'equalp)
+(defconstant-eqx float-exceptions-byte (byte 6 12) #'equalp)
(defconstant-eqx float-condition-bit (ash 1 23) #'equalp)
(def!constant float-fast-bit (ash 1 24))
{
os_context_t *context = arch_os_get_context(&void_context);
unsigned int code = (os_context_insn(context) >> 6) & 0xfffff;
+#ifdef LISP_FEATURE_LINUX
+ os_restore_fp_control(context);
+#endif
/* FIXME: This magic number is pseudo-atomic-trap from parms.lisp.
* Genesis should provide the proper #define, but it specialcases
* pseudo-atomic-trap to work around some oddity on SPARC.
unsigned int op, rs, rt, rd, funct, dest = 32;
int immed;
int result;
+#ifdef LISP_FEATURE_LINUX
+ os_restore_fp_control(context);
+#endif
op = (bad_inst >> 26) & 0x3f;
rs = (bad_inst >> 21) & 0x1f;
arch_skip_instruction(context);
}
+unsigned int
+arch_get_fp_control(void)
+{
+ register unsigned int ret asm("$2");
+
+ __asm__ __volatile__ ("cfc1 %0, $31" : "=r" (ret));
+
+ return ret;
+}
+
+void
+arch_set_fp_control(unsigned int fp)
+{
+ __asm__ __volatile__ ("ctc1 %0, $31" :: "r" (fp));
+}
+
void
arch_install_interrupt_handlers(void)
{
#endif
}
+unsigned int arch_get_fp_control(void);
+void arch_set_fp_control(unsigned int fp);
+
#endif /* _MIPS_ARCH_H */
unsigned int
os_context_fp_control(os_context_t *context)
{
- /* FIXME: Probably do something. */
- return 0;
+ mcontext_t *mctx = &context->uc_mcontext;
+ struct sigcontext *ctx = (struct sigcontext *)mctx;
+ return ctx->sc_fpc_csr;
}
void
os_restore_fp_control(os_context_t *context)
{
- /* FIXME: Probably do something. */
+ unsigned int ctl = os_context_fp_control(context);
+ ctl &= ~(FLOAT_STICKY_BITS_MASK | FLOAT_EXCEPTIONS_BYTE_MASK);
+ arch_set_fp_control(ctl);
}
unsigned int
(with-test (:name :nan-comparisons
- :fails-on (or :x86-64 :sparc))
+ :fails-on (or :x86-64 :sparc :mips))
(sb-int:with-float-traps-masked (:invalid)
(macrolet ((test (form)
(let ((nform (subst '(/ 0.0 0.0) 'nan form)))
;;; 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".)
-"1.0.8.35"
+"1.0.8.36"