ReactOS 0.4.15-dev-8231-g29a56f3
fpcontrol.c File Reference
#include <ntstatus.h>
#include <windows.h>
#include <apitest.h>
#include <xmmintrin.h>
#include <float.h>
#include <pseh/pseh2.h>
Include dependency graph for fpcontrol.c:

Go to the source code of this file.

Macros

#define WIN32_NO_STATUS
 
#define ON_IX86(x)
 
#define ON_AMD64(x)
 
#define ON_ARM(x)
 

Typedefs

typedef enum _FP_OP FP_OP
 

Enumerations

enum  _FP_OP {
  OP_Inexact , OP_Underflow , OP_Overflow , OP_ZeroDivide ,
  OP_Invalid , OP_Denormal
}
 

Functions

unsigned int get_native_fpcw (void)
 
void set_native_fpcw (unsigned int value)
 
void Test_controlfp (void)
 
void Test_exceptions (void)
 
 START_TEST (fpcontrol)
 

Variables

struct {
   unsigned int   Value
 
   unsigned int   Mask
 
   unsigned int   Result
 
   unsigned int   Native
 
g_controlfp_Testcases []
 
struct {
   FP_OP   Operation
 
   unsigned int   Fpcw
 
   unsigned int   FpStatus
 
   unsigned int   ExceptionCode
 
