1 /* Install given floating-point environment and raise exceptions. 2 Copyright (C) 1997-2022 Free Software Foundation, Inc. 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 7 License as published by the Free Software Foundation; either 8 version 2.1 of the 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 #include <arm-features.h> 22 23 24 int __feupdateenv(const fenv_t * envp)25__feupdateenv (const fenv_t *envp) 26 { 27 fpu_control_t fpscr, new_fpscr, updated_fpscr; 28 int excepts; 29 30 /* Fail if a VFP unit isn't present. */ 31 if (!ARM_HAVE_VFP) 32 return 1; 33 34 _FPU_GETCW (fpscr); 35 excepts = fpscr & FE_ALL_EXCEPT; 36 37 if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV)) 38 { 39 /* Merge current exception flags with the saved fenv. */ 40 new_fpscr = envp->__cw | excepts; 41 42 /* Write new FPSCR if different (ignoring NZCV flags). */ 43 if (((fpscr ^ new_fpscr) & ~_FPU_MASK_NZCV) != 0) 44 _FPU_SETCW (new_fpscr); 45 46 /* Raise the exceptions if enabled in the new FP state. */ 47 if (excepts & (new_fpscr >> FE_EXCEPT_SHIFT)) 48 return __feraiseexcept (excepts); 49 50 return 0; 51 } 52 53 /* Preserve the reserved FPSCR flags. */ 54 new_fpscr = fpscr & (_FPU_RESERVED | FE_ALL_EXCEPT); 55 new_fpscr |= (envp == FE_DFL_ENV) ? _FPU_DEFAULT : _FPU_IEEE; 56 57 if (((new_fpscr ^ fpscr) & ~_FPU_MASK_NZCV) != 0) 58 { 59 _FPU_SETCW (new_fpscr); 60 61 /* Not all VFP architectures support trapping exceptions, so 62 test whether the relevant bits were set and fail if not. */ 63 _FPU_GETCW (updated_fpscr); 64 65 if (new_fpscr & ~updated_fpscr) 66 return 1; 67 } 68 69 /* Raise the exceptions if enabled in the new FP state. */ 70 if (excepts & (new_fpscr >> FE_EXCEPT_SHIFT)) 71 return __feraiseexcept (excepts); 72 73 return 0; 74 } 75 libm_hidden_def (__feupdateenv) 76 weak_alias (__feupdateenv, feupdateenv) 77 libm_hidden_weak (feupdateenv) 78