Changeset 13937


Ignore:
Timestamp:
Jul 7, 2010, 7:59:31 PM (9 years ago)
Author:
rme
Message:

New scheme for dealing with fp exceptions in foreign code.

Instead of masking fp exceptions around FF calls, leave them enabled.
handle_exception() and handle_floating_point_exception() are now
prepared to deal with them by preserving the currently masked exceptions,
masking them all, and then resuming execution (after setting a flag
to make note of this). At the end of .SPffcall, if the flag is set
the fp status is saved, and the masked exceptions are restored
to what they were before the FF call.

This may not make a huge difference in ff call performance, but
unconditionally saving and restoring the MXCSR around every call
is probably not free (according to one source I consulted, ldmxcsr
takes 42 clock cycles; stmxcsr 19).

Location:
branches/rme-fpe/lisp-kernel
Files:
3 edited

Legend:

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

    r13882 r13937  
    942942
    943943Boolean
    944 handle_floating_point_exception(TCR *tcr, ExceptionInformation *xp, siginfo_t *info)
     944handle_floating_point_exception(TCR *tcr, ExceptionInformation *xp, siginfo_t *info, int old_valence)
    945945{
    946946  int code,skip;
     
    954954#endif 
    955955
    956   if ((fulltag_of(cmain) == fulltag_misc) &&
    957       (header_subtag(header_of(cmain)) == subtag_macptr)) {
     956  if (old_valence == TCR_STATE_FOREIGN) {
     957    /* We got a floating point exception in foreign code.  Set a flag
     958       in the TCR to indicate this, and resume with FP exceptions
     959       disabled.  .SPffcall will check the flag, and if it's set,
     960       will save the FP status and re-enable exceptions. */
     961
     962    /*
     963     * We might get multiple foreign FP exceptions, so take care
     964     * to preseve lisp's original MXCSR.
     965     */
     966    if (! (tcr->flags & (1<<TCR_FLAG_BIT_FOREIGN_FPE))) {
     967      tcr->lisp_mxcsr = xpMXCSR(xp) & ~MXCSR_STATUS_MASK;
     968      tcr->flags |= (1<<TCR_FLAG_BIT_FOREIGN_FPE);
     969    }
     970    xpMXCSR(xp) &= ~MXCSR_STATUS_MASK;
     971    xpMXCSR(xp) |= MXCSR_CONTROL_MASK;
     972    return true;
     973  } else if ((fulltag_of(cmain) == fulltag_misc) &&
     974             (header_subtag(header_of(cmain)) == subtag_macptr)) {
    958975    xcf = create_exception_callback_frame(xp, tcr);
    959976    skip = callback_to_lisp(tcr, cmain, xp, xcf, SIGFPE, code, 0, 0);
     
    10781095  pc program_counter = (pc)xpPC(context);
    10791096
    1080   if (old_valence != TCR_STATE_LISP) {
     1097  if ((old_valence != TCR_STATE_LISP) && signum != SIGFPE) {
    10811098    return false;
    10821099  }
     
    12371254#endif
    12381255
    1239     return handle_floating_point_exception(tcr, context, info);
     1256    return handle_floating_point_exception(tcr, context, info, old_valence);
    12401257
    12411258#if SIGBUS != SIGNUM_FOR_INTN_TRAP
  • branches/rme-fpe/lisp-kernel/x86-spentry32.s

    r13561 r13937  
    41844184        __(popl rcontext(tcr.save_eflags))
    41854185        __(cld)       
    4186         __(stmxcsr rcontext(tcr.lisp_mxcsr))
    41874186        __(emms)
    4188         __(ldmxcsr rcontext(tcr.foreign_mxcsr))
    41894187        __(movl (%esp),%ebp)
    41904188LocalLabelPrefix`'ffcall_setup:
     
    42154213        __(clr %fn)
    42164214        __(pxor %fpzero,%fpzero)
     4215        /* If we got a floating-point exception during the ff-call,
     4216           our handler will have set a flag, preserved lisp's MXCSR,
     4217           and resumed execution with fp exceptions masked. */
     4218        __(btrq $TCR_FLAG_BIT_FOREIGN_FPE,rcontext(tcr.flags))
     4219        __(jnc 1f)
    42174220        __(cmpb $0,C(bogus_fp_exceptions))
    42184221        __(je 0f)
     
    42224225        __ifdef(`SSE2_MATH_LIB')
    42234226        __(stmxcsr rcontext(tcr.ffi_exception))
     4227        __(ldmxcsr rcontext(tcr.lisp_mxcsr)) /* preserved by the handler */
    42244228        __else
    42254229        __(fnstsw rcontext(tcr.ffi_exception))
     
    42354239        __(pop %arg_y)           
    42364240        __(pop %temp1)
    4237         __(ldmxcsr rcontext(tcr.lisp_mxcsr))
    42384241        __(check_pending_interrupt(%temp0))
    42394242        __(pop %temp0)
  • branches/rme-fpe/lisp-kernel/x86-spentry64.s

    r13561 r13937  
    39913991        __(movq $TCR_STATE_FOREIGN,rcontext(tcr.valence))
    39923992        __(movq rcontext(tcr.foreign_sp),%rsp)
    3993         __(stmxcsr rcontext(tcr.lisp_mxcsr))
    39943993        __(emms)
    3995         __(ldmxcsr rcontext(tcr.foreign_mxcsr))
    39963994        __(movq (%rsp),%rbp)
    39973995        __ifdef(`DARWIN_GS_HACK')
     
    40704068        __(clr %fn)
    40714069        __(pxor %fpzero,%fpzero)
     4070
     4071        /* If we got a floating-point exception during the ff-call,
     4072           our handler will have set a flag, preserved lisp's MXCSR,
     4073           and resumed execution with fp exceptions masked. */
     4074        __(btrq $TCR_FLAG_BIT_FOREIGN_FPE,rcontext(tcr.flags))
     4075        __(jnc 1f)
    40724076        __(cmpb $0,C(bogus_fp_exceptions)(%rip))
    40734077        __(je 0f)
     
    40754079        __(jmp 1f)
    407640800:      __(stmxcsr rcontext(tcr.ffi_exception))
     4081        __(ldmxcsr rcontext(tcr.lisp_mxcsr)) /* preserved by the handler */
    407740821:      __(movq rcontext(tcr.save_vsp),%rsp)
    40784083        __(movq rcontext(tcr.save_rbp),%rbp)
     
    40904095        __(pop %temp2)
    40914096        __(pop %temp1)
    4092         __(ldmxcsr rcontext(tcr.lisp_mxcsr))
    40934097        __(check_pending_interrupt(%temp0))
    40944098        __(pop %temp0)
     
    42114215        __(movq $TCR_STATE_FOREIGN,rcontext(tcr.valence))
    42124216        __(movq rcontext(tcr.foreign_sp),%rsp)
    4213         __(stmxcsr rcontext(tcr.lisp_mxcsr))
    42144217        __(emms)
    4215         __(ldmxcsr rcontext(tcr.foreign_mxcsr))
    42164218        __(movq (%rsp),%rbp)
    42174219        __ifdef(`DARWIN_GS_HACK')
     
    42904292        __(clr %fn)
    42914293        __(pxor %fpzero,%fpzero)
     4294        /* Check for fp exceptions as in .SPffcall, above. */
     4295        __(btrq $TCR_FLAG_BIT_FOREIGN_FPE,rcontext(tcr.flags))
     4296        __(jnc 1f)
    42924297        __(cmpb $0,C(bogus_fp_exceptions)(%rip))
    42934298        __(je 0f)
     
    42954300        __(jmp 1f)
    429643010:      __(stmxcsr rcontext(tcr.ffi_exception))
     4302        __(ldmxcsr rcontext(tcr.lisp_mxcsr))
    429743031:      __(movq rcontext(tcr.save_vsp),%rsp)
    42984304        __(movq rcontext(tcr.save_rbp),%rbp)
     
    43104316        __(pop %temp2)
    43114317        __(pop %temp1)
    4312         __(ldmxcsr rcontext(tcr.lisp_mxcsr))
    43134318        __(check_pending_interrupt(%temp0))
    43144319        __(pop %temp0)
Note: See TracChangeset for help on using the changeset viewer.