Index: /branches/rme-fpe/lisp-kernel/x86-exceptions.c
===================================================================
--- /branches/rme-fpe/lisp-kernel/x86-exceptions.c	(revision 13948)
+++ /branches/rme-fpe/lisp-kernel/x86-exceptions.c	(revision 13949)
@@ -942,5 +942,35 @@
 
 Boolean
-handle_floating_point_exception(TCR *tcr, ExceptionInformation *xp, siginfo_t *info, int old_valence)
+handle_foreign_fpe(TCR *tcr, ExceptionInformation *xp, siginfo_t *info)
+{
+#ifdef X8632
+  return false;
+#else
+  int code;
+
+#ifdef WINDOWS
+  if (info->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
+    return false;
+#else
+  if (info->si_code == FPE_INTDIV)
+    return false;
+#endif
+
+  /*
+   * Cooperate with .SPffcall to avoid saving and restoring the MXCSR
+   * around every foreign call.
+   */
+    if (! (tcr->flags & (1<<TCR_FLAG_BIT_FOREIGN_FPE))) {
+      tcr->flags |= (1<<TCR_FLAG_BIT_FOREIGN_FPE);
+      tcr->lisp_mxcsr = xpMXCSR(xp) & ~MXCSR_STATUS_MASK;
+    }
+    xpMXCSR(xp) &= ~MXCSR_STATUS_MASK;
+    xpMXCSR(xp) |= MXCSR_CONTROL_MASK;
+    return true;
+#endif
+}
+
+Boolean
+handle_floating_point_exception(TCR *tcr, ExceptionInformation *xp, siginfo_t *info)
 {
   int code,skip;
@@ -953,27 +983,4 @@
   code = info->si_code;
 #endif  
-
-  if (old_valence == TCR_STATE_FOREIGN) {
-#ifdef X8632
-    return false;
-#else
-    /* We got a floating point exception in foreign code.  Set a flag
-       in the TCR to indicate this, and resume with FP exceptions
-       disabled.  .SPffcall will check the flag, and if it's set,
-       will save the FP status and re-enable exceptions. */
-
-    /*
-     * We might get multiple foreign FP exceptions, so take care
-     * to preseve lisp's original MXCSR.
-     */
-    if (! (tcr->flags & (1<<TCR_FLAG_BIT_FOREIGN_FPE))) {
-      tcr->lisp_mxcsr = xpMXCSR(xp) & ~MXCSR_STATUS_MASK;
-      tcr->flags |= (1<<TCR_FLAG_BIT_FOREIGN_FPE);
-    }
-    xpMXCSR(xp) &= ~MXCSR_STATUS_MASK;
-    xpMXCSR(xp) |= MXCSR_CONTROL_MASK;
-    return true;
-#endif
-  }
 
   if ((fulltag_of(cmain) == fulltag_misc) &&
@@ -1101,6 +1108,10 @@
   pc program_counter = (pc)xpPC(context);
 
-  if ((old_valence != TCR_STATE_LISP) && signum != SIGFPE) {
-    return false;
+  if (old_valence != TCR_STATE_LISP) {
+    if (old_valence == TCR_STATE_FOREIGN && signum == SIGFPE) {
+      return handle_foreign_fpe(tcr, context, info);
+    } else {
+      return false;
+    }
   }
 
@@ -1260,5 +1271,5 @@
 #endif
 
-    return handle_floating_point_exception(tcr, context, info, old_valence);
+    return handle_floating_point_exception(tcr, context, info);
 
 #if SIGBUS != SIGNUM_FOR_INTN_TRAP
@@ -3392,4 +3403,6 @@
       case EXC_ARITHMETIC:
         signum = SIGFPE;
+	if (code == EXC_I386_DIV)
+	  code = FPE_INTDIV;
         break;
         
