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 extern int __mingw_has_sse (void); 10 #endif /* !(defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__)) */ 11 12 /* 7.6.2.4 13 The fesetexceptflag function sets the complete status for those 14 exception flags indicated by the argument excepts, according to the 15 representation in the object pointed to by flagp. The value of 16 *flagp shall have been set by a previous call to fegetexceptflag 17 whose second argument represented at least those exceptions 18 represented by the argument excepts. This function does not raise 19 exceptions, but only sets the state of the flags. */ 20 fesetexceptflag(const fexcept_t * flagp,int excepts)21int fesetexceptflag (const fexcept_t * flagp, int excepts) 22 { 23 fenv_t _env; 24 25 excepts &= FE_ALL_EXCEPT; 26 27 #if defined(_ARM_) || defined(__arm__) 28 __asm__ volatile ("fmrx %0, FPSCR" : "=r" (_env)); 29 _env.__cw &= ~excepts; 30 _env.__cw |= (*flagp & excepts); 31 __asm__ volatile ("fmxr FPSCR, %0" : : "r" (_env)); 32 #elif defined(_ARM64_) || defined(__aarch64__) 33 unsigned __int64 fpcr; 34 (void) _env; 35 __asm__ volatile ("mrs %0, fpcr" : "=r" (fpcr)); 36 fpcr &= ~excepts; 37 fpcr |= (*flagp & excepts); 38 __asm__ volatile ("msr fpcr, %0" : : "r" (fpcr)); 39 #else 40 __asm__ volatile ("fnstenv %0;" : "=m" (_env)); 41 _env.__status_word &= ~excepts; 42 _env.__status_word |= (*flagp & excepts); 43 __asm__ volatile ("fldenv %0;" : : "m" (_env)); 44 45 if (__mingw_has_sse ()) 46 { 47 int sse_cw; 48 __asm__ volatile ("stmxcsr %0;" : "=m" (sse_cw)); 49 sse_cw &= ~(excepts << 7); 50 sse_cw |= ((*flagp & excepts) << 7); 51 __asm__ volatile ("ldmxcsr %0" : : "m" (sse_cw)); 52 } 53 54 #endif /* defined(_ARM_) || defined(__arm__) || defined(_ARM64_) || defined(__aarch64__) */ 55 return 0; 56 } 57