1 /* Copyright (C) 2009-2021 Free Software Foundation, Inc. 2 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public License as 7 published by the Free Software Foundation; either version 2.1 of the 8 License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 #include <fenv.h> 20 #include <fpu_control.h> 21 22 int __feupdateenv(const fenv_t * envp)23__feupdateenv (const fenv_t *envp) 24 { 25 fpu_control_t fpcr; 26 fpu_control_t fpcr_new; 27 fpu_control_t updated_fpcr; 28 fpu_fpsr_t fpsr; 29 fpu_fpsr_t fpsr_new; 30 int excepts; 31 32 _FPU_GETCW (fpcr); 33 _FPU_GETFPSR (fpsr); 34 excepts = fpsr & FE_ALL_EXCEPT; 35 36 if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV)) 37 { 38 fpcr_new = envp->__fpcr; 39 fpsr_new = envp->__fpsr | excepts; 40 41 if (fpcr != fpcr_new) 42 _FPU_SETCW (fpcr_new); 43 44 if (fpsr != fpsr_new) 45 _FPU_SETFPSR (fpsr_new); 46 47 if (excepts & (fpcr_new >> FE_EXCEPT_SHIFT)) 48 return __feraiseexcept (excepts); 49 50 return 0; 51 } 52 53 fpcr_new = fpcr & _FPU_RESERVED; 54 fpsr_new = fpsr & (_FPU_FPSR_RESERVED | FE_ALL_EXCEPT); 55 56 if (envp == FE_DFL_ENV) 57 { 58 fpcr_new |= _FPU_DEFAULT; 59 fpsr_new |= _FPU_FPSR_DEFAULT; 60 } 61 else 62 { 63 fpcr_new |= _FPU_FPCR_IEEE; 64 fpsr_new |= _FPU_FPSR_IEEE; 65 } 66 67 _FPU_SETFPSR (fpsr_new); 68 69 if (fpcr != fpcr_new) 70 { 71 _FPU_SETCW (fpcr_new); 72 73 /* Trapping exceptions are optional in AArch64; the relevant enable 74 bits in FPCR are RES0 hence the absence of support can be detected 75 by reading back the FPCR and comparing with the required value. */ 76 _FPU_GETCW (updated_fpcr); 77 78 if (fpcr_new & ~updated_fpcr) 79 return 1; 80 } 81 82 if (excepts & (fpcr_new >> FE_EXCEPT_SHIFT)) 83 return __feraiseexcept (excepts); 84 85 return 0; 86 } 87 libm_hidden_def (__feupdateenv) 88 weak_alias (__feupdateenv, feupdateenv) 89 libm_hidden_weak (feupdateenv) 90