Changeset 13949


Ignore:
Timestamp:
Jul 10, 2010, 3:41:58 AM (9 years ago)
Author:
rme
Message:

Handler support for SIGFPE while in foreign code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/rme-fpe/lisp-kernel/x86-exceptions.c

    r13940 r13949  
    942942
    943943Boolean
    944 handle_floating_point_exception(TCR *tcr, ExceptionInformation *xp, siginfo_t *info, int old_valence)
     944handle_foreign_fpe(TCR *tcr, ExceptionInformation *xp, siginfo_t *info)
     945{
     946#ifdef X8632
     947  return false;
     948#else
     949  int code;
     950
     951#ifdef WINDOWS
     952  if (info->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
     953    return false;
     954#else
     955  if (info->si_code == FPE_INTDIV)
     956    return false;
     957#endif
     958
     959  /*
     960   * Cooperate with .SPffcall to avoid saving and restoring the MXCSR
     961   * around every foreign call.
     962   */
     963    if (! (tcr->flags & (1<<TCR_FLAG_BIT_FOREIGN_FPE))) {
     964      tcr->flags |= (1<<TCR_FLAG_BIT_FOREIGN_FPE);
     965      tcr->lisp_mxcsr = xpMXCSR(xp) & ~MXCSR_STATUS_MASK;
     966    }
     967    xpMXCSR(xp) &= ~MXCSR_STATUS_MASK;
     968    xpMXCSR(xp) |= MXCSR_CONTROL_MASK;
     969    return true;
     970#endif
     971}
     972
     973Boolean
     974handle_floating_point_exception(TCR *tcr, ExceptionInformation *xp, siginfo_t *info)
    945975{
    946976  int code,skip;
     
    953983  code = info->si_code;
    954984#endif 
    955 
    956   if (old_valence == TCR_STATE_FOREIGN) {
    957 #ifdef X8632
    958     return false;
    959 #else
    960     /* We got a floating point exception in foreign code.  Set a flag
    961        in the TCR to indicate this, and resume with FP exceptions
    962        disabled.  .SPffcall will check the flag, and if it's set,
    963        will save the FP status and re-enable exceptions. */
    964 
    965     /*
    966      * We might get multiple foreign FP exceptions, so take care
    967      * to preseve lisp's original MXCSR.
    968      */
    969     if (! (tcr->flags & (1<<TCR_FLAG_BIT_FOREIGN_FPE))) {
    970       tcr->lisp_mxcsr = xpMXCSR(xp) & ~MXCSR_STATUS_MASK;
    971       tcr->flags |= (1<<TCR_FLAG_BIT_FOREIGN_FPE);
    972     }
    973     xpMXCSR(xp) &= ~MXCSR_STATUS_MASK;
    974     xpMXCSR(xp) |= MXCSR_CONTROL_MASK;
    975     return true;
    976 #endif
    977   }
    978985
    979986  if ((fulltag_of(cmain) == fulltag_misc) &&
     
    11011108  pc program_counter = (pc)xpPC(context);
    11021109
    1103   if ((old_valence != TCR_STATE_LISP) && signum != SIGFPE) {
    1104     return false;
     1110  if (old_valence != TCR_STATE_LISP) {
     1111    if (old_valence == TCR_STATE_FOREIGN && signum == SIGFPE) {
     1112      return handle_foreign_fpe(tcr, context, info);
     1113    } else {
     1114      return false;
     1115    }
    11051116  }
    11061117
     
    12601271#endif
    12611272
    1262     return handle_floating_point_exception(tcr, context, info, old_valence);
     1273    return handle_floating_point_exception(tcr, context, info);
    12631274
    12641275#if SIGBUS != SIGNUM_FOR_INTN_TRAP
     
    33923403      case EXC_ARITHMETIC:
    33933404        signum = SIGFPE;
     3405        if (code == EXC_I386_DIV)
     3406          code = FPE_INTDIV;
    33943407        break;
    33953408       
Note: See TracChangeset for help on using the changeset viewer.