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 fex_merge_flags = __fex_merge_flags
  31 
  32 #pragma weak feholdexcept = __feholdexcept
  33 #pragma weak feupdateenv = __feupdateenv
  34 #pragma weak fegetenv = __fegetenv
  35 #pragma weak fesetenv = __fesetenv
  36 
  37 #pragma weak feholdexcept96 = __feholdexcept96
  38 #pragma weak feupdateenv96 = __feupdateenv
  39 #pragma weak fegetenv96 = __fegetenv
  40 #pragma weak fesetenv96 = __fesetenv
  41 
  42 #include "fenv_synonyms.h"
  43 #include <fenv.h>
  44 #include <ucontext.h>
  45 #include <thread.h>
  46 #include "fex_handler.h"
  47 #include "fenv_inlines.h"
  48 
  49 const fenv_t __fenv_dfl_env = {
  50         {
  51                 { FEX_NONSTOP, (void(*)())0 },
  52                 { FEX_NONSTOP, (void(*)())0 },
  53                 { FEX_NONSTOP, (void(*)())0 },
  54                 { FEX_NONSTOP, (void(*)())0 },
  55                 { FEX_NONSTOP, (void(*)())0 },
  56                 { FEX_NONSTOP, (void(*)())0 },
  57                 { FEX_NONSTOP, (void(*)())0 },
  58                 { FEX_NONSTOP, (void(*)())0 },
  59                 { FEX_NONSTOP, (void(*)())0 },
  60                 { FEX_NONSTOP, (void(*)())0 },
  61                 { FEX_NONSTOP, (void(*)())0 },
  62                 { FEX_NONSTOP, (void(*)())0 },
  63         },
  64 #ifdef __x86
  65         0x13000000
  66 #else
  67         0
  68 #endif
  69 };
  70 
  71 int feholdexcept(fenv_t *p)
  72 {
  73         (void) fegetenv(p);
  74         (void) feclearexcept(FE_ALL_EXCEPT);
  75         return !fex_set_handling(FEX_ALL, FEX_NONSTOP, NULL);
  76 }
  77 
  78 int feholdexcept96(fenv_t *p)
  79 {
  80         (void) fegetenv(p);
  81         (void) feclearexcept(FE_ALL_EXCEPT);
  82         return fex_set_handling(FEX_ALL, FEX_NONSTOP, NULL);
  83 }
  84 
  85 int feupdateenv(const fenv_t *p)
  86 {
  87         unsigned long   fsr;
  88 
  89         __fenv_getfsr(&fsr);
  90         (void) fesetenv(p);
  91         (void) feraiseexcept((int)__fenv_get_ex(fsr));
  92         return 0;
  93 }
  94 
  95 int fegetenv(fenv_t *p)
  96 {
  97         fex_getexcepthandler(&p->__handlers, FEX_ALL);
  98         __fenv_getfsr(&p->__fsr);
  99         return 0;
 100 }
 101 
 102 int fesetenv(const fenv_t *p)
 103 {
 104         __fenv_setfsr(&p->__fsr);
 105         fex_setexcepthandler(&p->__handlers, FEX_ALL);
 106         return 0;
 107 }
 108 
 109 void fex_merge_flags(const fenv_t *p)
 110 {
 111         unsigned long   fsr;
 112 
 113         __fenv_getfsr(&fsr);
 114         __fenv_set_ex(fsr, __fenv_get_ex(fsr) | __fenv_get_ex(p->__fsr));
 115         __fenv_setfsr(&fsr);
 116         if (fex_get_log())
 117                 __fex_update_te();
 118 }