Reactos

[CRT] Fix amd64 floating point control functions

+243 -32
+4
sdk/include/crt/float.h
··· 59 59 #define _PC_24 0x00020000 60 60 #define _PC_53 0x00010000 61 61 #define _PC_64 0x00000000 62 + #define _DN_SAVE 0x00000000 63 + #define _DN_FLUSH 0x01000000 64 + #define _DN_FLUSH_OPERANDS_SAVE_RESULTS 0x02000000 65 + #define _DN_SAVE_OPERANDS_FLUSH_RESULTS 0x03000000 62 66 63 67 /* These are also defined in Mingw math.h, needed to work around 64 68 GCC build issues. */
+23
sdk/lib/crt/float/amd64/_clearfp.c
··· 1 + /* 2 + * PROJECT: ReactOS CRT 3 + * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 + * PURPOSE: x64 implementation of _clearfp 5 + * COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org> 6 + */ 7 + 8 + #include <float.h> 9 + #include <xmmintrin.h> 10 + 11 + unsigned int __cdecl _clearfp(void) 12 + { 13 + unsigned int retval; 14 + 15 + /* Get current status value */ 16 + retval = _statusfp(); 17 + 18 + /* Clear the exception mask */ 19 + _mm_setcsr(_mm_getcsr() & ~_MM_EXCEPT_MASK); 20 + 21 + /* Return the previous state */ 22 + return retval; 23 + }
+39
sdk/lib/crt/float/amd64/_control87.c
··· 1 + /* 2 + * PROJECT: ReactOS CRT 3 + * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 + * PURPOSE: Implementation of _control87 5 + * COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org> 6 + */ 7 + 8 + #include <xmmintrin.h> 9 + #include <float.h> 10 + 11 + unsigned int _get_native_fpcw(void); 12 + void _set_native_fpcw(unsigned int value); 13 + unsigned int _fpcw_native_to_abstract(unsigned int native); 14 + unsigned int _fpcw_abstract_to_native(unsigned int abstract); 15 + 16 + unsigned int __cdecl _control87(unsigned int newval, unsigned int mask) 17 + { 18 + unsigned int native, oldval, updated; 19 + 20 + /* Sanatize the mask */ 21 + mask &= _MCW_DN | _MCW_EM | _MCW_RC; 22 + 23 + /* Get native control word */ 24 + native = _get_native_fpcw(); 25 + 26 + /* Convert to abstract */ 27 + oldval = _fpcw_native_to_abstract(native); 28 + 29 + /* Update it according to the given parameters */ 30 + updated = (oldval & ~mask) | (newval & mask); 31 + 32 + /* Convert back to native */ 33 + native = _fpcw_abstract_to_native(updated); 34 + 35 + /* Set the native value */ 36 + _set_native_fpcw(native); 37 + 38 + return updated; 39 + }
+13
sdk/lib/crt/float/amd64/_controlfp.c
··· 1 + /* 2 + * PROJECT: ReactOS CRT 3 + * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 + * PURPOSE: x64 implementation of _controlfp 5 + * COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org> 6 + */ 7 + 8 + #include <float.h> 9 + 10 + unsigned int __cdecl _controlfp(unsigned int newval, unsigned int mask) 11 + { 12 + return _control87(newval, mask & ~_EM_DENORMAL); 13 + }
+14
sdk/lib/crt/float/amd64/_fpreset.c
··· 1 + /* 2 + * PROJECT: ReactOS CRT 3 + * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 + * PURPOSE: x64 implementation of _fpreset 5 + * COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org> 6 + */ 7 + 8 + #include <xmmintrin.h> 9 + 10 + void __cdecl _fpreset(void) 11 + { 12 + /* Mask everything */ 13 + _mm_setcsr(_MM_MASK_MASK); 14 + }
+33
sdk/lib/crt/float/amd64/_statusfp.c
··· 1 + /* 2 + * PROJECT: ReactOS CRT 3 + * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 + * PURPOSE: x64 implementation of _statusfp 5 + * COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org> 6 + */ 7 + 8 + #include <float.h> 9 + #include <xmmintrin.h> 10 + 11 + unsigned int __cdecl _statusfp(void) 12 + { 13 + unsigned int mxcsr, status = 0; 14 + 15 + /* Get MXCSR */ 16 + mxcsr = _mm_getcsr(); 17 + 18 + /* Convert to abstract status flags */ 19 + if (mxcsr & _MM_EXCEPT_INVALID) 20 + status |= _SW_INVALID; 21 + if (mxcsr & _MM_EXCEPT_DENORM) 22 + status |= _SW_DENORMAL; 23 + if (mxcsr & _MM_EXCEPT_DIV_ZERO) 24 + status |= _SW_ZERODIVIDE; 25 + if (mxcsr & _MM_EXCEPT_OVERFLOW) 26 + status |= _SW_OVERFLOW; 27 + if (mxcsr & _MM_EXCEPT_UNDERFLOW) 28 + status |= _SW_UNDERFLOW; 29 + if (mxcsr & _MM_EXCEPT_INEXACT) 30 + status |= _SW_INEXACT; 31 + 32 + return status; 33 + }
-15
sdk/lib/crt/float/amd64/clearfp.S
··· 1 - 2 - 3 - 4 - #include <asm.inc> 5 - 6 - .code64 7 - 8 - PUBLIC _clearfp 9 - FUNC _clearfp 10 - .ENDPROLOG 11 - fnclex 12 - 13 - ENDFUNC 14 - 15 - END
-13
sdk/lib/crt/float/amd64/fpreset.S
··· 1 - 2 - #include <asm.inc> 3 - 4 - .code64 5 - 6 - PUBLIC _fpreset 7 - FUNC _fpreset 8 - .endprolog 9 - fninit 10 - ret 11 - ENDFUNC 12 - 13 - END
+111
sdk/lib/crt/float/amd64/machfpcw.c
··· 1 + /* 2 + * PROJECT: ReactOS CRT 3 + * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 + * PURPOSE: Implementation of x64 floating point control word helper functions 5 + * COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org> 6 + */ 7 + 8 + #include <float.h> 9 + #include <xmmintrin.h> 10 + 11 + #define _MM_DENORMALS_ARE_ZERO 0x0040 12 + 13 + unsigned int _get_native_fpcw(void) 14 + { 15 + return _mm_getcsr(); 16 + } 17 + 18 + void _set_native_fpcw(unsigned int value) 19 + { 20 + _mm_setcsr(value); 21 + } 22 + 23 + unsigned int _fpcw_native_to_abstract(unsigned int native) 24 + { 25 + unsigned int rounding_mask, abstract = 0; 26 + 27 + /* Handle exception mask */ 28 + if (native & _MM_MASK_INVALID) 29 + abstract |= _EM_INVALID; 30 + if (native & _MM_MASK_DENORM) 31 + abstract |= _EM_DENORMAL; 32 + if (native & _MM_MASK_DIV_ZERO) 33 + abstract |= _EM_ZERODIVIDE; 34 + if (native & _MM_MASK_OVERFLOW) 35 + abstract |= _EM_OVERFLOW; 36 + if (native & _MM_MASK_UNDERFLOW) 37 + abstract |= _EM_UNDERFLOW; 38 + if (native & _MM_MASK_INEXACT) 39 + abstract |= _EM_INEXACT; 40 + 41 + /* Handle rounding mode */ 42 + rounding_mask = (native & _MM_ROUND_MASK); 43 + if (rounding_mask == _MM_ROUND_DOWN) 44 + abstract |= _RC_DOWN; 45 + else if(rounding_mask == _MM_ROUND_UP) 46 + abstract |= _RC_UP; 47 + else if (rounding_mask == _MM_ROUND_TOWARD_ZERO) 48 + abstract |= _RC_CHOP; 49 + 50 + /* Handle denormal control */ 51 + if (native & _MM_DENORMALS_ARE_ZERO) 52 + { 53 + if (native & _MM_FLUSH_ZERO_MASK) 54 + abstract |= _DN_FLUSH; 55 + else 56 + abstract |= _DN_FLUSH_OPERANDS_SAVE_RESULTS; 57 + } 58 + else 59 + { 60 + if (native & _MM_FLUSH_ZERO_MASK) 61 + abstract |= _DN_SAVE_OPERANDS_FLUSH_RESULTS; 62 + else 63 + abstract |= _DN_SAVE; 64 + } 65 + 66 + return abstract; 67 + } 68 + 69 + unsigned int _fpcw_abstract_to_native(unsigned int abstract) 70 + { 71 + unsigned int rounding_mask, native = 0; 72 + 73 + /* Handle exception mask */ 74 + if (abstract & _EM_INVALID) 75 + native |= _MM_MASK_INVALID; 76 + if (abstract & _EM_DENORMAL) 77 + native |= _MM_MASK_DENORM; 78 + if (abstract & _EM_ZERODIVIDE) 79 + native |= _MM_MASK_DIV_ZERO; 80 + if (abstract & _EM_OVERFLOW) 81 + native |= _MM_MASK_OVERFLOW; 82 + if (abstract & _EM_UNDERFLOW) 83 + native |= _MM_MASK_UNDERFLOW; 84 + if (abstract & _EM_INEXACT) 85 + native |= _MM_MASK_INEXACT; 86 + 87 + /* Handle rounding mode */ 88 + rounding_mask = (abstract & _MCW_RC); 89 + if (rounding_mask == _RC_DOWN) 90 + native |= _MM_ROUND_DOWN; 91 + else if (rounding_mask == _RC_UP) 92 + native |= _MM_ROUND_UP; 93 + else if (rounding_mask == _RC_CHOP) 94 + native |= _MM_ROUND_TOWARD_ZERO; 95 + 96 + /* Handle Denormal Control */ 97 + if ((abstract & _MCW_DN) == _DN_FLUSH) 98 + { 99 + native |= _MM_DENORMALS_ARE_ZERO | _MM_FLUSH_ZERO_MASK; 100 + } 101 + else if ((abstract & _MCW_DN) == _DN_FLUSH_OPERANDS_SAVE_RESULTS) 102 + { 103 + native |= _MM_DENORMALS_ARE_ZERO; 104 + } 105 + else if ((abstract & _MCW_DN) == _DN_SAVE_OPERANDS_FLUSH_RESULTS) 106 + { 107 + native |= _MM_FLUSH_ZERO_MASK; 108 + } 109 + 110 + return native; 111 + }
+6 -4
sdk/lib/crt/float/float.cmake
··· 23 23 ) 24 24 elseif(ARCH STREQUAL "amd64") 25 25 list(APPEND CRT_FLOAT_SOURCE 26 - float/i386/cntrlfp.c 27 - float/i386/statfp.c 26 + float/amd64/_clearfp.c 27 + float/amd64/_control87.c 28 + float/amd64/_controlfp.c 29 + float/amd64/_fpreset.c 30 + float/amd64/_statusfp.c 31 + float/amd64/machfpcw.c 28 32 ) 29 33 list(APPEND CRT_FLOAT_ASM_SOURCE 30 - float/amd64/clearfp.S 31 34 float/amd64/getsetfpcw.S 32 - float/amd64/fpreset.S 33 35 float/amd64/logb.S 34 36 ) 35 37 elseif(ARCH STREQUAL "arm")