Index: src/code/float-trap.lisp
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/code/float-trap.lisp,v
retrieving revision 1.19
diff -u -r1.19 float-trap.lisp
--- src/code/float-trap.lisp	6 Oct 2005 19:43:00 -0000	1.19
+++ src/code/float-trap.lisp	28 Jun 2006 10:34:15 -0000
@@ -153,10 +153,28 @@
   `(not (zerop (logand ,(dpb (float-trap-mask traps) float-traps-byte 0)
                        (floating-point-modes)))))
 
+;;; SIGFPE code to floating-point error
+#+freebsd
+(defparameter *sigfpe-code-error-alist*
+  (list (cons sb!unix::fpe-intovf 'floating-point-overflow)
+        (cons sb!unix::fpe-intdiv 'division-by-zero)
+        (cons sb!unix::fpe-fltdiv 'division-by-zero)
+        (cons sb!unix::fpe-fltovf 'floating-point-overflow)
+        (cons sb!unix::fpe-fltund 'floating-point-underflow)
+        (cons sb!unix::fpe-fltres 'floating-point-inexact)
+        (cons sb!unix::fpe-fltinv 'floating-point-invalid-operation)
+        (cons sb!unix::fpe-fltsub 'floating-point-exception)))
+
 ;;; Signal the appropriate condition when we get a floating-point error.
 (defun sigfpe-handler (signal info context)
-  (declare (ignore signal info))
+  (declare (ignore signal #!-freebsd info))
+  #!+freebsd
+  (declare (type system-area-pointer info))
   (declare (type system-area-pointer context))
+  #!+freebsd
+  (let ((code (sb!unix::siginfo-code info)))
+    (error (or (cdr (assoc code *sigfpe-code-error-alist*))
+               'floating-point-exception)))
   (let* ((modes (context-floating-point-modes
                  (sb!alien:sap-alien context (* os-context-t))))
          (traps (logand (ldb float-exceptions-byte modes)
Index: src/code/target-signal.lisp
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/code/target-signal.lisp,v
retrieving revision 1.34
diff -u -r1.34 target-signal.lisp
--- src/code/target-signal.lisp	10 Apr 2006 16:08:45 -0000	1.34
+++ src/code/target-signal.lisp	28 Jun 2006 10:34:15 -0000
@@ -163,6 +163,10 @@
 
 ;;;; etc.
 
+;;; extract si_code from siginfo_t
+(sb!alien:define-alien-routine ("siginfo_code" siginfo-code) sb!alien:int
+  (info system-area-pointer))
+
 ;;; CMU CL comment:
 ;;;   Magically converted by the compiler into a break instruction.
 (defun receive-pending-interrupt ()
Index: src/runtime/interrupt.c
===================================================================
RCS file: /cvsroot/sbcl/sbcl/src/runtime/interrupt.c,v
retrieving revision 1.113
diff -u -r1.113 interrupt.c
--- src/runtime/interrupt.c	7 Jun 2006 16:25:10 -0000	1.113
+++ src/runtime/interrupt.c	28 Jun 2006 10:34:15 -0000
@@ -1376,3 +1376,9 @@
     SHOW("returning from interrupt_init()");
 #endif
 }
+
+int
+siginfo_code(siginfo_t *info)
+{
+    return info->si_code;
+}
Index: tools-for-build/grovel-headers.c
===================================================================
RCS file: /cvsroot/sbcl/sbcl/tools-for-build/grovel-headers.c,v
retrieving revision 1.15
diff -u -r1.15 grovel-headers.c
--- tools-for-build/grovel-headers.c	18 Jun 2006 23:47:58 -0000	1.15
+++ tools-for-build/grovel-headers.c	28 Jun 2006 10:34:15 -0000
@@ -338,6 +338,16 @@
     defsignal("sigxcpu", SIGXCPU);
     defsignal("sigxfsz", SIGXFSZ);
 #endif
+#ifdef __FreeBSD__
+    defconstant("fpe-intovf", FPE_INTOVF);
+    defconstant("fpe-intdiv", FPE_INTDIV);
+    defconstant("fpe-fltdiv", FPE_FLTDIV);
+    defconstant("fpe-fltovf", FPE_FLTOVF);
+    defconstant("fpe-fltund", FPE_FLTUND);
+    defconstant("fpe-fltres", FPE_FLTRES);
+    defconstant("fpe-fltinv", FPE_FLTINV);
+    defconstant("fpe-fltsub", FPE_FLTSUB);
+#endif
 #endif // _WIN32
     return 0;
 }
