Nikolay Igotti
Fixing FPU control word on Win32
On Win32 fixing of control word is also possible, but done differently, as Win32 uses SEH (structured exception handlers) to handle hardware faults, and some magic is required to let fault really restart.
#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
#include <float.h>
long original_fpcw = 0;
LONG WINAPI exceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
DWORD ec = exceptionInfo->ExceptionRecord->ExceptionCode;
if (ec == EXCEPTION_FLT_UNDERFLOW || ec == EXCEPTION_FLT_INEXACT_RESULT) {
PCONTEXT ctx = exceptionInfo->ContextRecord;
// mask underflow, precision, invalid
ctx->FloatSave.ControlWord = original_fpcw | 0xffff0031;
ctx->FloatSave.StatusWord &= ctx->FloatSave.ControlWord | 0xffffff80;
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
int _tmain(int argc, _TCHAR* argv[])
{
__try {
float d=0.1,v=1;
int i;
original_fpcw = _control87(0, 0);
_control87(_EM_INEXACT, MCW_EM);
for (i=0; i < 1000; i++) {
v *= d;
}
printf("v = %0.60f\n",v);
} __except(exceptionFilter(
(_EXCEPTION_POINTERS*)GetExceptionInformation())) {
}
return 0;
}
PS: for references, FPU control word bits mean (fpu_control.h):
* 15-13 12 11-10 9-8 7-6 5 4 3 2 1 0 * | reserved | IC | RC | PC | reserved | PM | UM | OM | ZM | DM | IM * * IM: Invalid operation mask * DM: Denormalized operand mask * ZM: Zero-divide mask * OM: Overflow mask * UM: Underflow mask * PM: Precision (inexact result) mask * * Mask bit is 1 means no interrupt. * * PC: Precision control * 11 - round to extended precision * 10 - round to double precision * 00 - round to single precision * * RC: Rounding control * 00 - rounding to nearest * 01 - rounding down (toward - infinity) * 10 - rounding up (toward + infinity) * 11 - rounding toward zero * * * IC: Infinity control * That is for 8087 and 80287 only.
Posted at 04:18PM Jun 20, 2007 by nike in Sun | Comments[2]
Wednesday Jun 20, 2007
Posted by Ivan Krylov on July 03, 2007 at 06:05 PM MSD #
Posted by Ivan Krylov on August 01, 2007 at 03:27 PM MSD #