1 /** 2 * This file has no copyright assigned and is placed in the Public Domain. 3 * This file is part of the mingw-w64 runtime package. 4 * No warranty is given; refer to the file DISCLAIMER.PD within this package. 5 */ 6 #include <fenv.h> 7 8 #if !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) 9 int __mingw_has_sse (void); 10 #endif /* !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) */ 11 12 /* 7.6.3.2 13 The fesetround function establishes the rounding direction 14 represented by its argument round. If the argument is not equal 15 to the value of a rounding direction macro, the rounding direction 16 is not changed. */ 17 fesetround(int mode)18int fesetround (int mode) 19 { 20 #if defined(_ARM_) || defined(__arm__) 21 fenv_t _env; 22 if ((mode & ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)) != 0) 23 return -1; 24 __asm__ volatile ("fmrx %0, FPSCR" : "=r" (_env)); 25 _env.__cw &= ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO); 26 _env.__cw |= mode; 27 __asm__ volatile ("fmxr FPSCR, %0" : : "r" (_env)); 28 #elif defined(_ARM64_) || defined(__aarch64__) 29 unsigned __int64 fpcr; 30 if ((mode & ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)) != 0) 31 return -1; 32 __asm__ volatile ("mrs %0, fpcr" : "=r" (fpcr)); 33 fpcr &= ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO); 34 fpcr |= mode; 35 __asm__ volatile ("msr fpcr, %0" : : "r" (fpcr)); 36 #else 37 unsigned short _cw; 38 if ((mode & ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)) 39 != 0) 40 return -1; 41 __asm__ volatile ("fnstcw %0;": "=m" (*&_cw)); 42 _cw &= ~0xc00; 43 _cw |= mode; 44 __asm__ volatile ("fldcw %0;" : : "m" (*&_cw)); 45 46 if (__mingw_has_sse ()) 47 { 48 int mxcsr; 49 50 __asm__ volatile ("stmxcsr %0" : "=m" (*&mxcsr)); 51 mxcsr &= ~0x6000; 52 mxcsr |= mode << 3; 53 __asm__ volatile ("ldmxcsr %0" : : "m" (*&mxcsr)); 54 } 55 #endif /* defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) */ 56 return 0; 57 } 58