|
48 | 48 |
|
49 | 49 | # define fopen_for_append(filename) fopen(filename,"a+t") |
50 | 50 |
|
51 | | -/* default fpu control word: |
52 | | - _RC_NEAR: round to nearest |
53 | | - _PC_53 : double precision arithmetic (instead of extended) |
54 | | - _EM_XXX: silent operations (no signals please) |
| 51 | +/* default fpu control word and mask: |
| 52 | + _MCW_RC: Rounding control |
| 53 | + _RC_NEAR: round to nearest |
| 54 | + _MCW_PC: Precision control |
| 55 | + _PC_53: double precision arithmetic (instead of extended) |
| 56 | + _MCW_EM: Interupt exception mask |
| 57 | + _EM_XXX: silent operations (no signals please) |
| 58 | + https://docs.microsoft.com/en-us/previous-versions/e9b52ceh%28v%3dvs.140%29 |
55 | 59 | */ |
| 60 | + |
| 61 | +#if !defined(_MCW_PC) |
| 62 | +// x64 does not support _MCW_PC |
| 63 | +// The x64 CPU hardware default is 64-bit precision mode (80-bit long double); |
| 64 | +// Microsoft expects software to set 53-bit mode before any user mode x87 instructions |
| 65 | +// are reached. Microsoft made a change in responsibility for initializing precision mode |
| 66 | +// in the X64 OS. The X64 OS sets 53-bit mode prior to starting your .exe, where the 32-bit OS |
| 67 | +// expected the program to make that initialization. |
| 68 | +# define _MCW_PC 0 |
| 69 | +#endif |
| 70 | + |
| 71 | +#define FPU_MASK (_MCW_EM | _MCW_RC | _MCW_PC) |
56 | 72 | #define FPU_DEFAULT (_RC_NEAR + _PC_53 + _EM_INVALID + _EM_ZERODIVIDE + _EM_OVERFLOW + _EM_UNDERFLOW + _EM_INEXACT + _EM_DENORMAL) |
57 | 73 |
|
58 | 74 | #define MAXFRAMES 64 |
|
116 | 132 | ioInitPlatformSpecific(void) |
117 | 133 | { |
118 | 134 | /* Setup the FPU */ |
119 | | - _controlfp(FPU_DEFAULT, _MCW_EM | _MCW_RC | _MCW_PC | _MCW_IC); |
| 135 | + _controlfp(FPU_DEFAULT, FPU_MASK); |
120 | 136 |
|
121 | 137 | /* Create the wake up event. */ |
122 | 138 | vmWakeUpEvent = CreateEvent(NULL, 1, 0, NULL); |
@@ -363,8 +379,9 @@ static LONG CALLBACK squeakExceptionHandler(LPEXCEPTION_POINTERS exp) |
363 | 379 | DWORD code = exp->ExceptionRecord->ExceptionCode; |
364 | 380 | if((code >= EXCEPTION_FLT_DENORMAL_OPERAND) && (code <= EXCEPTION_FLT_UNDERFLOW)) |
365 | 381 | { |
366 | | - /* turn on the default masking of exceptions in the FPU and proceed */ |
367 | | - _controlfp(FPU_DEFAULT, _MCW_EM | _MCW_RC | _MCW_PC | _MCW_IC); |
| 382 | + /* in case FFI callout to foreign code changed FP mode */ |
| 383 | + /* restore our default masking of exceptions in the FPU and proceed */ |
| 384 | + _controlfp(FPU_DEFAULT, FPU_MASK); |
368 | 385 | result = EXCEPTION_CONTINUE_EXECUTION; |
369 | 386 | } |
370 | 387 | } |
@@ -799,3 +816,4 @@ void *os_exports[][3] = |
799 | 816 | { |
800 | 817 | { 0, 0, 0 } |
801 | 818 | }; |
| 819 | + |
0 commit comments