[Git][cmucl/cmucl][issue-425-correctly-rounded-math-functions] 18 commits: Fix #424: Use fdlibm hypot

Raymond Toy pushed to branch issue-425-correctly-rounded-math-functions at cmucl / cmucl Commits: 4660c011 by Raymond Toy at 2025-08-14T07:40:17-07:00 Fix #424: Use fdlibm hypot - - - - - 6a2028c5 by Raymond Toy at 2025-08-14T07:40:17-07:00 Merge branch 'issue-424-fix-hypot' into 'master' Fix #424: Use fdlibm hypot Closes #424 See merge request cmucl/cmucl!311 - - - - - cb874f7f by Raymond Toy at 2025-08-14T07:42:48-07:00 Update release notes for #424 - - - - - d2c96f1b by Raymond Toy at 2025-08-14T07:45:18-07:00 Fix #426: Define float-modes type correctly - - - - - 2db294b1 by Raymond Toy at 2025-08-14T07:45:18-07:00 Merge branch 'issue-426-fix-float-modes-type-def' into 'master' Fix #426: Define float-modes type correctly Closes #426 See merge request cmucl/cmucl!313 - - - - - eb98570f by Raymond Toy at 2025-08-14T07:55:12-07:00 Update release notes for #426 [skip-ci] - - - - - 65050c00 by Raymond Toy at 2025-08-18T18:37:51-07:00 Merge branch 'master' into issue-425-correctly-rounded-math-functions - - - - - cd2edae5 by Raymond Toy at 2025-08-19T14:16:31-07:00 Fix #432: Don't pass -M option to make-extra-dist.sh - - - - - c65554a5 by Raymond Toy at 2025-08-19T14:16:31-07:00 Merge branch 'issue-432-fix-man-option-for-make-extra-dist' into 'master' Fix #432: Don't pass -M option to make-extra-dist.sh Closes #432 See merge request cmucl/cmucl!315 - - - - - 633e64a4 by Raymond Toy at 2025-09-05T07:55:14-07:00 Fix #431: Fix setting of x87 modes in set-floating-point-modes - - - - - 7ab74e13 by Raymond Toy at 2025-09-05T07:55:15-07:00 Merge branch 'issue-431-fix-set-floating-point-modes' into 'master' Fix #431: Fix setting of x87 modes in set-floating-point-modes Closes #431 See merge request cmucl/cmucl!314 - - - - - 62235089 by Raymond Toy at 2025-09-12T08:51:26-07:00 Update release notes Forgot to include #432 [skip-ci] - - - - - 61592012 by Raymond Toy at 2025-09-16T17:50:14-07:00 Fix #381: cmucl-unix.pot depends on OS - - - - - 4dd79bc9 by Raymond Toy at 2025-09-16T17:50:15-07:00 Merge branch 'issue-381-cmucl-unix-depends-on-os' into 'master' Fix #381: cmucl-unix.pot depends on OS Closes #381 See merge request cmucl/cmucl!319 - - - - - 69a8a4b6 by Raymond Toy at 2025-09-16T19:43:12-07:00 Update release notes Forgot to add #381 [skip-ci] - - - - - fb29eb6e by Raymond Toy at 2025-09-17T08:32:41-07:00 Fix #440: Update CI to use snapshot 2025-09 - - - - - d537a8a3 by Raymond Toy at 2025-09-17T08:32:41-07:00 Merge branch 'issue-440-ci-use-snapshot-2025-09' into 'master' Fix #440: Update CI to use snapshot 2025-09 Closes #440 See merge request cmucl/cmucl!320 - - - - - 131d10d8 by Raymond Toy at 2025-09-17T12:13:35-07:00 Merge branch 'master' into issue-425-correctly-rounded-math-functions - - - - - 16 changed files: - .gitlab-ci.yml - bin/make-dist.sh - + src/bootfiles/21e/boot-2025-07.lisp - src/code/float-trap.lisp - src/code/irrat.lisp - src/code/unix.lisp - src/code/x86-vm.lisp - src/compiler/x86/float-sse2.lisp - src/compiler/x86/parms.lisp - src/general-info/release-21f.md - src/i18n/locale/cmucl-x86-vm.pot - src/lisp/GNUmakefile - + src/lisp/e_hypot.c - + tests/float-x86.lisp - tests/float.lisp - tests/irrat.lisp Changes: ===================================== .gitlab-ci.yml ===================================== @@ -1,6 +1,6 @@ variables: year: "2025" - month: "07" + month: "09" download_url: "https://common-lisp.net/project/cmucl/downloads/snapshots/$year/$month" version: "$year-$month-x86" tar_ext: "xz" ===================================== bin/make-dist.sh ===================================== @@ -189,7 +189,7 @@ GTAR_OPTS="-t ${GTAR:-tar}" EXTRA_OPTS="${GROUP:+ -G ${GROUP}} ${OWNER:+ -O ${OWNER}}" INSTALL_OPTS="${INSTALL_DIR:+ -I ${INSTALL_DIR}}" MANDIR="${MANDIR:+ -M ${MANDIR}}" -OPTIONS="${GTAR_OPTS} ${EXTRA_OPTS} ${INSTALL_OPTS} ${MANDIR}" +OPTIONS="${GTAR_OPTS} ${EXTRA_OPTS} ${INSTALL_OPTS}" set -x echo Creating distribution for $ARCH $OS ===================================== src/bootfiles/21e/boot-2025-07.lisp ===================================== @@ -0,0 +1,25 @@ +;; Bootstrap file to define some constants we use early in the build. + +(in-package :x86) + +(defconstant x87-float-infinity-control-byte + (byte 1 (+ 12 16)) + "The bit in the x87 FPU control word that controls the infinity mode.") +(defconstant x87-float-rounding-mode + (byte 2 (+ 10 16)) + "The bits in the x87 FPU control word for the rounding mode.") +(defconstant x87-float-precision-control-byte + (byte 2 (+ 8 16)) + "The bits in the x87 FPU contol word for the FP operation precision.") +(defconstant x87-float-traps-byte + (byte 6 16) + "The bits in the x87 FPU control word indicating the exceptions that + are enabled.") +(defconstant x87-float-precision-control-alist + `((:24-bits . 0) + (:reserved . 1) + (:53-bits . 2) + (:64-bits . 3)) + "Alist for the x87 precison control. The car is the symbolic + precision and the cdr is the value for the precision control field.") + ===================================== src/code/float-trap.lisp ===================================== @@ -114,21 +114,24 @@ ;; Set the floating point modes for both X87 and SSE2. This ;; include the rounding control bits. (let* ((rc (ldb float-rounding-mode new-mode)) - (new-exceptions (logand #x3f new-mode)) - (new-enables (logand #x3f (ash new-mode -7))) - (x87-modes - (logior new-exceptions - (ash rc 10) - (ash new-enables 16) - ;; Set precision control to be 64-bit, always. We - ;; don't use the x87 registers with sse2, so this - ;; is ok and would be the correct setting if we - ;; ever support long-floats. - (ash 3 (+ 8 16))))) - (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) - ) + (new-exceptions (ldb float-exceptions-byte new-mode)) + (new-enables (ldb float-traps-byte new-mode)) + (x87-modes 0)) + ;; From the new mode, update the x87 FPU mode with the same set + ;; of accrued exceptions, enabled exceptions, and rounding mode. + (setf x87-modes (dpb new-exceptions float-exceptions-byte x87-modes)) + (setf x87-modes (dpb new-enables x87-float-traps-byte x87-modes)) + (setf x87-modes (dpb rc x87-float-rounding-mode x87-modes)) + + ;; Set precision to 64-bits (double-extended). + (setf x87-modes + (dpb (cdr (assoc :64-bits x87-float-precision-control-alist)) + x87-float-precision-control-byte + x87-modes)) + + (setf (vm::sse2-floating-point-modes) (ldb (byte 16 0) new-mode)) + (setf (vm::x87-floating-point-modes) (ldb (byte 30 0) x87-modes))) + new-mode)) #+(and sse2 darwin) (progn ===================================== src/code/irrat.lisp ===================================== @@ -121,7 +121,7 @@ (def-math-rtn ("__ieee754_pow" %pow) 2) #-(or x86 sparc-v7 sparc-v8 sparc-v9) (def-math-rtn "sqrt" 1) -(def-math-rtn "hypot" 2) +(def-math-rtn ("__ieee754_hypot" %hypot) 2) (def-math-rtn ("fdlibm_log1p" %log1p) 1) (def-math-rtn ("fdlibm_expm1" %expm1) 1) ===================================== src/code/unix.lisp ===================================== @@ -2166,7 +2166,7 @@ #+linux (defun unix-getpwuid (uid) - "Return a USER-INFO structure for the user identified by UID. If + _N"Return a USER-INFO structure for the user identified by UID. If not found, NIL is returned with a second value indicating the cause of the failure. In particular, if the second value is 0 (or ENONENT, ESRCH, EBADF, etc.), then the uid was not found." ===================================== src/code/x86-vm.lisp ===================================== @@ -733,3 +733,88 @@ (multiple-value-bind (fop dst src) (get-fp-operation scp) (values fop (list dst src)))) + +;; See src/compiler/x86/float-sse2.lisp for a description of the x87 +;; control and status words. + +(defconstant x87-float-infinity-control-byte + (byte 1 (+ 12 16)) + "The bit in the x87 FPU control word that controls the infinity mode.") + +(defconstant x87-float-rounding-mode + (byte 2 (+ 10 16)) + "The bits in the x87 FPU control word for the rounding mode.") + +(defconstant x87-float-precision-control-byte + (byte 2 (+ 8 16)) + "The bits in the x87 FPU contol word for the FP operation precision.") + +(defconstant x87-float-traps-byte + (byte 6 16) + "The bits in the x87 FPU control word indicating the exceptions that + are enabled.") + +(defconstant x87-float-precision-control-alist + `((:24-bits . 0) + (:reserved . 1) + (:53-bits . 2) + (:64-bits . 3)) + "Alist for the x87 precison control. The car is the symbolic + precision and the cdr is the value for the precision control field.") + +(defun print-fp-exceptions-enabled (enabled) + (format t "Precision enable: ~30T~A~%" (ldb (byte 1 5) enabled)) + (format t "Underflow enable: ~30T~A~%" (ldb (byte 1 4) enabled)) + (format t "Overflow enable: ~30T~A~%" (ldb (byte 1 3) enabled)) + (format t "Divide-by-zero enable: ~30T~A~%" (ldb (byte 1 2) enabled)) + (format t "Denormal op enable: ~30T~A~%" (ldb (byte 1 1) enabled)) + (format t "Invalid op enable: ~30T~A~%" (ldb (byte 1 0) enabled))) + +(defun print-fp-current-exceptions (current) + (format t "Precision flag: ~30T~A~%" (ldb (byte 1 5) current)) + (format t "Underflow flag: ~30T~A~%" (ldb (byte 1 4) current)) + (format t "Overflow flag: ~30T~A~%" (ldb (byte 1 3) current)) + (format t "Divide-by-zero flag: ~30T~A~%" (ldb (byte 1 2) current)) + (format t "Denormal op flag: ~30T~A~%" (ldb (byte 1 1) current)) + (format t "Invalid op flag: ~30T~A~%" (ldb (byte 1 0) current))) + +(defun print-sse2-fp-modes (&optional (sse-mode (sse2-floating-point-modes))) + "Print SSE2 floating modes word in a human-readable fashion." + ;; Note that Intel uses masks to disable the exception, but to match + ;; the rest of cmucl, these bits are represented as enable bits. + (format t "Flush-to-zero: ~30T~A~%" (ldb (byte 1 15) sse-mode)) + (let ((rc (ldb float-rounding-mode sse-mode))) + (format t "Rounding control: ~30T#b~2,'0b ~S~%" + rc + (car (rassoc rc rounding-mode-alist)))) + (print-fp-exceptions-enabled (ldb float-traps-byte sse-mode)) + (print-fp-current-exceptions (ldb float-exceptions-byte sse-mode))) + +(defun print-x87-fp-modes (&optional (x87-mode (x87-floating-point-modes))) + "Print X87 floating modes word in a human-readable fashion." + ;; Note that Intel uses masks to disable the exception, but to match + ;; the rest of cmucl, these bits are represented as enable bits. + (format t "Status word:~%") + (format t "FPU busy: ~30T~A~%" (ldb (byte 1 15) x87-mode)) + (format t "Condition code C3: ~30T~A~%" (ldb (byte 1 14) x87-mode)) + (format t "Top of stack: ~30T~D~%" (ldb (byte 3 11) x87-mode)) + (format t "Condition code C2: ~30T~A~%" (ldb (byte 1 10) x87-mode)) + (format t "Condition code C1: ~30T~A~%" (ldb (byte 1 9) x87-mode)) + (format t "Condition code C0: ~30T~A~%" (ldb (byte 1 8) x87-mode)) + (format t "Error summary: ~30T~A~%" (ldb (byte 1 7) x87-mode)) + (format t "Stack fault: ~30T~A~%" (ldb (byte 1 6) x87-mode)) + (print-fp-current-exceptions (ldb float-exceptions-byte x87-mode)) + (format t "~%Control word:~%") + (format t "Reserved: ~30T#b~2,'0b~%" (ldb (byte 2 (+ 13 16)) x87-mode)) + (format t "Infinity control: ~30T~A~%" (ldb x87-float-infinity-control-byte x87-mode)) + (let ((rc (ldb x87-float-rounding-mode x87-mode))) + (format t "Rounding control: ~30T#b~2,'0b ~S~%" + rc + (car (rassoc rc rounding-mode-alist)))) + (let ((pc (ldb x87-float-precision-control-byte x87-mode))) + (format t "Precision control: ~30T#b~2,'0b ~S~%" + pc + (car (rassoc pc x87-float-precision-control-alist)))) + (format t "Reserved: ~30T#b~2,'0b~%" (ldb (byte 2 (+ 6 16)) x87-mode)) + (print-fp-exceptions-enabled (ldb x87-float-traps-byte x87-mode))) + ===================================== src/compiler/x86/float-sse2.lisp ===================================== @@ -1288,6 +1288,10 @@ ;; 0 invalid operation flag ;; ;; See below for rounding control +;; +;; Also see float-rounding-mode, float-sticky-bits, float-traps-byte, +;; and float-exceptions-byte in compiler/x86/parms.lisp. + (defknown sse2-floating-point-modes () float-modes (flushable)) (defknown ((setf sse2-floating-point-modes)) (float-modes) float-modes) ===================================== src/compiler/x86/parms.lisp ===================================== @@ -205,9 +205,15 @@ ;; need to do it this way because the interface assumes the modes are ;; in the same order as the MXCSR register. (defconstant float-rounding-mode (byte 2 13)) -(defconstant float-sticky-bits (byte 6 0)) -(defconstant float-traps-byte (byte 6 7)) -(defconstant float-exceptions-byte (byte 6 0)) +(defconstant float-sticky-bits (byte 6 0) + "The bits in the FP mode that hold the accrued exceptions that have + occurred since the bits were reset.") +(defconstant float-traps-byte (byte 6 7) + "The bits in the FP mode that hold FP exceptions that are enabled.") +(defconstant float-exceptions-byte (byte 6 0) + "The bits in the FP mode that hold the current exception. However + for x86, there aren't separate bits for this, so we use the stick + bits from the accrued exceptions") (progn ;; SSE2 has a flush-to-zero flag, which we use as the fast bit. Some ===================================== src/general-info/release-21f.md ===================================== @@ -123,6 +123,7 @@ public domain. * #375 `unix-mkstemp` and `unix-mkdtemp` actually returns the file names now. * #379 Support GNU-style command-line option names + * #381 cmucl-unix.pot depends on OS * #382 Command-line options are case-sensitive * #385 Fixed compiler warning about `%p` in Linux-os.c * #386 Generate `def-unix-error` forms from OS-specific files. @@ -137,6 +138,10 @@ public domain. * #417 PCL complains about repeated aux variables in defmethod * #418 Update asdf to version 3.3.7.4 (for package-local-nicknames) + * #424 Use fdlibm `hypot` to fix bug in snapshot 2025-07 + * #426 Define float-modes type correctly for `(setf (x87-set-floating-point-modes))` + * #431 Fix setting of x87 FP modes in `set-floating-point-modes` + * #432 `make-dist.sh` passes `-M` to `make-extra-dist.sh` which doesn't accept `-M` option. * Other changes: * Improvements to the PCL implementation of CLOS: * Changes to building procedure: ===================================== src/i18n/locale/cmucl-x86-vm.pot ===================================== @@ -77,6 +77,38 @@ msgstr "" msgid "Thread safe push of val onto the list in the vector element." msgstr "" +#: src/code/x86-vm.lisp +msgid "The bit in the x87 FPU control word that controls the infinity mode." +msgstr "" + +#: src/code/x86-vm.lisp +msgid "The bits in the x87 FPU control word for the rounding mode." +msgstr "" + +#: src/code/x86-vm.lisp +msgid "The bits in the x87 FPU contol word for the FP operation precision." +msgstr "" + +#: src/code/x86-vm.lisp +msgid "" +"The bits in the x87 FPU control word indicating the exceptions that\n" +" are enabled." +msgstr "" + +#: src/code/x86-vm.lisp +msgid "" +"Alist for the x87 precison control. The car is the symbolic\n" +" precision and the cdr is the value for the precision control field." +msgstr "" + +#: src/code/x86-vm.lisp +msgid "Print SSE2 floating modes word in a human-readable fashion." +msgstr "" + +#: src/code/x86-vm.lisp +msgid "Print X87 floating modes word in a human-readable fashion." +msgstr "" + #: src/code/load.lisp msgid "Top-Level Form" msgstr "" @@ -136,6 +168,23 @@ msgstr "" msgid "Maximum number of bits in a positive fixnum" msgstr "" +#: src/compiler/x86/parms.lisp +msgid "" +"The bits in the FP mode that hold the accrued exceptions that have\n" +" occurred since the bits were reset." +msgstr "" + +#: src/compiler/x86/parms.lisp +msgid "The bits in the FP mode that hold FP exceptions that are enabled." +msgstr "" + +#: src/compiler/x86/parms.lisp +msgid "" +"The bits in the FP mode that hold the current exception. However\n" +" for x86, there aren't separate bits for this, so we use the stick\n" +" bits from the accrued exceptions" +msgstr "" + #: src/compiler/x86/vm.lisp msgid "Redefining SC number ~D from ~S to ~S." msgstr "" ===================================== src/lisp/GNUmakefile ===================================== @@ -28,6 +28,7 @@ FDLIBM = k_sin.c k_cos.c k_tan.c s_sin.c s_cos.c s_tan.c sincos.c \ e_rem_pio2.c k_rem_pio2.c \ e_log10.c s_scalbn.c \ setexception.c \ + e_hypot.c \ log2.c SRCS = lisp.c coreparse.c alloc.c monitor.c print.c interr.c \ ===================================== src/lisp/e_hypot.c ===================================== @@ -0,0 +1,144 @@ + +/* @(#)e_hypot.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_hypot(x,y) + * + * Method : + * If (assume round-to-nearest) z=x*x+y*y + * has error less than sqrt(2)/2 ulp, than + * sqrt(z) has error less than 1 ulp (exercise). + * + * So, compute sqrt(x*x+y*y) with some care as + * follows to get the error below 1 ulp: + * + * Assume x>y>0; + * (if possible, set rounding to round-to-nearest) + * 1. if x > 2y use + * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y + * where x1 = x with lower 32 bits cleared, x2 = x-x1; else + * 2. if x <= 2y use + * t1*y1+((x-y)*(x-y)+(t1*y2+t2*y)) + * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1, + * y1= y with lower 32 bits chopped, y2 = y-y1. + * + * NOTE: scaling may be necessary if some argument is too + * large or too tiny + * + * Special cases: + * hypot(x,y) is INF if x or y is +INF or -INF; else + * hypot(x,y) is NAN if x or y is NAN. + * + * Accuracy: + * hypot(x,y) returns sqrt(x^2+y^2) with error less + * than 1 ulps (units in the last place) + */ + +#include "fdlibm.h" + +static inline void +set_hiword(double* d, int hi) +{ + union { int i[2]; double d; } ux; + + ux.d = *d; + ux.i[HIWORD] = hi; + *d = ux.d; +} + +static inline int +get_loword(double d) +{ + union { int i[2]; double d; } ux; + ux.d = d; + return ux.i[LOWORD]; +} + +static inline int +get_hiword(double d) +{ + union { int i[2]; double d; } ux; + ux.d = d; + + return ux.i[HIWORD]; +} + + +#ifdef __STDC__ + double __ieee754_hypot(double x, double y) +#else + double __ieee754_hypot(x,y) + double x, y; +#endif +{ + double a=x,b=y,t1,t2,y1,y2,w; + int j,k,ha,hb; + + ha = get_hiword(x)&0x7fffffff; /* high word of x */ + hb = get_hiword(y)&0x7fffffff; /* high word of y */ + if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} + set_hiword(&a,ha); /* a <- |a| */ + set_hiword(&b, hb); /* b <- |b| */ + + if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */ + k=0; + if(ha > 0x5f300000) { /* a>2**500 */ + if(ha >= 0x7ff00000) { /* Inf or NaN */ + w = a+b; /* for sNaN */ + if(((ha&0xfffff)|get_loword(a))==0) w = a; + if(((hb^0x7ff00000)|get_loword(b))==0) w = b; + return w; + } + /* scale a and b by 2**-600 */ + ha -= 0x25800000; hb -= 0x25800000; k += 600; + set_hiword(&a, ha); + set_hiword(&b, hb); + } + if(hb < 0x20b00000) { /* b < 2**-500 */ + if(hb <= 0x000fffff) { /* subnormal b or 0 */ + if((hb|(get_loword(b)))==0) return a; + t1=0; + set_hiword(&t1, 0x7fd00000); /* t1=2^1022 */ + b *= t1; + a *= t1; + k -= 1022; + } else { /* scale a and b by 2^600 */ + ha += 0x25800000; /* a *= 2^600 */ + hb += 0x25800000; /* b *= 2^600 */ + k -= 600; + set_hiword(&a, ha); + set_hiword(&b, hb); + } + } + /* medium size a and b */ + w = a-b; + if (w>b) { + t1 = 0; + set_hiword(&t1, ha); + t2 = a-t1; + w = sqrt(t1*t1-(b*(-b)-t2*(a+t1))); + } else { + a = a+a; + y1 = 0; + set_hiword(&y1, hb); + y2 = b - y1; + t1 = 0; + set_hiword(&t1, ha+0x00100000); + t2 = a - t1; + w = sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b))); + } + if(k!=0) { + t1 = 1.0; + set_hiword(&t1, get_hiword(t1) + (k<<20)); + return t1*w; + } else return w; +} ===================================== tests/float-x86.lisp ===================================== @@ -0,0 +1,59 @@ +;; Tests of float functions + +(defpackage :float-x86-tests + (:use :cl :lisp-unit)) + +(in-package "FLOAT-X86-TESTS") + +(define-test set-floating-point-modes + (let ((old-x87-modes (x86::x87-floating-point-modes)) + (old-sse2-modes (x86::sse2-floating-point-modes)) + x87-modes sse2-modes) + (unwind-protect + (progn + ;; Set some new traps and rounding mode. + (ext:set-floating-point-modes :traps '(:underflow + :overflow + :invalid + :divide-by-zero) + :rounding-mode :zero) + ;; Save these new FP modes + (setf x87-modes (x86::x87-floating-point-modes)) + (setf sse2-modes (x86::sse2-floating-point-modes))) + + (setf (x86::x87-floating-point-modes) old-x87-modes) + (setf (x86::sse2-floating-point-modes) old-sse2-modes)) + + (let* ((x87-exceptions-enabled (ldb x86::x87-float-traps-byte x87-modes)) + (x87-rc (ldb x86::x87-float-rounding-mode x87-modes)) + (sse2-exceptions-enabled (ldb x86::float-traps-byte sse2-modes)) + (sse2-rc (ldb x86::float-rounding-mode sse2-modes))) + (format t "*X87 FP mode words:~%") + (x86::print-x87-fp-modes x87-modes) + (format t "~%*SSE2 FP mode words:~%") + (x86::print-sse2-fp-modes sse2-modes) + + ;; Verify that we set the enabled exceptions + ;; correctly. First for sse2, then for x87. + (assert-false (logbitp 5 sse2-exceptions-enabled)) ; precision + (assert-true (logbitp 4 sse2-exceptions-enabled)) ; underflow + (assert-true (logbitp 3 sse2-exceptions-enabled)) ; overflow + (assert-true (logbitp 2 sse2-exceptions-enabled)) ; divide-by-zero + (assert-false (logbitp 1 sse2-exceptions-enabled)) ; denormal + (assert-true (logbitp 0 sse2-exceptions-enabled)) ; invalid + + (assert-false (logbitp 5 x87-exceptions-enabled)) ; precision + (assert-true (logbitp 4 x87-exceptions-enabled)) ; underflow + (assert-true (logbitp 3 x87-exceptions-enabled)) ; overflow + (assert-true (logbitp 2 x87-exceptions-enabled)) ; divide-by-zero + (assert-false (logbitp 1 x87-exceptions-enabled)) ; denormal + (assert-true (logbitp 0 x87-exceptions-enabled)) ; invalid + + ;; Verify the rounding mode is set to zero + (assert-eql :zero (car (rassoc sse2-rc x86::rounding-mode-alist))) + (assert-eql :zero (car (rassoc x87-rc x86::rounding-mode-alist))) + + ;; Verify precision for x87 + (assert-eql :64-bits + (car (rassoc (ldb x86::x87-float-precision-control-byte x87-modes) + x86::x87-float-precision-control-alist)))))) ===================================== tests/float.lisp ===================================== @@ -342,4 +342,3 @@ (x86::x87-floating-point-modes))))) (assert-true (typep new-mode 'x86::float-modes)) (assert-equal new-mode (setf (x86::x87-floating-point-modes) new-mode)))) - ===================================== tests/irrat.lisp ===================================== @@ -245,6 +245,17 @@ (tanh #c(200w0 200w0)))) +;; See bug #424 +(define-test hypot + (:tag :issues) + (assert-eql 3.8950612975366328d0 + (kernel:%hypot 2.302585092994046d0 3.141592653589793d0)) + (let ((result (expt #C(2.302585092994046d0 3.141592653589793d0) 4))) + (assert-eql -188.4466069439329d0 + (realpart result)) + (assert-eql -132.16721026205448d0 + (imagpart result)))) + (define-test cos-tiny (:tag issues) ;; This test comes from the Maxima testsuite where core-math was not @@ -260,3 +271,4 @@ ;; The computed result looked it had like a single-precision accuracy. (assert-eql -0.37106498060016496d0 (kernel:%log (kernel:make-double-float (+ 1071644672 398457) 0)))) + View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/5ff177cb9f69fcd1042dbdf... -- View it on GitLab: https://gitlab.common-lisp.net/cmucl/cmucl/-/compare/5ff177cb9f69fcd1042dbdf... You're receiving this email because of your account on gitlab.common-lisp.net.
participants (1)
-
Raymond Toy (@rtoy)