/* * 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 */ #include #include #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; }