use secret sauce to clear MXCSR in win32 context, and handle secret STATUS_FLOAT_MULTIPLE_* SEH codes raised by SSE traps

db4
Joe Groff 2009-09-14 12:02:02 -05:00
parent 578c977a7e
commit c1bc5f22e4
4 changed files with 49 additions and 10 deletions

29
vm/os-windows-nt.32.hpp Normal file → Executable file
View File

@ -4,4 +4,33 @@ namespace factor
#define ESP Esp
#define EIP Eip
typedef struct DECLSPEC_ALIGN(16) _M128A {
ULONGLONG Low;
LONGLONG High;
} M128A, *PM128A;
/* The ExtendedRegisters field of the x86.32 CONTEXT structure uses this layout; however,
* this structure is only made available from winnt.h on x86.64 */
typedef struct _XMM_SAVE_AREA32 {
WORD ControlWord; /* 000 */
WORD StatusWord; /* 002 */
BYTE TagWord; /* 004 */
BYTE Reserved1; /* 005 */
WORD ErrorOpcode; /* 006 */
DWORD ErrorOffset; /* 008 */
WORD ErrorSelector; /* 00c */
WORD Reserved2; /* 00e */
DWORD DataOffset; /* 010 */
WORD DataSelector; /* 014 */
WORD Reserved3; /* 016 */
DWORD MxCsr; /* 018 */
DWORD MxCsr_Mask; /* 01c */
M128A FloatRegisters[8]; /* 020 */
M128A XmmRegisters[16]; /* 0a0 */
BYTE Reserved4[96]; /* 1a0 */
} XMM_SAVE_AREA32, *PXMM_SAVE_AREA32;
#define X87SW(ctx) (ctx)->FloatSave.StatusWord
#define MXCSR(ctx) ((XMM_SAVE_AREA32*)((ctx)->ExtendedRegisters))->MxCsr
}

3
vm/os-windows-nt.64.hpp Normal file → Executable file
View File

@ -4,4 +4,7 @@ namespace factor
#define ESP Rsp
#define EIP Rip
#define X87SW(ctx) (ctx)->FloatSave.StatusWord
#define MXCSR(ctx) (ctx)->MxCsr
}

22
vm/os-windows-nt.cpp Normal file → Executable file
View File

@ -28,16 +28,18 @@ FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe)
c->EIP = (cell)memory_signal_handler_impl;
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
case EXCEPTION_FLT_INEXACT_RESULT:
case EXCEPTION_FLT_INVALID_OPERATION:
case EXCEPTION_FLT_OVERFLOW:
case EXCEPTION_FLT_STACK_CHECK:
case EXCEPTION_FLT_UNDERFLOW:
/* XXX MxCsr is not available in CONTEXT structure on x86.32 */
signal_fpu_status = c->FloatSave.StatusWord;
c->FloatSave.StatusWord = 0;
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:
signal_fpu_status = fpu_status(X87SW(c) | MXCSR(c));
X87SW(c) = 0;
MXCSR(c) &= 0xffffffc0;
c->EIP = (cell)fp_signal_handler_impl;
break;
case 0x40010006:

5
vm/os-windows-nt.hpp Normal file → Executable file
View File

@ -23,4 +23,9 @@ void c_to_factor_toplevel(cell quot);
FACTOR_STDCALL LONG exception_handler(PEXCEPTION_POINTERS pe);
void open_console();
// SSE traps raise these exception codes, which are defined in internal NT headers
// but not winbase.h
#define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4
#define STATUS_FLOAT_MULTIPLE_TRAPS 0xC00002B5
}