25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * CDDL HEADER START
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * The contents of this file are subject to the terms of the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Common Development and Distribution License (the "License").
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * You may not use this file except in compliance with the License.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * or http://www.opensolaris.org/os/licensing.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * See the License for the specific language governing permissions
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * and limitations under the License.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner]
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * CDDL HEADER END
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * Use is subject to license terms.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis#if defined(__sparc) && !defined(__sparcv9)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* 2.x signal.h doesn't declare sigemptyset or sigismember
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if they're #defined (see sys/signal.h) */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisextern int sigismember(const sigset_t *, int);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* external globals */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisvoid (*__mt_fex_sync)() = NULL; /* for synchronization with libmtsk */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisvoid (*__libm_mt_fex_sync)() = NULL; /* new, improved version of above */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* private variables */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisstatic mutex_t handlers_key_lock = DEFAULTMUTEX;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtisstatic struct sigaction oact = { 0, SIG_DFL };
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis/* private const data */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* Return the traps to be enabled given the current handling modes
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis__fex_te_needed(struct fex_handler_data *thr_handlers, unsigned long fsr)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* set traps for handling modes */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis for (i = 0; i < FEX_NUM_EXC; i++)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (thr_handlers[i].__mode != FEX_NONSTOP)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* add traps for retrospective diagnostics */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* The following function synchronizes with libmtsk (SPARC only, for now)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis__fex_sync_with_libmtsk(int begin, int master)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* The following function may be used for synchronization with any
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* internal project that manages multiple threads
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis__fex_sync_with_threads(enum __libm_mt_fex_sync_actions action,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* clear traps, making all accrued flags visible in status word */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* Code for setting or clearing interval mode on US-III and above.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* This is embedded as data so we don't have to mark the library
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* as a v8plusb/v9b object. (I could have just used one entry and
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* modified the second word to set the bits I want, but that would
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* have required another mutex.)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis { 0x81c3e008, 0x81b01020 }, /* retl, siam 0 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis { 0x81c3e008, 0x81b01024 }, /* retl, siam 4 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis { 0x81c3e008, 0x81b01025 }, /* retl, siam 5 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis { 0x81c3e008, 0x81b01026 }, /* retl, siam 6 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis { 0x81c3e008, 0x81b01027 } /* retl, siam 7 */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* If a handling mode is in effect, apply it; otherwise invoke the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* saved handler
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis__fex_hdlr(int sig, siginfo_t *sip, ucontext_t *uap)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* determine which exception occurred */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((int)(e = __fex_get_invalid_type(sip, uap)) < 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* not an IEEE exception */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* get the handling mode */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis handler = oact.sa_handler; /* for log; just looking, no need to lock */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (thr_handlers && thr_handlers[(int)e].__mode != FEX_NOHANDLER) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* make an entry in the log of retro. diag. if need be */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis i = ((int)uap->uc_mcontext.fpregs.fpu_fsr >> 5) & 0x1f;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis __fex_mklog(uap, (char *)sip->si_addr, i, e, mode, (void *)handler);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* handle the exception based on the mode */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* custom or nonstop mode; disable traps and clear flags */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* if interval mode was set, clear it, then substitute the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis interval rounding direction and clear ns mode in the fsr */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (uap->uc_mcontext.xrs.xrs_id == XRS_ID)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis gsr = (*(unsigned long long*)((prxregset_t*)uap->uc_mcontext.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis fsr = (fsr & ~0xc0400000ul) | ((gsr & 3) << 30);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* decode the operation */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* if a custom mode handler is installed, invoke it */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* if we got here from feraiseexcept, pass dummy info */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (addr >= (unsigned long)feraiseexcept &&
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info.op1.type = info.op2.type = info.res.type =
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* restore interval mode if it was set, and put the original
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis rounding direction and ns mode back in the fsr */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* restore modes in case the user's handler changed them */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* stuff the result */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* "or" in any exception flags and update traps */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* revert to the saved handler (if any) */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case (unsigned long)SIG_DFL:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* simulate trap with no handler installed */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case (unsigned long)SIG_IGN:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* If a handling mode is in effect, apply it; otherwise invoke the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* saved handler
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis__fex_hdlr(int sig, siginfo_t *sip, ucontext_t *uap)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis void (*handler)() = NULL, (*simd_handler[4])();
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis int mode, simd_mode[4], i, len, accrued, *ap;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis unsigned int cwsw, oldcwsw, mxcsr, oldmxcsr;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* check for an exception caused by an SSE instruction */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (!(uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.status & 0x80)) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* disable all traps and clear flags */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis __fex_get_simd_op(uap, &inst, simd_e, simd_info);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis addr = (unsigned long)uap->uc_mcontext.gregs[REG_PC];
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis accrued = uap->uc_mcontext.fpregs.fp_reg_set.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis for (i = 0; i < 4; i++) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((int)simd_e[i] < 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis accrued |= uap->uc_mcontext.fpregs.fp_reg_set.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis for (i = 0; i < 4; i++) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((int)simd_e[i] < 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis for (i = 0; i < 4; i++) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((int)simd_e[i] < 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis __fex_st_simd_result(uap, &inst, simd_e, simd_info);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis for (i = 0; i < 4; i++) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((int)simd_e[i] < 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* set MMX mode */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((int)e < 0) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (thr_handlers && thr_handlers[(int)e].__mode !=
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis addr = (unsigned long)uap->uc_mcontext.gregs[REG_PC];
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis accrued = uap->uc_mcontext.fpregs.fp_reg_set.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis accrued |= uap->uc_mcontext.fpregs.fp_reg_set.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis __fex_mklog(uap, (char *)addr, accrued, e, mode,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (addr >= (unsigned long)feraiseexcept &&
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis __fex_st_sse_result(uap, &inst, e, &info);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * In 64-bit mode, the 32-bit convert-to-integer
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * instructions zero the upper 32 bits of the
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * destination. (We do this here and not in
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * __fex_st_sse_result because __fex_st_sse_result
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis * can be called from __fex_st_simd_result, too.)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (inst.op == cvtss2si || inst.op == cvttss2si ||
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis inst.op == cvtsd2si || inst.op == cvttsd2si)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* advance the pc past the SSE instruction */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* determine which exception occurred */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if ((int)(e = __fex_get_invalid_type(sip, uap)) < 0)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* not an IEEE exception */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* get the handling mode */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis handler = oact.sa_handler; /* for log; just looking, no need to lock */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (thr_handlers && thr_handlers[(int)e].__mode != FEX_NOHANDLER) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* make an entry in the log of retro. diag. if need be */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis addr = (unsigned long)uap->uc_mcontext.fpregs.fp_reg_set.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis addr = (unsigned long)uap->uc_mcontext.fpregs.fp_reg_set.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis accrued = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.status &
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis accrued |= uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis __fex_mklog(uap, (char *)addr, accrued, e, mode, (void *)handler);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* handle the exception based on the mode */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* disable all traps and clear flags */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* decode the operation */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* if a custom mode handler is installed, invoke it */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* if we got here from feraiseexcept, pass dummy info */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (addr >= (unsigned long)feraiseexcept &&
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis info.op1.type = info.op2.type = info.res.type =
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* restore modes in case the user's handler changed them */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* stuff the result */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis i = __fex_te_needed(thr_handlers, accrued);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw &= ~0x3d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw |= (accrued & ~i);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.cw |= 0x3d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.cw &= ~i;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[1] &= ~0x3d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[1] |=
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[0] |= 0x3d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[0] &= ~i;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.mxcsr &= ~0x3d;
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.mxcsr |=
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.mxcsr &=
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* revert to the saved handler (if any) */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case (unsigned long)SIG_DFL:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* simulate trap with no handler installed */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis case (unsigned long)SIG_IGN:
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* Return a pointer to the thread-specific handler data, and
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* initialize it if necessary
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* initialize to FEX_NOHANDLER if trap is enabled,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis FEX_NONSTOP if trap is disabled */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis for (i = 0; i < FEX_NUM_EXC; i++)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis ((te & te_bit[i])? FEX_NOHANDLER : FEX_NONSTOP);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (thr_getspecific(handlers_key, (void **)&ptr) != 0 &&
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis thr_keycreate(&handlers_key, free) != 0) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (thr_setspecific(handlers_key, (void *)ptr) != 0) {
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* initialize to FEX_NOHANDLER if trap is enabled,
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis FEX_NONSTOP if trap is disabled */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis for (i = 0; i < FEX_NUM_EXC; i++)
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis ptr[i].__mode = ((te & te_bit[i])? FEX_NOHANDLER : FEX_NONSTOP);
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis* Update the trap enable bits according to the selected modes
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* determine which traps are needed */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* install __fex_hdlr as necessary */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* set the new trap enable bits (only if SIGFPE is not blocked) */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis if (sigprocmask(0, NULL, &blocked) == 0 &&
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* synchronize with libmtsk */
25c28e83beb90e7c80452a7c818c5e6f73a07dc8Piotr Jasiukajtis /* synchronize with other projects */