]> gitweb.factorcode.org Git - factor.git/commitdiff
use secret sauce to clear MXCSR in win32 context, and handle secret STATUS_FLOAT_MULT...
authorJoe Groff <arcata@gmail.com>
Mon, 14 Sep 2009 17:02:02 +0000 (12:02 -0500)
committerJoe Groff <arcata@gmail.com>
Mon, 14 Sep 2009 17:02:02 +0000 (12:02 -0500)
vm/os-windows-nt.32.hpp [changed mode: 0644->0755]
vm/os-windows-nt.64.hpp [changed mode: 0644->0755]
vm/os-windows-nt.cpp [changed mode: 0644->0755]
vm/os-windows-nt.hpp [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index ed67e28..748272f
@@ -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
+
 }
old mode 100644 (file)
new mode 100755 (executable)
index 30ce150..b64bd60
@@ -4,4 +4,7 @@ namespace factor
 #define ESP Rsp
 #define EIP Rip
 
+#define X87SW(ctx) (ctx)->FloatSave.StatusWord
+#define MXCSR(ctx) (ctx)->MxCsr
+
 }
old mode 100644 (file)
new mode 100755 (executable)
index 017a96b..b50c9b7
@@ -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:
old mode 100644 (file)
new mode 100755 (executable)
index 4371771..088103b
@@ -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
+
 }