mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[CRT] Fix amd64 floating point control functions
This commit is contained in:
parent
39f11249ff
commit
76086220fa
10 changed files with 243 additions and 32 deletions
|
@ -59,6 +59,10 @@
|
|||
#define _PC_24 0x00020000
|
||||
#define _PC_53 0x00010000
|
||||
#define _PC_64 0x00000000
|
||||
#define _DN_SAVE 0x00000000
|
||||
#define _DN_FLUSH 0x01000000
|
||||
#define _DN_FLUSH_OPERANDS_SAVE_RESULTS 0x02000000
|
||||
#define _DN_SAVE_OPERANDS_FLUSH_RESULTS 0x03000000
|
||||
|
||||
/* These are also defined in Mingw math.h, needed to work around
|
||||
GCC build issues. */
|
||||
|
|
23
sdk/lib/crt/float/amd64/_clearfp.c
Normal file
23
sdk/lib/crt/float/amd64/_clearfp.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: x64 implementation of _clearfp
|
||||
* COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org>
|
||||
*/
|
||||
|
||||
#include <float.h>
|
||||
#include <xmmintrin.h>
|
||||
|
||||
unsigned int __cdecl _clearfp(void)
|
||||
{
|
||||
unsigned int retval;
|
||||
|
||||
/* Get current status value */
|
||||
retval = _statusfp();
|
||||
|
||||
/* Clear the exception mask */
|
||||
_mm_setcsr(_mm_getcsr() & ~_MM_EXCEPT_MASK);
|
||||
|
||||
/* Return the previous state */
|
||||
return retval;
|
||||
}
|
39
sdk/lib/crt/float/amd64/_control87.c
Normal file
39
sdk/lib/crt/float/amd64/_control87.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Implementation of _control87
|
||||
* COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org>
|
||||
*/
|
||||
|
||||
#include <xmmintrin.h>
|
||||
#include <float.h>
|
||||
|
||||
unsigned int _get_native_fpcw(void);
|
||||
void _set_native_fpcw(unsigned int value);
|
||||
unsigned int _fpcw_native_to_abstract(unsigned int native);
|
||||
unsigned int _fpcw_abstract_to_native(unsigned int abstract);
|
||||
|
||||
unsigned int __cdecl _control87(unsigned int newval, unsigned int mask)
|
||||
{
|
||||
unsigned int native, oldval, updated;
|
||||
|
||||
/* Sanatize the mask */
|
||||
mask &= _MCW_DN | _MCW_EM | _MCW_RC;
|
||||
|
||||
/* Get native control word */
|
||||
native = _get_native_fpcw();
|
||||
|
||||
/* Convert to abstract */
|
||||
oldval = _fpcw_native_to_abstract(native);
|
||||
|
||||
/* Update it according to the given parameters */
|
||||
updated = (oldval & ~mask) | (newval & mask);
|
||||
|
||||
/* Convert back to native */
|
||||
native = _fpcw_abstract_to_native(updated);
|
||||
|
||||
/* Set the native value */
|
||||
_set_native_fpcw(native);
|
||||
|
||||
return updated;
|
||||
}
|
13
sdk/lib/crt/float/amd64/_controlfp.c
Normal file
13
sdk/lib/crt/float/amd64/_controlfp.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: x64 implementation of _controlfp
|
||||
* COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org>
|
||||
*/
|
||||
|
||||
#include <float.h>
|
||||
|
||||
unsigned int __cdecl _controlfp(unsigned int newval, unsigned int mask)
|
||||
{
|
||||
return _control87(newval, mask & ~_EM_DENORMAL);
|
||||
}
|
14
sdk/lib/crt/float/amd64/_fpreset.c
Normal file
14
sdk/lib/crt/float/amd64/_fpreset.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: x64 implementation of _fpreset
|
||||
* COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org>
|
||||
*/
|
||||
|
||||
#include <xmmintrin.h>
|
||||
|
||||
void __cdecl _fpreset(void)
|
||||
{
|
||||
/* Mask everything */
|
||||
_mm_setcsr(_MM_MASK_MASK);
|
||||
}
|
33
sdk/lib/crt/float/amd64/_statusfp.c
Normal file
33
sdk/lib/crt/float/amd64/_statusfp.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: x64 implementation of _statusfp
|
||||
* COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org>
|
||||
*/
|
||||
|
||||
#include <float.h>
|
||||
#include <xmmintrin.h>
|
||||
|
||||
unsigned int __cdecl _statusfp(void)
|
||||
{
|
||||
unsigned int mxcsr, status = 0;
|
||||
|
||||
/* Get MXCSR */
|
||||
mxcsr = _mm_getcsr();
|
||||
|
||||
/* Convert to abstract status flags */
|
||||
if (mxcsr & _MM_EXCEPT_INVALID)
|
||||
status |= _SW_INVALID;
|
||||
if (mxcsr & _MM_EXCEPT_DENORM)
|
||||
status |= _SW_DENORMAL;
|
||||
if (mxcsr & _MM_EXCEPT_DIV_ZERO)
|
||||
status |= _SW_ZERODIVIDE;
|
||||
if (mxcsr & _MM_EXCEPT_OVERFLOW)
|
||||
status |= _SW_OVERFLOW;
|
||||
if (mxcsr & _MM_EXCEPT_UNDERFLOW)
|
||||
status |= _SW_UNDERFLOW;
|
||||
if (mxcsr & _MM_EXCEPT_INEXACT)
|
||||
status |= _SW_INEXACT;
|
||||
|
||||
return status;
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
|
||||
|
||||
#include <asm.inc>
|
||||
|
||||
.code64
|
||||
|
||||
PUBLIC _clearfp
|
||||
FUNC _clearfp
|
||||
.ENDPROLOG
|
||||
fnclex
|
||||
|
||||
ENDFUNC
|
||||
|
||||
END
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
#include <asm.inc>
|
||||
|
||||
.code64
|
||||
|
||||
PUBLIC _fpreset
|
||||
FUNC _fpreset
|
||||
.endprolog
|
||||
fninit
|
||||
ret
|
||||
ENDFUNC
|
||||
|
||||
END
|
111
sdk/lib/crt/float/amd64/machfpcw.c
Normal file
111
sdk/lib/crt/float/amd64/machfpcw.c
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* PROJECT: ReactOS CRT
|
||||
* LICENSE: MIT (https://spdx.org/licenses/MIT)
|
||||
* PURPOSE: Implementation of x64 floating point control word helper functions
|
||||
* COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org>
|
||||
*/
|
||||
|
||||
#include <float.h>
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#define _MM_DENORMALS_ARE_ZERO 0x0040
|
||||
|
||||
unsigned int _get_native_fpcw(void)
|
||||
{
|
||||
return _mm_getcsr();
|
||||
}
|
||||
|
||||
void _set_native_fpcw(unsigned int value)
|
||||
{
|
||||
_mm_setcsr(value);
|
||||
}
|
||||
|
||||
unsigned int _fpcw_native_to_abstract(unsigned int native)
|
||||
{
|
||||
unsigned int rounding_mask, abstract = 0;
|
||||
|
||||
/* Handle exception mask */
|
||||
if (native & _MM_MASK_INVALID)
|
||||
abstract |= _EM_INVALID;
|
||||
if (native & _MM_MASK_DENORM)
|
||||
abstract |= _EM_DENORMAL;
|
||||
if (native & _MM_MASK_DIV_ZERO)
|
||||
abstract |= _EM_ZERODIVIDE;
|
||||
if (native & _MM_MASK_OVERFLOW)
|
||||
abstract |= _EM_OVERFLOW;
|
||||
if (native & _MM_MASK_UNDERFLOW)
|
||||
abstract |= _EM_UNDERFLOW;
|
||||
if (native & _MM_MASK_INEXACT)
|
||||
abstract |= _EM_INEXACT;
|
||||
|
||||
/* Handle rounding mode */
|
||||
rounding_mask = (native & _MM_ROUND_MASK);
|
||||
if (rounding_mask == _MM_ROUND_DOWN)
|
||||
abstract |= _RC_DOWN;
|
||||
else if(rounding_mask == _MM_ROUND_UP)
|
||||
abstract |= _RC_UP;
|
||||
else if (rounding_mask == _MM_ROUND_TOWARD_ZERO)
|
||||
abstract |= _RC_CHOP;
|
||||
|
||||
/* Handle denormal control */
|
||||
if (native & _MM_DENORMALS_ARE_ZERO)
|
||||
{
|
||||
if (native & _MM_FLUSH_ZERO_MASK)
|
||||
abstract |= _DN_FLUSH;
|
||||
else
|
||||
abstract |= _DN_FLUSH_OPERANDS_SAVE_RESULTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (native & _MM_FLUSH_ZERO_MASK)
|
||||
abstract |= _DN_SAVE_OPERANDS_FLUSH_RESULTS;
|
||||
else
|
||||
abstract |= _DN_SAVE;
|
||||
}
|
||||
|
||||
return abstract;
|
||||
}
|
||||
|
||||
unsigned int _fpcw_abstract_to_native(unsigned int abstract)
|
||||
{
|
||||
unsigned int rounding_mask, native = 0;
|
||||
|
||||
/* Handle exception mask */
|
||||
if (abstract & _EM_INVALID)
|
||||
native |= _MM_MASK_INVALID;
|
||||
if (abstract & _EM_DENORMAL)
|
||||
native |= _MM_MASK_DENORM;
|
||||
if (abstract & _EM_ZERODIVIDE)
|
||||
native |= _MM_MASK_DIV_ZERO;
|
||||
if (abstract & _EM_OVERFLOW)
|
||||
native |= _MM_MASK_OVERFLOW;
|
||||
if (abstract & _EM_UNDERFLOW)
|
||||
native |= _MM_MASK_UNDERFLOW;
|
||||
if (abstract & _EM_INEXACT)
|
||||
native |= _MM_MASK_INEXACT;
|
||||
|
||||
/* Handle rounding mode */
|
||||
rounding_mask = (abstract & _MCW_RC);
|
||||
if (rounding_mask == _RC_DOWN)
|
||||
native |= _MM_ROUND_DOWN;
|
||||
else if (rounding_mask == _RC_UP)
|
||||
native |= _MM_ROUND_UP;
|
||||
else if (rounding_mask == _RC_CHOP)
|
||||
native |= _MM_ROUND_TOWARD_ZERO;
|
||||
|
||||
/* Handle Denormal Control */
|
||||
if ((abstract & _MCW_DN) == _DN_FLUSH)
|
||||
{
|
||||
native |= _MM_DENORMALS_ARE_ZERO | _MM_FLUSH_ZERO_MASK;
|
||||
}
|
||||
else if ((abstract & _MCW_DN) == _DN_FLUSH_OPERANDS_SAVE_RESULTS)
|
||||
{
|
||||
native |= _MM_DENORMALS_ARE_ZERO;
|
||||
}
|
||||
else if ((abstract & _MCW_DN) == _DN_SAVE_OPERANDS_FLUSH_RESULTS)
|
||||
{
|
||||
native |= _MM_FLUSH_ZERO_MASK;
|
||||
}
|
||||
|
||||
return native;
|
||||
}
|
|
@ -23,13 +23,15 @@ if(ARCH STREQUAL "i386")
|
|||
)
|
||||
elseif(ARCH STREQUAL "amd64")
|
||||
list(APPEND CRT_FLOAT_SOURCE
|
||||
float/i386/cntrlfp.c
|
||||
float/i386/statfp.c
|
||||
float/amd64/_clearfp.c
|
||||
float/amd64/_control87.c
|
||||
float/amd64/_controlfp.c
|
||||
float/amd64/_fpreset.c
|
||||
float/amd64/_statusfp.c
|
||||
float/amd64/machfpcw.c
|
||||
)
|
||||
list(APPEND CRT_FLOAT_ASM_SOURCE
|
||||
float/amd64/clearfp.S
|
||||
float/amd64/getsetfpcw.S
|
||||
float/amd64/fpreset.S
|
||||
float/amd64/logb.S
|
||||
)
|
||||
elseif(ARCH STREQUAL "arm")
|
||||
|
|
Loading…
Reference in a new issue