1726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman/*- 2726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> 3726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * All rights reserved. 4726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * 5726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * Redistribution and use in source and binary forms, with or without 6726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * modification, are permitted provided that the following conditions 7726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * are met: 8726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * 1. Redistributions of source code must retain the above copyright 9726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * notice, this list of conditions and the following disclaimer. 10726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * 2. Redistributions in binary form must reproduce the above copyright 11726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * notice, this list of conditions and the following disclaimer in the 12726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * documentation and/or other materials provided with the distribution. 13726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * 14726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * SUCH DAMAGE. 25726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * 26726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * $FreeBSD: src/lib/msun/mips/fenv.c,v 1.1 2008/04/26 12:20:29 imp Exp $ 27726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman */ 28726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman 29726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman#include <fenv.h> 30726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman 3189d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes#define FCSR_CAUSE_SHIFT 10 3289d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes#define FCSR_ENABLE_SHIFT 5 3389d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes#define FCSR_ENABLE_MASK (FE_ALL_EXCEPT << FCSR_ENABLE_SHIFT) 3489d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes 3589d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes#define FCSR_RMASK 0x3 3689d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes 37726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman/* 38726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * Hopefully the system ID byte is immutable, so it's valid to use 39726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman * this as a default environment. 40726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearman */ 41726800e8f42f25a1bf7a36b1603ded29266e8ac6Chris Dearmanconst fenv_t __fe_dfl_env = 0; 422d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 432d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint fegetenv(fenv_t* __envp) { 442d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fenv_t _fcsr = 0; 452d367905a2e1b950f79b408141eea07c222b590bCalin Juravle#ifdef __mips_hard_float 462d367905a2e1b950f79b408141eea07c222b590bCalin Juravle __asm__ __volatile__("cfc1 %0,$31" : "=r" (_fcsr)); 472d367905a2e1b950f79b408141eea07c222b590bCalin Juravle#endif 482d367905a2e1b950f79b408141eea07c222b590bCalin Juravle *__envp = _fcsr; 492d367905a2e1b950f79b408141eea07c222b590bCalin Juravle return 0; 502d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 512d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 522d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint fesetenv(const fenv_t* __envp) { 532d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fenv_t _fcsr = *__envp; 542d367905a2e1b950f79b408141eea07c222b590bCalin Juravle#ifdef __mips_hard_float 552d367905a2e1b950f79b408141eea07c222b590bCalin Juravle __asm__ __volatile__("ctc1 %0,$31" : : "r" (_fcsr)); 562d367905a2e1b950f79b408141eea07c222b590bCalin Juravle#endif 572d367905a2e1b950f79b408141eea07c222b590bCalin Juravle return 0; 582d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 592d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 602d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint feclearexcept(int __excepts) { 612d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fexcept_t __fcsr; 622d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fegetenv(&__fcsr); 632d367905a2e1b950f79b408141eea07c222b590bCalin Juravle __excepts &= FE_ALL_EXCEPT; 6489d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes __fcsr &= ~(__excepts | (__excepts << FCSR_CAUSE_SHIFT)); 652d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fesetenv(&__fcsr); 662d367905a2e1b950f79b408141eea07c222b590bCalin Juravle return 0; 672d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 682d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 692d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint fegetexceptflag(fexcept_t* __flagp, int __excepts) { 702d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fexcept_t __fcsr; 712d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fegetenv(&__fcsr); 722d367905a2e1b950f79b408141eea07c222b590bCalin Juravle *__flagp = __fcsr & __excepts & FE_ALL_EXCEPT; 732d367905a2e1b950f79b408141eea07c222b590bCalin Juravle return 0; 742d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 752d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 762d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint fesetexceptflag(const fexcept_t* __flagp, int __excepts) { 772d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fexcept_t __fcsr; 782d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fegetenv(&__fcsr); 792d367905a2e1b950f79b408141eea07c222b590bCalin Juravle /* Ensure that flags are all legal */ 802d367905a2e1b950f79b408141eea07c222b590bCalin Juravle __excepts &= FE_ALL_EXCEPT; 812d367905a2e1b950f79b408141eea07c222b590bCalin Juravle __fcsr &= ~__excepts; 822d367905a2e1b950f79b408141eea07c222b590bCalin Juravle __fcsr |= *__flagp & __excepts; 832d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fesetenv(&__fcsr); 842d367905a2e1b950f79b408141eea07c222b590bCalin Juravle return 0; 852d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 862d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 872d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint feraiseexcept(int __excepts) { 882d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fexcept_t __fcsr; 892d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fegetenv(&__fcsr); 902d367905a2e1b950f79b408141eea07c222b590bCalin Juravle /* Ensure that flags are all legal */ 912d367905a2e1b950f79b408141eea07c222b590bCalin Juravle __excepts &= FE_ALL_EXCEPT; 922d367905a2e1b950f79b408141eea07c222b590bCalin Juravle /* Cause bit needs to be set as well for generating the exception*/ 9389d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes __fcsr |= __excepts | (__excepts << FCSR_CAUSE_SHIFT); 942d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fesetenv(&__fcsr); 952d367905a2e1b950f79b408141eea07c222b590bCalin Juravle return 0; 962d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 972d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 982d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint fetestexcept(int __excepts) { 992d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fexcept_t __FCSR; 1002d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fegetenv(&__FCSR); 1012d367905a2e1b950f79b408141eea07c222b590bCalin Juravle return (__FCSR & __excepts & FE_ALL_EXCEPT); 1022d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 1032d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 1042d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint fegetround(void) { 1052d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fenv_t _fcsr; 1062d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fegetenv(&_fcsr); 10789d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes return (_fcsr & FCSR_RMASK); 1082d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 1092d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 1102d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint fesetround(int __round) { 1112d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fenv_t _fcsr; 1122d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fegetenv(&_fcsr); 11389d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes _fcsr &= ~FCSR_RMASK; 11489d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes _fcsr |= (__round & FCSR_RMASK); 1152d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fesetenv(&_fcsr); 1162d367905a2e1b950f79b408141eea07c222b590bCalin Juravle return 0; 1172d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 1182d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 1192d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint feholdexcept(fenv_t* __envp) { 1202d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fenv_t __env; 1212d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fegetenv(&__env); 1222d367905a2e1b950f79b408141eea07c222b590bCalin Juravle *__envp = __env; 12389d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes __env &= ~(FE_ALL_EXCEPT | FCSR_ENABLE_MASK); 1242d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fesetenv(&__env); 1252d367905a2e1b950f79b408141eea07c222b590bCalin Juravle return 0; 1262d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 1272d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 1282d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint feupdateenv(const fenv_t* __envp) { 1292d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fexcept_t __fcsr; 1302d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fegetenv(&__fcsr); 1312d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fesetenv(__envp); 1322d367905a2e1b950f79b408141eea07c222b590bCalin Juravle feraiseexcept(__fcsr & FE_ALL_EXCEPT); 1332d367905a2e1b950f79b408141eea07c222b590bCalin Juravle return 0; 1342d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 1352d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 1362d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint feenableexcept(int __mask) { 1372d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fenv_t __old_fcsr, __new_fcsr; 1382d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fegetenv(&__old_fcsr); 13989d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes __new_fcsr = __old_fcsr | (__mask & FE_ALL_EXCEPT) << FCSR_ENABLE_SHIFT; 1402d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fesetenv(&__new_fcsr); 14189d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes return ((__old_fcsr >> FCSR_ENABLE_SHIFT) & FE_ALL_EXCEPT); 1422d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 1432d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 1442d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint fedisableexcept(int __mask) { 1452d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fenv_t __old_fcsr, __new_fcsr; 1462d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fegetenv(&__old_fcsr); 14789d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes __new_fcsr = __old_fcsr & ~((__mask & FE_ALL_EXCEPT) << FCSR_ENABLE_SHIFT); 1482d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fesetenv(&__new_fcsr); 14989d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes return ((__old_fcsr >> FCSR_ENABLE_SHIFT) & FE_ALL_EXCEPT); 1502d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 1512d367905a2e1b950f79b408141eea07c222b590bCalin Juravle 1522d367905a2e1b950f79b408141eea07c222b590bCalin Juravleint fegetexcept(void) { 1532d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fenv_t __fcsr; 1542d367905a2e1b950f79b408141eea07c222b590bCalin Juravle fegetenv(&__fcsr); 15589d61243f2f05748c0198b3c0e4766c2df2f4434Elliott Hughes return ((__fcsr & FCSR_ENABLE_MASK) >> FCSR_ENABLE_SHIFT); 1562d367905a2e1b950f79b408141eea07c222b590bCalin Juravle} 157