125c28e83SPiotr Jasiukajtis /* 225c28e83SPiotr Jasiukajtis * CDDL HEADER START 325c28e83SPiotr Jasiukajtis * 425c28e83SPiotr Jasiukajtis * The contents of this file are subject to the terms of the 525c28e83SPiotr Jasiukajtis * Common Development and Distribution License (the "License"). 625c28e83SPiotr Jasiukajtis * You may not use this file except in compliance with the License. 725c28e83SPiotr Jasiukajtis * 825c28e83SPiotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 925c28e83SPiotr Jasiukajtis * or http://www.opensolaris.org/os/licensing. 1025c28e83SPiotr Jasiukajtis * See the License for the specific language governing permissions 1125c28e83SPiotr Jasiukajtis * and limitations under the License. 1225c28e83SPiotr Jasiukajtis * 1325c28e83SPiotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each 1425c28e83SPiotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1525c28e83SPiotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the 1625c28e83SPiotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying 1725c28e83SPiotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner] 1825c28e83SPiotr Jasiukajtis * 1925c28e83SPiotr Jasiukajtis * CDDL HEADER END 2025c28e83SPiotr Jasiukajtis */ 2125c28e83SPiotr Jasiukajtis 2225c28e83SPiotr Jasiukajtis /* 2325c28e83SPiotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 2425c28e83SPiotr Jasiukajtis */ 2525c28e83SPiotr Jasiukajtis /* 2625c28e83SPiotr Jasiukajtis * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 2725c28e83SPiotr Jasiukajtis * Use is subject to license terms. 2825c28e83SPiotr Jasiukajtis */ 2925c28e83SPiotr Jasiukajtis 30*ddc0e0b5SRichard Lowe #pragma weak __feclearexcept = feclearexcept 31*ddc0e0b5SRichard Lowe #pragma weak __feraiseexcept = feraiseexcept 32*ddc0e0b5SRichard Lowe #pragma weak __fetestexcept = fetestexcept 33*ddc0e0b5SRichard Lowe #pragma weak __fegetexceptflag = fegetexceptflag 34*ddc0e0b5SRichard Lowe #pragma weak __fesetexceptflag = fesetexceptflag 3525c28e83SPiotr Jasiukajtis 36*ddc0e0b5SRichard Lowe #pragma weak feclearexcept96 = feclearexcept 37*ddc0e0b5SRichard Lowe #pragma weak feraiseexcept96 = feraiseexcept 38*ddc0e0b5SRichard Lowe #pragma weak fetestexcept96 = fetestexcept 39*ddc0e0b5SRichard Lowe #pragma weak fegetexceptflag96 = fegetexceptflag 40*ddc0e0b5SRichard Lowe #pragma weak fesetexceptflag96 = fesetexceptflag 4125c28e83SPiotr Jasiukajtis 4225c28e83SPiotr Jasiukajtis #include <fenv.h> 4325c28e83SPiotr Jasiukajtis #include <sys/ieeefp.h> 4425c28e83SPiotr Jasiukajtis #include <ucontext.h> 4525c28e83SPiotr Jasiukajtis #include <thread.h> 4625c28e83SPiotr Jasiukajtis #include "fex_handler.h" 4725c28e83SPiotr Jasiukajtis #include "fenv_inlines.h" 4825c28e83SPiotr Jasiukajtis 4925c28e83SPiotr Jasiukajtis 5025c28e83SPiotr Jasiukajtis int feclearexcept(int e) 5125c28e83SPiotr Jasiukajtis { 5225c28e83SPiotr Jasiukajtis unsigned long fsr; 5325c28e83SPiotr Jasiukajtis 5425c28e83SPiotr Jasiukajtis __fenv_getfsr(&fsr); 5525c28e83SPiotr Jasiukajtis __fenv_set_ex(fsr, __fenv_get_ex(fsr) & ~e); 5625c28e83SPiotr Jasiukajtis __fenv_setfsr(&fsr); 5725c28e83SPiotr Jasiukajtis if (fex_get_log()) 5825c28e83SPiotr Jasiukajtis __fex_update_te(); 5925c28e83SPiotr Jasiukajtis return 0; 6025c28e83SPiotr Jasiukajtis } 6125c28e83SPiotr Jasiukajtis 6225c28e83SPiotr Jasiukajtis /* 6325c28e83SPiotr Jasiukajtis * note - __fex_hdlr depends on fetestexcept following feraiseexcept 6425c28e83SPiotr Jasiukajtis */ 6525c28e83SPiotr Jasiukajtis int feraiseexcept(int e) 6625c28e83SPiotr Jasiukajtis { 6725c28e83SPiotr Jasiukajtis volatile double t; 6825c28e83SPiotr Jasiukajtis unsigned long fsr; 6925c28e83SPiotr Jasiukajtis 7025c28e83SPiotr Jasiukajtis if (e & FE_INVALID) { 7125c28e83SPiotr Jasiukajtis t = 0.0; 7225c28e83SPiotr Jasiukajtis t /= 0.0; 7325c28e83SPiotr Jasiukajtis } 7425c28e83SPiotr Jasiukajtis if (e & FE_DIVBYZERO) { 7525c28e83SPiotr Jasiukajtis t = 1.0e300; 7625c28e83SPiotr Jasiukajtis t /= 0.0; 7725c28e83SPiotr Jasiukajtis } 7825c28e83SPiotr Jasiukajtis if (e & FE_OVERFLOW) { 7925c28e83SPiotr Jasiukajtis /* if overflow is not trapped, avoid raising inexact */ 8025c28e83SPiotr Jasiukajtis __fenv_getfsr(&fsr); 8125c28e83SPiotr Jasiukajtis if (!(__fenv_get_te(fsr) & (1 << fp_trap_overflow))) { 8225c28e83SPiotr Jasiukajtis __fenv_set_ex(fsr, __fenv_get_ex(fsr) | FE_OVERFLOW); 8325c28e83SPiotr Jasiukajtis __fenv_setfsr(&fsr); 8425c28e83SPiotr Jasiukajtis } 8525c28e83SPiotr Jasiukajtis else { 8625c28e83SPiotr Jasiukajtis t = 1.0e300; 8725c28e83SPiotr Jasiukajtis t *= 1.0e300; 8825c28e83SPiotr Jasiukajtis } 8925c28e83SPiotr Jasiukajtis } 9025c28e83SPiotr Jasiukajtis if (e & FE_UNDERFLOW) { 9125c28e83SPiotr Jasiukajtis /* if underflow is not trapped, avoid raising inexact */ 9225c28e83SPiotr Jasiukajtis __fenv_getfsr(&fsr); 9325c28e83SPiotr Jasiukajtis if (!(__fenv_get_te(fsr) & (1 << fp_trap_underflow))) { 9425c28e83SPiotr Jasiukajtis __fenv_set_ex(fsr, __fenv_get_ex(fsr) | FE_UNDERFLOW); 9525c28e83SPiotr Jasiukajtis __fenv_setfsr(&fsr); 9625c28e83SPiotr Jasiukajtis } 9725c28e83SPiotr Jasiukajtis else { 9825c28e83SPiotr Jasiukajtis t = 1.0e-307; 9925c28e83SPiotr Jasiukajtis t -= 1.001e-307; 10025c28e83SPiotr Jasiukajtis } 10125c28e83SPiotr Jasiukajtis } 10225c28e83SPiotr Jasiukajtis if (e & FE_INEXACT) { 10325c28e83SPiotr Jasiukajtis t = 1.0e300; 10425c28e83SPiotr Jasiukajtis t += 1.0e-307; 10525c28e83SPiotr Jasiukajtis } 10625c28e83SPiotr Jasiukajtis return 0; 10725c28e83SPiotr Jasiukajtis } 10825c28e83SPiotr Jasiukajtis 10925c28e83SPiotr Jasiukajtis int fetestexcept(int e) 11025c28e83SPiotr Jasiukajtis { 11125c28e83SPiotr Jasiukajtis unsigned long fsr; 11225c28e83SPiotr Jasiukajtis 11325c28e83SPiotr Jasiukajtis __fenv_getfsr(&fsr); 11425c28e83SPiotr Jasiukajtis return (int)__fenv_get_ex(fsr) & e; 11525c28e83SPiotr Jasiukajtis } 11625c28e83SPiotr Jasiukajtis 11725c28e83SPiotr Jasiukajtis int fegetexceptflag(fexcept_t *p, int e) 11825c28e83SPiotr Jasiukajtis { 11925c28e83SPiotr Jasiukajtis unsigned long fsr; 12025c28e83SPiotr Jasiukajtis 12125c28e83SPiotr Jasiukajtis __fenv_getfsr(&fsr); 12225c28e83SPiotr Jasiukajtis *p = (int)__fenv_get_ex(fsr) & e; 12325c28e83SPiotr Jasiukajtis return 0; 12425c28e83SPiotr Jasiukajtis } 12525c28e83SPiotr Jasiukajtis 12625c28e83SPiotr Jasiukajtis int fesetexceptflag(const fexcept_t *p, int e) 12725c28e83SPiotr Jasiukajtis { 12825c28e83SPiotr Jasiukajtis unsigned long fsr; 12925c28e83SPiotr Jasiukajtis 13025c28e83SPiotr Jasiukajtis __fenv_getfsr(&fsr); 13125c28e83SPiotr Jasiukajtis __fenv_set_ex(fsr, (((int)__fenv_get_ex(fsr) & ~e) | (*p & e)) & 13225c28e83SPiotr Jasiukajtis FE_ALL_EXCEPT); 13325c28e83SPiotr Jasiukajtis __fenv_setfsr(&fsr); 13425c28e83SPiotr Jasiukajtis if (fex_get_log()) 13525c28e83SPiotr Jasiukajtis __fex_update_te(); 13625c28e83SPiotr Jasiukajtis return 0; 13725c28e83SPiotr Jasiukajtis } 138