fenv-softfloat.h revision 302408
123660Speter/*- 250476Speter * Copyright (c) 2004-2011 David Schultz <das@FreeBSD.ORG> 31573Srgrimes * All rights reserved. 41573Srgrimes * 5262722Smarcel * Redistribution and use in source and binary forms, with or without 61573Srgrimes * modification, are permitted provided that the following conditions 734386Sjb * are met: 834386Sjb * 1. Redistributions of source code must retain the above copyright 9262722Smarcel * notice, this list of conditions and the following disclaimer. 1030448Sbde * 2. Redistributions in binary form must reproduce the above copyright 1134386Sjb * notice, this list of conditions and the following disclaimer in the 1234386Sjb * documentation and/or other materials provided with the distribution. 1334386Sjb * 1434386Sjb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1534386Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16262722Smarcel * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18237434Skib * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19237434Skib * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20237434Skib * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21237434Skib * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2234386Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23276630Skib * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24276630Skib * SUCH DAMAGE. 25276630Skib * 26276630Skib * $FreeBSD: stable/11/lib/msun/src/fenv-softfloat.h 261161 2014-01-25 16:03:08Z andrew $ 27277610Sjilles */ 28277610Sjilles 29277610Sjilles#ifndef _FENV_H_ 30277610Sjilles#error "This file is meant to be included only by <fenv.h>." 31302092Sbrooks#endif 32302092Sbrooks 33276630Skib/* 34276630Skib * This file implements the functionality of <fenv.h> on platforms that 35276630Skib * lack an FPU and use softfloat in libc for floating point. To use it, 36276630Skib * you must write an <fenv.h> that provides the following: 37276630Skib * 38276630Skib * - a typedef for fenv_t, which may be an integer or struct type 39276630Skib * - a typedef for fexcept_t (XXX This file assumes fexcept_t is a 40276630Skib * simple integer type containing the exception mask.) 41276630Skib * - definitions of FE_* constants for the five exceptions and four 42280818Skib * rounding modes in IEEE 754, as described in fenv(3) 43276630Skib * - a definition, and the corresponding external symbol, for FE_DFL_ENV 44276630Skib * - a macro __set_env(env, flags, mask, rnd), which sets the given fenv_t 45276630Skib * from the exception flags, mask, and rounding mode 46276630Skib * - macros __env_flags(env), __env_mask(env), and __env_round(env), which 47276630Skib * extract fields from an fenv_t 48281712Skib * - a definition of __fenv_static 49276630Skib * 50276630Skib * If the architecture supports an optional FPU, it's recommended that you 51276630Skib * define fenv_t and fexcept_t to match the hardware ABI. Otherwise, it 52276630Skib * doesn't matter how you define them. 53276630Skib */ 54276630Skib 55276630Skibextern int __softfloat_float_exception_flags; 56276630Skibextern int __softfloat_float_exception_mask; 57276630Skibextern int __softfloat_float_rounding_mode; 58276630Skibvoid __softfloat_float_raise(int); 59276630Skib 60276630Skib__fenv_static inline int 61276630Skibfeclearexcept(int __excepts) 62276630Skib{ 63276630Skib 64276630Skib __softfloat_float_exception_flags &= ~__excepts; 65281712Skib return (0); 66276630Skib} 67276630Skib 68276630Skib__fenv_static inline int 69278870Smariusfegetexceptflag(fexcept_t *__flagp, int __excepts) 70278870Smarius{ 71278870Smarius 72278870Smarius *__flagp = __softfloat_float_exception_flags & __excepts; 73278870Smarius return (0); 74278870Smarius} 75278870Smarius 76276630Skib__fenv_static inline int 77276630Skibfesetexceptflag(const fexcept_t *__flagp, int __excepts) 78276630Skib{ 79276630Skib 8034386Sjb __softfloat_float_exception_flags &= ~__excepts; 8134386Sjb __softfloat_float_exception_flags |= *__flagp & __excepts; 821573Srgrimes return (0); 8334386Sjb} 8434386Sjb 8571770Sdeischen__fenv_static inline int 8671770Sdeischenferaiseexcept(int __excepts) 8764106Speter{ 8834386Sjb 8934386Sjb __softfloat_float_raise(__excepts); 9034386Sjb return (0); 9134386Sjb} 9234386Sjb 9334386Sjb__fenv_static inline int 941573Srgrimesfetestexcept(int __excepts) 9525105Sbde{ 962366Sbde 9725105Sbde return (__softfloat_float_exception_flags & __excepts); 982366Sbde} 9971770Sdeischen 1001573Srgrimes__fenv_static inline int 101262722Smarcelfegetround(void) 102156613Sdeischen{ 10325736Speter 10471770Sdeischen return (__softfloat_float_rounding_mode); 10525736Speter} 106217850Skib 107288373Skib__fenv_static inline int 108217850Skibfesetround(int __round) 109217850Skib{ 110217850Skib 111217850Skib __softfloat_float_rounding_mode = __round; 112217850Skib return (0); 11325105Sbde} 114194910Sjhb 115194910Sjhb__fenv_static inline int 116217850Skibfegetenv(fenv_t *__envp) 1172366Sbde{ 11825105Sbde 119194910Sjhb __set_env(*__envp, __softfloat_float_exception_flags, 12071770Sdeischen __softfloat_float_exception_mask, __softfloat_float_rounding_mode); 121194910Sjhb return (0); 122217850Skib} 1232366Sbde 124246884Spjd__fenv_static inline int 125246884Spjdfeholdexcept(fenv_t *__envp) 126246884Spjd{ 127246884Spjd fenv_t __env; 128246884Spjd 129246884Spjd fegetenv(__envp); 130246884Spjd __softfloat_float_exception_flags = 0; 131259921Spluknet __softfloat_float_exception_mask = 0; 132251526Sglebius return (0); 133246884Spjd} 134246884Spjd 135246884Spjd__fenv_static inline int 136246884Spjdfesetenv(const fenv_t *__envp) 137246884Spjd{ 138246884Spjd 139247667Spjd __softfloat_float_exception_flags = __env_flags(*__envp); 140246884Spjd __softfloat_float_exception_mask = __env_mask(*__envp); 141246884Spjd __softfloat_float_rounding_mode = __env_round(*__envp); 142247602Spjd return (0); 143247602Spjd} 144247602Spjd 145246884Spjd__fenv_static inline int 146246884Spjdfeupdateenv(const fenv_t *__envp) 147246884Spjd{ 148246884Spjd int __oflags = __softfloat_float_exception_flags; 149246884Spjd 150246884Spjd fesetenv(__envp); 151246884Spjd feraiseexcept(__oflags); 152246884Spjd return (0); 153246884Spjd} 154247667Spjd 155246884Spjd#if __BSD_VISIBLE 156246884Spjd 157246884Spjd/* We currently provide no external definitions of the functions below. */ 158246884Spjd 159246884Spjd__fenv_static inline int 160246884Spjdfeenableexcept(int __mask) 161246884Spjd{ 162246884Spjd int __omask = __softfloat_float_exception_mask; 163246884Spjd 164246884Spjd __softfloat_float_exception_mask |= __mask; 165246884Spjd return (__omask); 166246884Spjd} 167246884Spjd 168246884Spjd__fenv_static inline int 169246884Spjdfedisableexcept(int __mask) 170246884Spjd{ 171246884Spjd int __omask = __softfloat_float_exception_mask; 172246884Spjd 173246884Spjd __softfloat_float_exception_mask &= ~__mask; 174246884Spjd return (__omask); 175246884Spjd} 176246884Spjd 177246884Spjd__fenv_static inline int 178246884Spjdfegetexcept(void) 179246884Spjd{ 180246884Spjd 181246884Spjd return (__softfloat_float_exception_mask); 182246884Spjd} 183246884Spjd 184246884Spjd#endif /* __BSD_VISIBLE */ 185246884Spjd