1 /* Copyright (C) 1997-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 __fesetenv(const fenv_t * envp)23__fesetenv (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 31 _FPU_GETCW (fpcr); 32 33 if ((envp != FE_DFL_ENV) && (envp != FE_NOMASK_ENV)) 34 { 35 /* The new FPCR/FPSR are valid, so don't merge the reserved flags. */ 36 fpcr_new = envp->__fpcr; 37 38 if (fpcr != fpcr_new) 39 _FPU_SETCW (fpcr_new); 40 41 _FPU_SETFPSR (envp->__fpsr); 42 return 0; 43 } 44 45 _FPU_GETFPSR (fpsr); 46 fpcr_new = fpcr & _FPU_RESERVED; 47 fpsr_new = fpsr & _FPU_FPSR_RESERVED; 48 49 if (envp == FE_DFL_ENV) 50 { 51 fpcr_new |= _FPU_DEFAULT; 52 fpsr_new |= _FPU_FPSR_DEFAULT; 53 } 54 else 55 { 56 fpcr_new |= _FPU_FPCR_IEEE; 57 fpsr_new |= _FPU_FPSR_IEEE; 58 } 59 60 _FPU_SETFPSR (fpsr_new); 61 62 if (fpcr != fpcr_new) 63 { 64 _FPU_SETCW (fpcr_new); 65 66 /* Trapping exceptions are optional in AArch64; the relevant enable 67 bits in FPCR are RES0 hence the absence of support can be detected 68 by reading back the FPCR and comparing with the required value. */ 69 _FPU_GETCW (updated_fpcr); 70 71 return fpcr_new & ~updated_fpcr; 72 } 73 74 return 0; 75 } 76 libm_hidden_def (__fesetenv) 77 weak_alias (__fesetenv, fesetenv) 78 libm_hidden_weak (fesetenv) 79