1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved. 24 */ 25 26 /* 27 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #pragma weak __feclearexcept = feclearexcept 32 #pragma weak __feraiseexcept = feraiseexcept 33 #pragma weak __fetestexcept = fetestexcept 34 #pragma weak __fegetexceptflag = fegetexceptflag 35 #pragma weak __fesetexceptflag = fesetexceptflag 36 37 #pragma weak feclearexcept96 = feclearexcept 38 #pragma weak feraiseexcept96 = feraiseexcept 39 #pragma weak fetestexcept96 = fetestexcept 40 #pragma weak fegetexceptflag96 = fegetexceptflag 41 #pragma weak fesetexceptflag96 = fesetexceptflag 42 43 #include <fenv.h> 44 #include <sys/ieeefp.h> 45 #include <ucontext.h> 46 #include <thread.h> 47 #include "fex_handler.h" 48 #include "fenv_inlines.h" 49 50 int 51 feclearexcept(int e) 52 { 53 unsigned long fsr; 54 55 __fenv_getfsr(&fsr); 56 __fenv_set_ex(fsr, __fenv_get_ex(fsr) & ~e); 57 __fenv_setfsr(&fsr); 58 59 if (fex_get_log()) 60 __fex_update_te(); 61 62 return (0); 63 } 64 65 /* 66 * note - __fex_hdlr depends on fetestexcept following feraiseexcept 67 */ 68 int 69 feraiseexcept(int e) 70 { 71 volatile double t; 72 unsigned long fsr; 73 74 if (e & FE_INVALID) { 75 t = 0.0; 76 t /= 0.0; 77 } 78 79 if (e & FE_DIVBYZERO) { 80 t = 1.0e300; 81 t /= 0.0; 82 } 83 84 if (e & FE_OVERFLOW) { 85 /* if overflow is not trapped, avoid raising inexact */ 86 __fenv_getfsr(&fsr); 87 88 if (!(__fenv_get_te(fsr) & (1 << fp_trap_overflow))) { 89 __fenv_set_ex(fsr, __fenv_get_ex(fsr) | FE_OVERFLOW); 90 __fenv_setfsr(&fsr); 91 } else { 92 t = 1.0e300; 93 t *= 1.0e300; 94 } 95 } 96 97 if (e & FE_UNDERFLOW) { 98 /* if underflow is not trapped, avoid raising inexact */ 99 __fenv_getfsr(&fsr); 100 101 if (!(__fenv_get_te(fsr) & (1 << fp_trap_underflow))) { 102 __fenv_set_ex(fsr, __fenv_get_ex(fsr) | FE_UNDERFLOW); 103 __fenv_setfsr(&fsr); 104 } else { 105 t = 1.0e-307; 106 t -= 1.001e-307; 107 } 108 } 109 110 if (e & FE_INEXACT) { 111 t = 1.0e300; 112 t += 1.0e-307; 113 } 114 115 return (0); 116 } 117 118 int 119 fetestexcept(int e) 120 { 121 unsigned long fsr; 122 123 __fenv_getfsr(&fsr); 124 return ((int)__fenv_get_ex(fsr) & e); 125 } 126 127 int 128 fegetexceptflag(fexcept_t *p, int e) 129 { 130 unsigned long fsr; 131 132 __fenv_getfsr(&fsr); 133 *p = (int)__fenv_get_ex(fsr) & e; 134 return (0); 135 } 136 137 int 138 fesetexceptflag(const fexcept_t *p, int e) 139 { 140 unsigned long fsr; 141 142 __fenv_getfsr(&fsr); 143 __fenv_set_ex(fsr, (((int)__fenv_get_ex(fsr) & ~e) | (*p & e)) & 144 FE_ALL_EXCEPT); 145 __fenv_setfsr(&fsr); 146 147 if (fex_get_log()) 148 __fex_update_te(); 149 150 return (0); 151 }