Fixed x87 math precision (i386 build)

This commit is contained in:
tevador 2019-05-15 16:30:20 +02:00
parent 177d2e7c98
commit 2a04dfdd4f
2 changed files with 38 additions and 4 deletions

View File

@ -127,9 +127,7 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
void rx_reset_float_state() { void rx_reset_float_state() {
setRoundMode_(FE_TONEAREST); setRoundMode_(FE_TONEAREST);
#ifdef RANDOMX_USE_X87 rx_set_double_precision(); //set precision to 53 bits if needed by the platform
_control87(_PC_53, _MCW_PC); //set x87 precision to 53 bits
#endif
} }
void rx_set_rounding_mode(uint32_t mode) { void rx_set_rounding_mode(uint32_t mode) {
@ -153,6 +151,28 @@ void rx_set_rounding_mode(uint32_t mode) {
#endif #endif
#ifdef RANDOMX_USE_X87
#ifdef _M_IX86
void rx_set_double_precision() {
_control87(_PC_53, _MCW_PC);
}
#elif defined(__i386)
void rx_set_double_precision() {
uint16_t volatile x87cw;
asm volatile("fstcw %0" : "=m" (x87cw));
x87cw &= ~0x300;
x87cw |= 0x200;
asm volatile("fldcw %0" : : "m" (x87cw));
}
#endif
#endif //RANDOMX_USE_X87
union double_ser_t { union double_ser_t {
double f; double f;
uint64_t i; uint64_t i;

View File

@ -46,7 +46,8 @@ constexpr int RoundToZero = 3;
//the library "sqrt" function provided by MSVC for x86 targets doesn't give //the library "sqrt" function provided by MSVC for x86 targets doesn't give
//the correct results, so we have to use inline assembly to call x87 fsqrt directly //the correct results, so we have to use inline assembly to call x87 fsqrt directly
#if defined(_M_IX86) && !defined(__SSE2__) #if !defined(__SSE2__)
#if defined(_M_IX86)
inline double __cdecl rx_sqrt(double x) { inline double __cdecl rx_sqrt(double x) {
__asm { __asm {
fld x fld x
@ -54,13 +55,26 @@ inline double __cdecl rx_sqrt(double x) {
} }
} }
#define rx_sqrt rx_sqrt #define rx_sqrt rx_sqrt
void rx_set_double_precision();
#define RANDOMX_USE_X87 #define RANDOMX_USE_X87
#elif defined(__i386)
void rx_set_double_precision();
#define RANDOMX_USE_X87
#endif #endif
#endif //__SSE2__
#if !defined(rx_sqrt) #if !defined(rx_sqrt)
#define rx_sqrt sqrt #define rx_sqrt sqrt
#endif #endif
#if !defined(RANDOMX_USE_X87)
#define rx_set_double_precision
#endif
#ifdef __SSE2__ #ifdef __SSE2__
#ifdef __GNUC__ #ifdef __GNUC__
#include <x86intrin.h> #include <x86intrin.h>