Changeset 13949
- Timestamp:
- Jul 9, 2010, 8:41:58 PM (14 years ago)
- File:
-
- 1 edited
-
branches/rme-fpe/lisp-kernel/x86-exceptions.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/rme-fpe/lisp-kernel/x86-exceptions.c
r13940 r13949 942 942 943 943 Boolean 944 handle_floating_point_exception(TCR *tcr, ExceptionInformation *xp, siginfo_t *info, int old_valence) 944 handle_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 973 Boolean 974 handle_floating_point_exception(TCR *tcr, ExceptionInformation *xp, siginfo_t *info) 945 975 { 946 976 int code,skip; … … 953 983 code = info->si_code; 954 984 #endif 955 956 if (old_valence == TCR_STATE_FOREIGN) {957 #ifdef X8632958 return false;959 #else960 /* We got a floating point exception in foreign code. Set a flag961 in the TCR to indicate this, and resume with FP exceptions962 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 care967 * 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 #endif977 }978 985 979 986 if ((fulltag_of(cmain) == fulltag_misc) && … … 1101 1108 pc program_counter = (pc)xpPC(context); 1102 1109 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 } 1105 1116 } 1106 1117 … … 1260 1271 #endif 1261 1272 1262 return handle_floating_point_exception(tcr, context, info , old_valence);1273 return handle_floating_point_exception(tcr, context, info); 1263 1274 1264 1275 #if SIGBUS != SIGNUM_FOR_INTN_TRAP … … 3392 3403 case EXC_ARITHMETIC: 3393 3404 signum = SIGFPE; 3405 if (code == EXC_I386_DIV) 3406 code = FPE_INTDIV; 3394 3407 break; 3395 3408
Note:
See TracChangeset
for help on using the changeset viewer.
