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 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 30 #pragma weak __feclearexcept = feclearexcept 31 #pragma weak __feraiseexcept = feraiseexcept 32 #pragma weak __fetestexcept = fetestexcept 33 #pragma weak __fegetexceptflag = fegetexceptflag 34 #pragma weak __fesetexceptflag = fesetexceptflag 35 36 #pragma weak feclearexcept96 = feclearexcept 37 #pragma weak feraiseexcept96 = feraiseexcept 38 #pragma weak fetestexcept96 = fetestexcept 39 #pragma weak fegetexceptflag96 = fegetexceptflag 40 #pragma weak fesetexceptflag96 = fesetexceptflag 41 42 #include <fenv.h> 43 #include <sys/ieeefp.h> 44 #include <ucontext.h> 45 #include <thread.h> 46 #include "fex_handler.h" 47 #include "fenv_inlines.h" 48 49 50 int feclearexcept(int e) 51 { 52 unsigned long fsr; 53 54 __fenv_getfsr(&fsr); 55 __fenv_set_ex(fsr, __fenv_get_ex(fsr) & ~e); 56 __fenv_setfsr(&fsr); 57 if (fex_get_log()) 58 __fex_update_te(); 59 return 0; 60 } 61 62 /* 63 * note - __fex_hdlr depends on fetestexcept following feraiseexcept 64 */ 65 int feraiseexcept(int e) 66 { 67 volatile double t; 68 unsigned long fsr; 69 70 if (e & FE_INVALID) { 71 t = 0.0; 72 t /= 0.0; 73 } 74 if (e & FE_DIVBYZERO) { 75 t = 1.0e300; 76 t /= 0.0; 77 } 78 if (e & FE_OVERFLOW) { 79 /* if overflow is not trapped, avoid raising inexact */ 80 __fenv_getfsr(&fsr); 81 if (!(__fenv_get_te(fsr) & (1 << fp_trap_overflow))) { 82 __fenv_set_ex(fsr, __fenv_get_ex(fsr) | FE_OVERFLOW); 83 __fenv_setfsr(&fsr); 84 } 85 else { 86 t = 1.0e300; 87 t *= 1.0e300; 88 } 89 } 90 if (e & FE_UNDERFLOW) { 91 /* if underflow is not trapped, avoid raising inexact */ 92 __fenv_getfsr(&fsr); 93 if (!(__fenv_get_te(fsr) & (1 << fp_trap_underflow))) { 94 __fenv_set_ex(fsr, __fenv_get_ex(fsr) | FE_UNDERFLOW); 95 __fenv_setfsr(&fsr); 96 } 97 else { 98 t = 1.0e-307; 99 t -= 1.001e-307; 100 } 101 } 102 if (e & FE_INEXACT) { 103 t = 1.0e300; 104 t += 1.0e-307; 105 } 106 return 0; 107 } 108 109 int fetestexcept(int e) 110 { 111 unsigned long fsr; 112 113 __fenv_getfsr(&fsr); 114 return (int)__fenv_get_ex(fsr) & e; 115 } 116 117 int fegetexceptflag(fexcept_t *p, int e) 118 { 119 unsigned long fsr; 120 121 __fenv_getfsr(&fsr); 122 *p = (int)__fenv_get_ex(fsr) & e; 123 return 0; 124 } 125 126 int fesetexceptflag(const fexcept_t *p, int e) 127 { 128 unsigned long fsr; 129 130 __fenv_getfsr(&fsr); 131 __fenv_set_ex(fsr, (((int)__fenv_get_ex(fsr) & ~e) | (*p & e)) & 132 FE_ALL_EXCEPT); 133 __fenv_setfsr(&fsr); 134 if (fex_get_log()) 135 __fex_update_te(); 136 return 0; 137 }