Back to index

glibc  2.9
fesetenv.c
Go to the documentation of this file.
00001 /* Install given floating-point environment.
00002    Copyright (C) 1997,98,99,2000,01,02 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <fenv.h>
00022 #include <assert.h>
00023 #include <bp-sym.h>
00024 
00025 
00026 int
00027 __fesetenv (const fenv_t *envp)
00028 {
00029   fenv_t temp;
00030 
00031   /* The memory block used by fstenv/fldenv has a size of 28 bytes.  */
00032   assert (sizeof (fenv_t) == 28);
00033 
00034   /* Install the environment specified by ENVP.  But there are a few
00035      values which we do not want to come from the saved environment.
00036      Therefore, we get the current environment and replace the values
00037      we want to use from the environment specified by the parameter.  */
00038   __asm__ ("fnstenv %0" : "=m" (*&temp));
00039 
00040   if (envp == FE_DFL_ENV)
00041     {
00042       temp.__control_word |= FE_ALL_EXCEPT;
00043       temp.__control_word &= ~FE_TOWARDZERO;
00044       temp.__status_word &= ~FE_ALL_EXCEPT;
00045       temp.__eip = 0;
00046       temp.__cs_selector = 0;
00047       temp.__opcode = 0;
00048       temp.__data_offset = 0;
00049       temp.__data_selector = 0;
00050     }
00051   else if (envp == FE_NOMASK_ENV)
00052     {
00053       temp.__control_word &= ~(FE_ALL_EXCEPT | FE_TOWARDZERO);
00054       temp.__status_word &= ~FE_ALL_EXCEPT;
00055       temp.__eip = 0;
00056       temp.__cs_selector = 0;
00057       temp.__opcode = 0;
00058       temp.__data_offset = 0;
00059       temp.__data_selector = 0;
00060     }
00061   else
00062     {
00063       temp.__control_word &= ~(FE_ALL_EXCEPT | FE_TOWARDZERO);
00064       temp.__control_word |= (envp->__control_word
00065                            & (FE_ALL_EXCEPT | FE_TOWARDZERO));
00066       temp.__status_word &= ~FE_ALL_EXCEPT;
00067       temp.__status_word |= envp->__status_word & FE_ALL_EXCEPT;
00068       temp.__eip = envp->__eip;
00069       temp.__cs_selector = envp->__cs_selector;
00070       temp.__opcode = envp->__opcode;
00071       temp.__data_offset = envp->__data_offset;
00072       temp.__data_selector = envp->__data_selector;
00073     }
00074 
00075   __asm__ ("fldenv %0" : : "m" (temp));
00076 
00077   /* Success.  */
00078   return 0;
00079 }
00080 
00081 #include <shlib-compat.h>
00082 #if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
00083 strong_alias (__fesetenv, __old_fesetenv)
00084 compat_symbol (libm, BP_SYM (__old_fesetenv), BP_SYM (fesetenv), GLIBC_2_1);
00085 #endif
00086 
00087 libm_hidden_ver (__fesetenv, fesetenv)
00088 versioned_symbol (libm, BP_SYM (__fesetenv), BP_SYM (fesetenv), GLIBC_2_2);