LONG __stdcall FpeHandler(PEXCEPTION_POINTERS pe) { PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)pe->ExceptionRecord; CONTEXT *c = (CONTEXT*)pe->ContextRecord; switch (e->ExceptionCode) { case STATUS_FLOAT_DENORMAL_OPERAND: case STATUS_FLOAT_DIVIDE_BY_ZERO: case STATUS_FLOAT_INEXACT_RESULT: case STATUS_FLOAT_INVALID_OPERATION: case STATUS_FLOAT_OVERFLOW: case STATUS_FLOAT_STACK_CHECK: case STATUS_FLOAT_UNDERFLOW: case STATUS_FLOAT_MULTIPLE_FAULTS: case STATUS_FLOAT_MULTIPLE_TRAPS: X87CW(c) |= FPU_EXCEPTION_MASK; /* disable all FPU exceptions */ X87SW(c) &= ~FPU_STATUS_FLAGS; /* clear all pending FPU exceptions */ #ifdef _M_IX86 if (c->ContextFlags & CONTEXT_EXTENDED_REGISTERS) { #endif MXCSR(c) |= SSE_EXCEPTION_MASK; /* disable all SSE exceptions */ MXCSR(c) &= ~SSE_STATUS_FLAGS; /* clear all pending SSE exceptions */ #ifdef _M_IX86 } #endif return EXCEPTION_CONTINUE_EXECUTION; } LONG action = EXCEPTION_CONTINUE_SEARCH; if (gFPEPreviousFilter) action = gFPEPreviousFilter(pe); return action; }
LONG factor_vm::exception_handler(PEXCEPTION_RECORD e, void* frame, PCONTEXT c, void* dispatch) { switch (e->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: signal_fault_addr = e->ExceptionInformation[1]; signal_fault_pc = c->EIP; verify_memory_protection_error(signal_fault_addr); dispatch_signal_handler((cell*)&c->ESP, (cell*)&c->EIP, (cell)factor::memory_signal_handler_impl); break; case STATUS_FLOAT_DENORMAL_OPERAND: case STATUS_FLOAT_DIVIDE_BY_ZERO: case STATUS_FLOAT_INEXACT_RESULT: case STATUS_FLOAT_INVALID_OPERATION: case STATUS_FLOAT_OVERFLOW: case STATUS_FLOAT_STACK_CHECK: case STATUS_FLOAT_UNDERFLOW: case STATUS_FLOAT_MULTIPLE_FAULTS: case STATUS_FLOAT_MULTIPLE_TRAPS: #ifdef FACTOR_64 signal_fpu_status = fpu_status(MXCSR(c)); #else signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c)); // This seems to have no effect X87SW(c) = 0; #endif MXCSR(c) &= 0xffffffc0; dispatch_signal_handler((cell*)&c->ESP, (cell*)&c->EIP, (cell)factor::fp_signal_handler_impl); break; default: signal_number = e->ExceptionCode; dispatch_signal_handler((cell*)&c->ESP, (cell*)&c->EIP, (cell)factor::synchronous_signal_handler_impl); break; } return ExceptionContinueExecution; }
LONG factor_vm::exception_handler(PEXCEPTION_RECORD e, void *frame, PCONTEXT c, void *dispatch) { c->ESP = (cell)fix_callstack_top((stack_frame *)c->ESP); ctx->callstack_top = (stack_frame *)c->ESP; switch (e->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: signal_fault_addr = e->ExceptionInformation[1]; c->EIP = (cell)factor::memory_signal_handler_impl; break; case STATUS_FLOAT_DENORMAL_OPERAND: case STATUS_FLOAT_DIVIDE_BY_ZERO: case STATUS_FLOAT_INEXACT_RESULT: case STATUS_FLOAT_INVALID_OPERATION: case STATUS_FLOAT_OVERFLOW: case STATUS_FLOAT_STACK_CHECK: case STATUS_FLOAT_UNDERFLOW: case STATUS_FLOAT_MULTIPLE_FAULTS: case STATUS_FLOAT_MULTIPLE_TRAPS: #ifdef FACTOR_64 signal_fpu_status = fpu_status(MXCSR(c)); #else signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c)); /* This seems to have no effect */ X87SW(c) = 0; #endif MXCSR(c) &= 0xffffffc0; c->EIP = (cell)factor::fp_signal_handler_impl; break; default: signal_number = e->ExceptionCode; c->EIP = (cell)factor::misc_signal_handler_impl; break; } return 0; }
inline static void mach_clear_fpu_status(x86_float_state64_t *float_state) { MXCSR(float_state) &= 0xffffffc0; memset(&X87SW(float_state), 0, sizeof(X87SW(float_state))); }
inline static unsigned int mach_fpu_status(x86_float_state64_t *float_state) { unsigned short x87sw; memcpy(&x87sw, &X87SW(float_state), sizeof(x87sw)); return MXCSR(float_state) | x87sw; }