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_synonyms.h" 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 51 int 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 if (fex_get_log()) 59 __fex_update_te(); 60 return 0; 61 } 62 63 /* 64 * note - __fex_hdlr depends on fetestexcept following feraiseexcept 65 */ 66 int feraiseexcept(int e) 67 { 68 volatile double t; 69 unsigned long fsr; 70 71 if (e & FE_INVALID) { 72 t = 0.0; 73 t /= 0.0; 74 } 75 if (e & FE_DIVBYZERO) { 76 t = 1.0e300; 77 t /= 0.0; 78 } 79 if (e & FE_OVERFLOW) { 80 /* if overflow is not trapped, avoid raising inexact */ 81 __fenv_getfsr(&fsr); 82 if (!(__fenv_get_te(fsr) & (1 << fp_trap_overflow))) { 83 __fenv_set_ex(fsr, __fenv_get_ex(fsr) | FE_OVERFLOW); 84 __fenv_setfsr(&fsr); 85 } 86 else { 87 t = 1.0e300; 88 t *= 1.0e300; 89 } 90 } 91 if (e & FE_UNDERFLOW) { 92 /* if underflow is not trapped, avoid raising inexact */ 93 __fenv_getfsr(&fsr); 94 if (!(__fenv_get_te(fsr) & (1 << fp_trap_underflow))) { 95 __fenv_set_ex(fsr, __fenv_get_ex(fsr) | FE_UNDERFLOW); 96 __fenv_setfsr(&fsr); 97 } 98 else { 99 t = 1.0e-307; 100 t -= 1.001e-307; 101 } 102 } 103 if (e & FE_INEXACT) { 104 t = 1.0e300; 105 t += 1.0e-307; 106 } 107 return 0; 108 } 109 110 int fetestexcept(int e) 111 { 112 unsigned long fsr; 113 114 __fenv_getfsr(&fsr); 115 return (int)__fenv_get_ex(fsr) & e; 116 } 117 118 int fegetexceptflag(fexcept_t *p, int e) 119 { 120 unsigned long fsr; 121 122 __fenv_getfsr(&fsr); 123 *p = (int)__fenv_get_ex(fsr) & e; 124 return 0; 125 } 126 127 int fesetexceptflag(const fexcept_t *p, int e) 128 { 129 unsigned long fsr; 130 131 __fenv_getfsr(&fsr); 132 __fenv_set_ex(fsr, (((int)__fenv_get_ex(fsr) & ~e) | (*p & e)) & 133 FE_ALL_EXCEPT); 134 __fenv_setfsr(&fsr); 135 if (fex_get_log()) 136 __fex_update_te(); 137 return 0; 138 }