   unsigned int   Native
 
g_exception_Testcases []
 

Macro Definition Documentation

◆ ON_AMD64

#define ON_AMD64 (   x)

Definition at line 70 of file fpcontrol.c.

◆ ON_ARM

#define ON_ARM (   x)

Definition at line 76 of file fpcontrol.c.

◆ ON_IX86

#define ON_IX86 (   x)

Definition at line 64 of file fpcontrol.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 9 of file fpcontrol.c.

Typedef Documentation

◆ FP_OP

typedef enum _FP_OP FP_OP

Enumeration Type Documentation

◆ _FP_OP

Enumerator
OP_Inexact 
OP_Underflow 
OP_Overflow 
OP_ZeroDivide 
OP_Invalid 
OP_Denormal 

Definition at line 138 of file fpcontrol.c.

139{
146} FP_OP;
enum _FP_OP FP_OP
@ OP_Overflow
Definition: fpcontrol.c:142
@ OP_ZeroDivide
Definition: fpcontrol.c:143
@ OP_Underflow
Definition: fpcontrol.c:141
@ OP_Inexact
Definition: fpcontrol.c:140
@ OP_Invalid
Definition: fpcontrol.c:144
@ OP_Denormal
Definition: fpcontrol.c:145

Function Documentation

◆ get_native_fpcw()

unsigned int get_native_fpcw ( void  )

Definition at line 18 of file fpcontrol.c.

19{
20#ifdef _M_AMD64
21 return _mm_getcsr();
22#elif defined (_M_IX86)
23 unsigned short fpcw;
24#if defined(_MSC_VER)
25 __asm fstsw[fpcw];
26#else
27 __asm__ __volatile__("fstsw %0" : "=m" (fpcw) : );
28#endif
29 return fpcw;
30#else
31 #error "Unsupported architecture"
32 return 0;
33#endif
34}
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tsub %rbp, %rax\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tsub %rax, %rdx\n" "\tmov %rdx, %rbp\n" "\tjmp *%r8\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $32, %rsp\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
unsigned int _mm_getcsr(void)
Definition: xmmintrin.h:535

Referenced by START_TEST(), Test_controlfp(), and Test_exceptions().

◆ set_native_fpcw()

void set_native_fpcw ( unsigned int  value)

Definition at line 36 of file fpcontrol.c.

37{
38#ifdef _M_AMD64
40#elif defined (_M_IX86)
41 unsigned short fpcw = (unsigned short)value;
42#if defined(_MSC_VER)
43 __asm fldcw[fpcw];
44#else
45 __asm__ __volatile__("fldcw %0" : : "m" (fpcw));
46#endif
47#else
48#error "Unsupported architecture"
49#endif
50}
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
Definition: pdh_main.c:94
void _mm_setcsr(unsigned int a)
Definition: xmmintrin.h:542

◆ START_TEST()

START_TEST ( fpcontrol  )

Definition at line 257 of file fpcontrol.c.

258{
259 unsigned int native_fpcw, fpcw, fpstatus;
260
261 /* Test native start fpcw */
262 native_fpcw = get_native_fpcw();
263 ok_hex(native_fpcw, ON_IX86(0) ON_AMD64(0x1f80) ON_ARM(0) );
264
265 /* Test start fpcw */
266 fpcw = _controlfp(0, 0);
267 ok_hex(fpcw, ON_IX86(0x9001f) ON_AMD64(0x8001f) ON_ARM(0));
268
269 /* Test start status */
270 fpstatus = _statusfp();
271 ok_hex(fpstatus, 0);
272
273 /* Test _fpreset */
274 fpcw = _controlfp(0, 0xffffffff);
275 ok_hex(fpcw, 0x80000);
276 _fpreset();
277 fpcw = _controlfp(0, 0);
278 ok_hex(fpcw, ON_IX86(0x9001f) ON_AMD64(0x8001f) ON_ARM(0));
279
281#if defined(_M_IX86) || defined(_M_AMD64)
282 Test_control87();
283#endif
285}
#define ok_hex(expression, result)
Definition: atltest.h:94
void Test_controlfp(void)
Definition: fpcontrol.c:107
#define ON_IX86(x)
Definition: fpcontrol.c:64
unsigned int get_native_fpcw(void)
Definition: fpcontrol.c:18
void Test_exceptions(void)
Definition: fpcontrol.c:179
#define ON_ARM(x)
Definition: fpcontrol.c:76
#define ON_AMD64(x)
Definition: fpcontrol.c:70
__MINGW_NOTHROW _CRTIMP unsigned int __cdecl _controlfp(_In_ unsigned int unNew, _In_ unsigned int unMask)
__MINGW_NOTHROW void __cdecl _fpreset(void)
Definition: _fpreset.c:10
__MINGW_NOTHROW _CRTIMP unsigned int __cdecl _statusfp(void)
Definition: _statusfp.c:11

◆ Test_controlfp()

void Test_controlfp ( void  )

Definition at line 107 of file fpcontrol.c.

108{
109 unsigned int i, native_fpcw, fpcw;
110
111 for (i = 0; i < _countof(g_controlfp_Testcases); i++)
112 {
114 ok(fpcw == g_controlfp_Testcases[i].Result, "[%u] _controlfp failed: expected 0x%x, got 0x%x\n", i, g_controlfp_Testcases[i].Result, fpcw);
115 native_fpcw = get_native_fpcw();
116 ok(native_fpcw == g_controlfp_Testcases[i].Native, "[%u] wrong native_fpcw: expected 0x%x, got 0x%x\n", i, g_controlfp_Testcases[i].Native, native_fpcw);
117 }
118
119 /* Restore sane state */
120 _fpreset();
121}
#define ok(value,...)
Definition: atltest.h:57
unsigned int Result
Definition: fpcontrol.c:83
unsigned int Mask
Definition: fpcontrol.c:82
struct @1600 g_controlfp_Testcases[]
unsigned int Native
Definition: fpcontrol.c:84
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define _countof(array)
Definition: sndvol32.h:70
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by START_TEST().

◆ Test_exceptions()

void Test_exceptions ( void  )

Definition at line 179 of file fpcontrol.c.

180{
181 volatile double a, b;
182 unsigned long long ull;
183 volatile long status = 0;
184
185 unsigned int i, exp_fpstatus, native_fpcw, statusfp;
186
187 for (i = 0; i < _countof(g_exception_Testcases); i++)
188 {
189 /* Start clean */
190 status = 0;
191 _fpreset();
192 _clearfp();
193 ok_hex(_statusfp(), 0);
194
196#if defined(_M_IX86) || defined(_M_AMD64) // || defined(_M_ARM64) ?
199#endif
200
202 {
204 {
205 case OP_Inexact:
206 a = 1e-40;
207 b = (float)(a + 1e-40);
208 break;
209 case OP_Underflow:
210 a = DBL_MIN;
211 b = a / 3.0e16;
212 break;
213 case OP_Overflow:
214 a = DBL_MAX;
215 b = a * 3.0;
216 break;
217 case OP_ZeroDivide:
218 a = 0.0;
219 b = 1.0 / a;
220 break;
221 case OP_Invalid:
222 ull = 0x7FF0000000000001ull;
223 a = *(double*)&ull;
224 b = a * 2;
225 break;
226 case OP_Denormal:
227 a = DBL_MIN;
228 b = a - 4.9406564584124654e-324;
229 break;
230 default:
231 (void)b;
232 }
233 native_fpcw = get_native_fpcw();
234 statusfp = _clearfp();
235 }
237 {
238#ifdef _M_IX86
239 /* On x86 we need to clear before doing any other fp operations, otherwise it will throw again */
240 statusfp = _clearfp();
241 native_fpcw = get_native_fpcw();
242#else
243 native_fpcw = get_native_fpcw();
244 statusfp = _clearfp();
245#endif
247 }
248 _SEH2_END;
249
250 exp_fpstatus = g_exception_Testcases[i].FpStatus;
251 ok(statusfp == exp_fpstatus, "[%u] Wrong value for _statusfp(). Expected 0x%lx, got 0x%lx\n", i, exp_fpstatus, statusfp);
252 ok(status == g_exception_Testcases[i].ExceptionCode, "[%u] Wrong value for status. Expected 0x%lx, got 0x%lx\n", i, g_exception_Testcases[i].ExceptionCode, status);
253 ok(native_fpcw == g_exception_Testcases[i].Native, "[%u] wrong native_fpcw: expected 0x%x, got 0x%x\n", i, g_exception_Testcases[i].Native, native_fpcw);
254 }
255}
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
FP_OP Operation
Definition: fpcontrol.c:150
struct @1601 g_exception_Testcases[]
unsigned int Fpcw
Definition: fpcontrol.c:151
unsigned int ExceptionCode
Definition: fpcontrol.c:153
#define DBL_MIN
Definition: gcc_float.h:125
#define DBL_MAX
Definition: gcc_float.h:108
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
__MINGW_NOTHROW _CRTIMP unsigned int __cdecl _clearfp(void)
Definition: _clearfp.c:11
#define e
Definition: ke_i.h:82
#define a
Definition: ke_i.h:78
#define b
Definition: ke_i.h:79
unsigned int __cdecl _control87(unsigned int, unsigned int)
Definition: _control87.c:16
static float(__cdecl *square_half_float)(float x
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
Definition: ps.c:97

Referenced by START_TEST().

Variable Documentation

◆ ExceptionCode

unsigned int ExceptionCode

Definition at line 153 of file fpcontrol.c.

Referenced by Test_exceptions().

◆ Fpcw

unsigned int Fpcw

Definition at line 151 of file fpcontrol.c.

Referenced by Test_exceptions().

◆ FpStatus

unsigned int FpStatus

Definition at line 152 of file fpcontrol.c.

◆ 

struct { ... } g_controlfp_Testcases[]
Initial value:
=
{
{ 0xffffffff, 0xffffffff, ON_IX86(0x30e031f) ON_AMD64(0x308031f) ON_ARM(0), ON_IX86(0) ON_AMD64(0xff80) ON_ARM(0) },
{ 0, 0xffffffff, 0x80000, ON_IX86(0) ON_AMD64(0x100) ON_ARM(0) },
{ 0xffffffff, 0x14, 0x80014, ON_IX86(0) ON_AMD64(0x580) ON_ARM(0) },
}
#define _IC_AFFINE
Definition: float.h:53
#define _DN_SAVE_OPERANDS_FLUSH_RESULTS
Definition: float.h:65
#define _RC_UP
Definition: float.h:56
#define _EM_UNDERFLOW
Definition: float.h:51
#define _EM_ZERODIVIDE
Definition: float.h:49
#define _EM_INEXACT
Definition: float.h:52
#define _EM_OVERFLOW
Definition: float.h:50
#define _DN_SAVE
Definition: float.h:62
#define _EM_INVALID
Definition: float.h:47
#define _DN_FLUSH
Definition: float.h:63
#define _IC_PROJECTIVE
Definition: float.h:54
#define _DN_FLUSH_OPERANDS_SAVE_RESULTS
Definition: float.h:64
#define _EM_DENORMAL
Definition: float.h:48
#define _RC_NEAR
Definition: float.h:58
#define _RC_DOWN
Definition: float.h:57
#define _RC_CHOP
Definition: float.h:55
#define _MM_MASK_INVALID
Definition: xmmintrin.h:102
#define _MM_MASK_DENORM
Definition: xmmintrin.h:103
#define _MM_ROUND_NEAREST
Definition: xmmintrin.h:110
#define _MM_ROUND_DOWN
Definition: xmmintrin.h:111
#define _MM_MASK_DIV_ZERO
Definition: xmmintrin.h:104
#define _MM_ROUND_UP
Definition: xmmintrin.h:112
#define _MM_ROUND_TOWARD_ZERO
Definition: xmmintrin.h:113
#define _MM_MASK_OVERFLOW
Definition: xmmintrin.h:105
#define _MM_MASK_INEXACT
Definition: xmmintrin.h:107
#define _MM_MASK_UNDERFLOW
Definition: xmmintrin.h:106
#define _MM_FLUSH_ZERO_ON
Definition: xmmintrin.h:116

Referenced by Test_controlfp().

◆ 

struct { ... } g_exception_Testcases[]
Initial value:
=
{
{ OP_Inexact, 0xffffffff, _SW_UNDERFLOW | _SW_INEXACT ON_IX86(| _SW_DENORMAL), 0, ON_IX86(0x32) ON_AMD64(0xffb0) ON_ARM(0)},
{ OP_Underflow, 0xffffffff, _SW_UNDERFLOW | _SW_INEXACT, 0, ON_IX86(0x30) ON_AMD64(0xffb0) ON_ARM(0)},
{ OP_Overflow, 0xffffffff, _SW_OVERFLOW | _SW_INEXACT, 0, ON_IX86(0x28) ON_AMD64(0xffa8) ON_ARM(0) },
{ OP_Overflow, ~_EM_OVERFLOW, _SW_OVERFLOW | _SW_INEXACT, STATUS_FLOAT_OVERFLOW, ON_IX86(0x3800) ON_AMD64(0xfba8) ON_ARM(0) },
{ OP_ZeroDivide, 0xffffffff, _SW_ZERODIVIDE, 0, ON_IX86(0x4) ON_AMD64(0xff84) ON_ARM(0) },
{ OP_ZeroDivide, ~_EM_ZERODIVIDE, _SW_ZERODIVIDE, STATUS_FLOAT_DIVIDE_BY_ZERO, ON_IX86(0x3000) ON_AMD64(0xfd84) ON_ARM(0) },
{ OP_Invalid, 0xffffffff, _SW_INVALID, 0, ON_IX86(0x1) ON_AMD64(0xff81) ON_ARM(0) },
}
#define _SW_INEXACT
Definition: float.h:85
#define _SW_OVERFLOW
Definition: float.h:87
#define _SW_DENORMAL
Definition: float.h:90
#define _SW_ZERODIVIDE
Definition: float.h:88
#define _SW_UNDERFLOW
Definition: float.h:86
#define _SW_INVALID
Definition: float.h:89
#define STATUS_FLOAT_UNDERFLOW
Definition: ntstatus.h:383
#define STATUS_FLOAT_OVERFLOW
Definition: ntstatus.h:381
#define STATUS_FLOAT_DIVIDE_BY_ZERO
Definition: ntstatus.h:378
#define STATUS_FLOAT_INVALID_OPERATION
Definition: ntstatus.h:380
#define STATUS_FLOAT_INEXACT_RESULT
Definition: ntstatus.h:379

Referenced by Test_exceptions().

◆ Mask

unsigned int Mask

Definition at line 82 of file fpcontrol.c.

Referenced by $include(), __ll_lshift(), __ll_rshift(), __ull_rshift(), _BitScanForward(), _BitScanReverse(), _CountLeadingZeros(), _CountTrailingZeros(), _HalpDismissIrqGeneric(), _HalpDismissIrqLevel(), AcpiExInsertIntoField(), AcpiExWriteWithUpdateRule(), AcpiRsDecodeBitmask(), AcpiRsEncodeBitmask(), addIPAddress(), BitScanForward(), BitScanForwardAffinity(), BitScanReverse(), BitScanReverseAffinity(), CallDibStretchBlt(), co_IntGetScrollInfo(), co_IntTranslateAccelerator(), ConsoleFirmwareTextSetState(), ConsoleGraphicalSetTextState(), ConsoleTextLocalSetTextState(), d3dcompiler_parse_signature(), doSymEnumSymbols(), doSymSearch(), DrvBitBlt(), EngStretchBlt(), EngStretchBltROP(), ExDupHandleTable(), GetBitValue(), HalEndSystemInterrupt2(), HalpDispatchInterrupt2(), HalpEndSoftwareInterrupt2(), HidParser_SignRange(), i8042MouHandleButtons(), IntGdiCreateMaskFromRLE(), KeFindConfigurationNextEntry(), KeStartThread(), KfLowerIrql(), KiNpxHandler(), KiRecordDr7(), LdrpSnapThunk(), MiniportHandleInterrupt(), NEWco_IntGetScrollInfo(), NewCtxInit(), NtGdiEngStretchBlt(), NtQueryDebugFilterState(), NtSetDebugFilterState(), NvNetApplyPacketFilter(), PciIsSuiteVersion(), PciSize(), RcvBufRegisterMask(), read_bitmap_patterns(), read_metadata_patterns(), RtlClearBits(), RtlSetBits(), SepPropagateAcl(), SetBitValue(), sym_enum(), SymEnumSourceFiles(), SymEnumSourceFilesW(), SymEnumSymbols(), SymEnumSymbolsW(), SymSearch(), SymSearchW(), test_componentinfo(), Test_controlfp(), test_FileContents1(), test_FileContents2(), test_FileDescriptor(), test_FileDescriptor_Folder(), test_pack_ACCESS_ALLOWED_ACE(), test_pack_ACCESS_DENIED_ACE(), test_pack_SYSTEM_ALARM_ACE(), test_pack_SYSTEM_AUDIT_ACE(), UDFBuildHashEntry(), UefiVideoOutputChar(), VCheckAcl__(), VGADDI_BltBrush(), VGADDI_BltMask(), VGADDI_BltPointerToVGA(), WTSWaitSystemEvent(), and XboxVideoOutputChar().

◆ Native

unsigned int Native

Definition at line 84 of file fpcontrol.c.

Referenced by PciSetResources(), Test_controlfp(), and Test_exceptions().

◆ Operation

◆ Result

unsigned int Result

Definition at line 83 of file fpcontrol.c.

Referenced by Test_controlfp().

◆ Value

Definition at line 81 of file fpcontrol.c.