Print this page
11210 libm should be cstyle(1ONBLD) clean

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libm/common/m9x/__fex_hdlr.c
          +++ new/usr/src/lib/libm/common/m9x/__fex_hdlr.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  24   24   */
       25 +
  25   26  /*
  26   27   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  27   28   * Use is subject to license terms.
  28   29   */
  29   30  
  30   31  #undef lint
  31   32  #include <signal.h>
  32   33  #include <siginfo.h>
  33   34  #include <ucontext.h>
  34   35  #include <stdio.h>
↓ open down ↓ 5 lines elided ↑ open up ↑
  40   41  #include <sunmath.h>
  41   42  #endif
  42   43  #include <fenv.h>
  43   44  #include "fex_handler.h"
  44   45  #include "fenv_inlines.h"
  45   46  
  46   47  #if defined(__sparc) && !defined(__sparcv9)
  47   48  #include <sys/procfs.h>
  48   49  #endif
  49   50  
  50      -/* 2.x signal.h doesn't declare sigemptyset or sigismember
  51      -   if they're #defined (see sys/signal.h) */
       51 +/*
       52 + * 2.x signal.h doesn't declare sigemptyset or sigismember
       53 + * if they're #define'd (see sys/signal.h)
       54 + */
  52   55  extern int sigemptyset(sigset_t *);
  53   56  extern int sigismember(const sigset_t *, int);
  54   57  
  55   58  /* external globals */
  56      -void (*__mt_fex_sync)() = NULL; /* for synchronization with libmtsk */
       59 +void (*__mt_fex_sync)() = NULL;         /* for synchronization with libmtsk */
  57   60  #pragma weak __mt_fex_sync
  58   61  
  59      -void (*__libm_mt_fex_sync)() = NULL; /* new, improved version of above */
       62 +void (*__libm_mt_fex_sync)() = NULL;    /* new, improved version of above */
  60   63  #pragma weak __libm_mt_fex_sync
  61   64  
  62   65  /* private variables */
  63   66  static fex_handler_t main_handlers;
  64   67  static int handlers_initialized = 0;
  65   68  static thread_key_t handlers_key;
  66   69  static mutex_t handlers_key_lock = DEFAULTMUTEX;
  67      -
  68   70  static struct sigaction oact = { 0, SIG_DFL };
  69   71  static mutex_t hdlr_lock = DEFAULTMUTEX;
  70   72  static int hdlr_installed = 0;
  71   73  
  72   74  /* private const data */
  73   75  static const int te_bit[FEX_NUM_EXC] = {
  74      -        1 << fp_trap_inexact,
  75      -        1 << fp_trap_division,
  76      -        1 << fp_trap_underflow,
  77      -        1 << fp_trap_overflow,
  78      -        1 << fp_trap_invalid,
  79      -        1 << fp_trap_invalid,
  80      -        1 << fp_trap_invalid,
  81      -        1 << fp_trap_invalid,
  82      -        1 << fp_trap_invalid,
  83      -        1 << fp_trap_invalid,
  84      -        1 << fp_trap_invalid,
  85      -        1 << fp_trap_invalid
       76 +        1 << fp_trap_inexact, 1 << fp_trap_division, 1 << fp_trap_underflow,
       77 +        1 << fp_trap_overflow, 1 << fp_trap_invalid, 1 << fp_trap_invalid,
       78 +        1 << fp_trap_invalid, 1 << fp_trap_invalid, 1 << fp_trap_invalid,
       79 +        1 << fp_trap_invalid, 1 << fp_trap_invalid, 1 << fp_trap_invalid
  86   80  };
  87   81  
  88   82  /*
  89      -*  Return the traps to be enabled given the current handling modes
  90      -*  and flags
  91      -*/
       83 + *  Return the traps to be enabled given the current handling modes
       84 + *  and flags
       85 + */
  92   86  static int
  93   87  __fex_te_needed(struct fex_handler_data *thr_handlers, unsigned long fsr)
  94   88  {
  95      -        int             i, ex, te;
       89 +        int i, ex, te;
  96   90  
  97   91          /* set traps for handling modes */
  98   92          te = 0;
       93 +
  99   94          for (i = 0; i < FEX_NUM_EXC; i++)
 100   95                  if (thr_handlers[i].__mode != FEX_NONSTOP)
 101   96                          te |= te_bit[i];
 102   97  
 103   98          /* add traps for retrospective diagnostics */
       99 +
 104  100          if (fex_get_log()) {
 105  101                  ex = (int)__fenv_get_ex(fsr);
      102 +
 106  103                  if (!(ex & FE_INEXACT))
 107  104                          te |= (1 << fp_trap_inexact);
      105 +
 108  106                  if (!(ex & FE_UNDERFLOW))
 109  107                          te |= (1 << fp_trap_underflow);
      108 +
 110  109                  if (!(ex & FE_OVERFLOW))
 111  110                          te |= (1 << fp_trap_overflow);
      111 +
 112  112                  if (!(ex & FE_DIVBYZERO))
 113  113                          te |= (1 << fp_trap_division);
      114 +
 114  115                  if (!(ex & FE_INVALID))
 115  116                          te |= (1 << fp_trap_invalid);
 116  117          }
 117  118  
 118      -        return te;
      119 +        return (te);
 119  120  }
 120  121  
 121  122  /*
 122      -*  The following function synchronizes with libmtsk (SPARC only, for now)
 123      -*/
      123 + *  The following function synchronizes with libmtsk (SPARC only, for now)
      124 + */
 124  125  static void
 125  126  __fex_sync_with_libmtsk(int begin, int master)
 126  127  {
 127  128          static fenv_t master_env;
 128  129          static int env_initialized = 0;
 129  130          static mutex_t env_lock = DEFAULTMUTEX;
 130  131  
 131  132          if (begin) {
 132  133                  mutex_lock(&env_lock);
      134 +
 133  135                  if (master) {
 134  136                          (void) fegetenv(&master_env);
 135  137                          env_initialized = 1;
 136      -                }
 137      -                else if (env_initialized)
      138 +                } else if (env_initialized) {
 138  139                          (void) fesetenv(&master_env);
      140 +                }
      141 +
 139  142                  mutex_unlock(&env_lock);
 140      -        }
 141      -        else if (master && fex_get_log())
      143 +        } else if (master && fex_get_log()) {
 142  144                  __fex_update_te();
      145 +        }
 143  146  }
 144  147  
 145  148  /*
 146      -*  The following function may be used for synchronization with any
 147      -*  internal project that manages multiple threads
 148      -*/
      149 + *  The following function may be used for synchronization with any
      150 + *  internal project that manages multiple threads
      151 + */
 149  152  enum __libm_mt_fex_sync_actions {
 150      -        __libm_mt_fex_start_master = 0,
 151      -        __libm_mt_fex_start_slave,
 152      -        __libm_mt_fex_finish_master,
 153      -        __libm_mt_fex_finish_slave
      153 +        __libm_mt_fex_start_master = 0, __libm_mt_fex_start_slave,
      154 +        __libm_mt_fex_finish_master, __libm_mt_fex_finish_slave
 154  155  };
 155  156  
 156  157  struct __libm_mt_fex_sync_data {
 157      -        fenv_t  master_env;
 158      -        int             initialized;
 159      -        mutex_t lock;
      158 +        fenv_t master_env;
      159 +        int initialized;
      160 +        mutex_t lock;
 160  161  };
 161  162  
 162  163  static void
 163      -__fex_sync_with_threads(enum __libm_mt_fex_sync_actions action,
 164      -        struct __libm_mt_fex_sync_data *thr_env)
      164 +__fex_sync_with_threads(enum __libm_mt_fex_sync_actions action, struct
      165 +    __libm_mt_fex_sync_data *thr_env)
 165  166  {
 166  167          switch (action) {
 167  168          case __libm_mt_fex_start_master:
 168  169                  mutex_lock(&thr_env->lock);
 169  170                  (void) fegetenv(&thr_env->master_env);
 170  171                  thr_env->initialized = 1;
 171  172                  mutex_unlock(&thr_env->lock);
 172  173                  break;
 173  174  
 174  175          case __libm_mt_fex_start_slave:
 175  176                  mutex_lock(&thr_env->lock);
      177 +
 176  178                  if (thr_env->initialized)
 177  179                          (void) fesetenv(&thr_env->master_env);
      180 +
 178  181                  mutex_unlock(&thr_env->lock);
 179  182                  break;
 180  183  
 181  184          case __libm_mt_fex_finish_master:
 182  185  #if defined(__x86)
 183  186                  __fex_update_te();
 184  187  #else
 185  188                  if (fex_get_log())
 186  189                          __fex_update_te();
 187  190  #endif
 188  191                  break;
 189  192  
 190  193          case __libm_mt_fex_finish_slave:
 191  194  #if defined(__x86)
 192      -                /* clear traps, making all accrued flags visible in status word */
      195 +                /*
      196 +                 * clear traps, making all accrued flags visible in status
      197 +                 * word
      198 +                 */
 193  199                  {
 194      -                        unsigned long   fsr;
      200 +                        unsigned long fsr;
      201 +
 195  202                          __fenv_getfsr(&fsr);
 196  203                          __fenv_set_te(fsr, 0);
 197  204                          __fenv_setfsr(&fsr);
 198  205                  }
 199  206  #endif
 200  207                  break;
 201  208          }
 202  209  }
 203  210  
 204  211  #if defined(__sparc)
 205      -
 206  212  /*
 207      -*  Code for setting or clearing interval mode on US-III and above.
 208      -*  This is embedded as data so we don't have to mark the library
 209      -*  as a v8plusb/v9b object.  (I could have just used one entry and
 210      -*  modified the second word to set the bits I want, but that would
 211      -*  have required another mutex.)
 212      -*/
      213 + *  Code for setting or clearing interval mode on US-III and above.
      214 + *  This is embedded as data so we don't have to mark the library
      215 + *  as a v8plusb/v9b object.  (I could have just used one entry and
      216 + *  modified the second word to set the bits I want, but that would
      217 + *  have required another mutex.)
      218 + */
 213  219  static const unsigned int siam[][2] = {
 214      -        { 0x81c3e008, 0x81b01020 }, /* retl, siam 0 */
 215      -        { 0x81c3e008, 0x81b01024 }, /* retl, siam 4 */
 216      -        { 0x81c3e008, 0x81b01025 }, /* retl, siam 5 */
 217      -        { 0x81c3e008, 0x81b01026 }, /* retl, siam 6 */
 218      -        { 0x81c3e008, 0x81b01027 }  /* retl, siam 7 */
      220 +        { 0x81c3e008, 0x81b01020 },     /* retl, siam 0 */
      221 +        { 0x81c3e008, 0x81b01024 },     /* retl, siam 4 */
      222 +        { 0x81c3e008, 0x81b01025 },     /* retl, siam 5 */
      223 +        { 0x81c3e008, 0x81b01026 },     /* retl, siam 6 */
      224 +        { 0x81c3e008, 0x81b01027 }      /* retl, siam 7 */
 219  225  };
 220  226  
 221  227  /*
 222      -*  If a handling mode is in effect, apply it; otherwise invoke the
 223      -*  saved handler
 224      -*/
      228 + *  If a handling mode is in effect, apply it; otherwise invoke the
      229 + *  saved handler
      230 + */
 225  231  static void
 226  232  __fex_hdlr(int sig, siginfo_t *sip, ucontext_t *uap)
 227  233  {
 228      -        struct fex_handler_data *thr_handlers;
 229      -        struct sigaction        act;
 230      -        void                    (*handler)(), (*siamp)();
 231      -        int                     mode, i;
 232      -        enum fex_exception      e;
 233      -        fex_info_t              info;
 234      -        unsigned long           fsr, tmpfsr, addr;
 235      -        unsigned int            gsr;
      234 +        struct fex_handler_data *thr_handlers;
      235 +        struct sigaction act;
      236 +
      237 +        void (*handler)(), (*siamp)();
      238 +
      239 +        int mode, i;
      240 +        enum fex_exception e;
      241 +        fex_info_t info;
      242 +        unsigned long fsr, tmpfsr, addr;
      243 +        unsigned int gsr;
 236  244  
 237  245          /* determine which exception occurred */
 238  246          switch (sip->si_code) {
 239  247          case FPE_FLTDIV:
 240  248                  e = fex_division;
 241  249                  break;
 242  250          case FPE_FLTOVF:
 243  251                  e = fex_overflow;
 244  252                  break;
 245  253          case FPE_FLTUND:
 246  254                  e = fex_underflow;
 247  255                  break;
 248  256          case FPE_FLTRES:
 249  257                  e = fex_inexact;
 250  258                  break;
 251  259          case FPE_FLTINV:
      260 +
 252  261                  if ((int)(e = __fex_get_invalid_type(sip, uap)) < 0)
 253  262                          goto not_ieee;
      263 +
 254  264                  break;
 255  265          default:
 256  266                  /* not an IEEE exception */
 257  267                  goto not_ieee;
 258  268          }
 259  269  
 260  270          /* get the handling mode */
 261  271          mode = FEX_NOHANDLER;
 262  272          handler = oact.sa_handler; /* for log; just looking, no need to lock */
 263  273          thr_handlers = __fex_get_thr_handlers();
      274 +
 264  275          if (thr_handlers && thr_handlers[(int)e].__mode != FEX_NOHANDLER) {
 265  276                  mode = thr_handlers[(int)e].__mode;
 266  277                  handler = thr_handlers[(int)e].__handler;
 267  278          }
 268  279  
 269  280          /* make an entry in the log of retro. diag. if need be */
 270  281          i = ((int)uap->uc_mcontext.fpregs.fpu_fsr >> 5) & 0x1f;
 271  282          __fex_mklog(uap, (char *)sip->si_addr, i, e, mode, (void *)handler);
 272  283  
 273  284          /* handle the exception based on the mode */
 274      -        if (mode == FEX_NOHANDLER)
      285 +        if (mode == FEX_NOHANDLER) {
 275  286                  goto not_ieee;
 276      -        else if (mode == FEX_ABORT)
      287 +        } else if (mode == FEX_ABORT) {
 277  288                  abort();
 278      -        else if (mode == FEX_SIGNAL) {
      289 +        } else if (mode == FEX_SIGNAL) {
 279  290                  handler(sig, sip, uap);
 280  291                  return;
 281  292          }
 282  293  
 283  294          /* custom or nonstop mode; disable traps and clear flags */
 284  295          __fenv_getfsr(&fsr);
 285  296          __fenv_set_te(fsr, 0);
 286  297          __fenv_set_ex(fsr, 0);
 287  298  
 288      -        /* if interval mode was set, clear it, then substitute the
 289      -           interval rounding direction and clear ns mode in the fsr */
      299 +        /*
      300 +         * if interval mode was set, clear it, then substitute the interval
      301 +         * rounding direction and clear ns mode in the fsr
      302 +         */
 290  303  #ifdef __sparcv9
 291  304          gsr = uap->uc_mcontext.asrs[3];
 292  305  #else
 293  306          gsr = 0;
      307 +
 294  308          if (uap->uc_mcontext.xrs.xrs_id == XRS_ID)
 295      -                gsr = (*(unsigned long long*)((prxregset_t*)uap->uc_mcontext.
 296      -                    xrs.xrs_ptr)->pr_un.pr_v8p.pr_filler);
      309 +                gsr = (*(unsigned long long *)
      310 +                    ((prxregset_t *)uap->uc_mcontext.xrs.xrs_ptr)->pr_un.
      311 +                    pr_v8p.pr_filler);
 297  312  #endif
 298  313          gsr = (gsr >> 25) & 7;
      314 +
 299  315          if (gsr & 4) {
 300      -                siamp = (void (*)()) siam[0];
      316 +                siamp = (void (*)())siam[0];
 301  317                  siamp();
 302  318                  tmpfsr = fsr;
 303  319                  fsr = (fsr & ~0xc0400000ul) | ((gsr & 3) << 30);
 304  320          }
      321 +
 305  322          __fenv_setfsr(&fsr);
 306  323  
 307  324          /* decode the operation */
 308  325          __fex_get_op(sip, uap, &info);
 309  326  
 310  327          /* if a custom mode handler is installed, invoke it */
 311  328          if (mode == FEX_CUSTOM) {
 312  329                  /* if we got here from feraiseexcept, pass dummy info */
 313  330                  addr = (unsigned long)sip->si_addr;
 314      -                if (addr >= (unsigned long)feraiseexcept &&
 315      -                    addr < (unsigned long)fetestexcept) {
      331 +
      332 +                if (addr >= (unsigned long)feraiseexcept && addr < (unsigned
      333 +                    long)fetestexcept) {
 316  334                          info.op = fex_other;
 317  335                          info.op1.type = info.op2.type = info.res.type =
 318  336                              fex_nodata;
 319  337                  }
 320  338  
 321      -                /* restore interval mode if it was set, and put the original
 322      -                   rounding direction and ns mode back in the fsr */
      339 +                /*
      340 +                 * restore interval mode if it was set, and put the original
      341 +                 * rounding direction and ns mode back in the fsr
      342 +                 */
 323  343                  if (gsr & 4) {
 324  344                          __fenv_setfsr(&tmpfsr);
 325      -                        siamp = (void (*)()) siam[1 + (gsr & 3)];
      345 +                        siamp = (void (*)())siam[1 + (gsr & 3)];
 326  346                          siamp();
 327  347                  }
 328  348  
 329  349                  handler(1 << (int)e, &info);
 330  350  
 331  351                  /* restore modes in case the user's handler changed them */
 332  352                  if (gsr & 4) {
 333      -                        siamp = (void (*)()) siam[0];
      353 +                        siamp = (void (*)())siam[0];
 334  354                          siamp();
 335  355                  }
      356 +
 336  357                  __fenv_setfsr(&fsr);
 337  358          }
 338  359  
 339  360          /* stuff the result */
 340  361          __fex_st_result(sip, uap, &info);
 341  362  
 342  363          /* "or" in any exception flags and update traps */
 343  364          fsr = uap->uc_mcontext.fpregs.fpu_fsr;
 344  365          fsr |= ((info.flags & 0x1f) << 5);
 345  366          i = __fex_te_needed(thr_handlers, fsr);
 346  367          __fenv_set_te(fsr, i);
 347  368          uap->uc_mcontext.fpregs.fpu_fsr = fsr;
 348  369          return;
 349  370  
 350  371  not_ieee:
 351  372          /* revert to the saved handler (if any) */
 352  373          mutex_lock(&hdlr_lock);
 353  374          act = oact;
 354  375          mutex_unlock(&hdlr_lock);
      376 +
 355  377          switch ((unsigned long)act.sa_handler) {
 356  378          case (unsigned long)SIG_DFL:
 357  379                  /* simulate trap with no handler installed */
 358  380                  sigaction(SIGFPE, &act, NULL);
 359  381                  kill(getpid(), SIGFPE);
 360  382                  break;
 361  383  #if !defined(__lint)
 362  384          case (unsigned long)SIG_IGN:
 363  385                  break;
 364  386  #endif
 365  387          default:
 366  388                  act.sa_handler(sig, sip, uap);
 367  389          }
 368  390  }
 369      -
 370  391  #elif defined(__x86)
 371      -
 372  392  #if defined(__amd64)
 373      -#define test_sse_hw     1
      393 +#define test_sse_hw             1
 374  394  #else
 375  395  extern int _sse_hw;
 376      -#define test_sse_hw     _sse_hw
      396 +
      397 +#define test_sse_hw             _sse_hw
 377  398  #endif
 378  399  
 379  400  #if !defined(REG_PC)
 380      -#define REG_PC  EIP
      401 +#define REG_PC                  EIP
 381  402  #endif
 382  403  
 383  404  /*
 384      -*  If a handling mode is in effect, apply it; otherwise invoke the
 385      -*  saved handler
 386      -*/
      405 + *  If a handling mode is in effect, apply it; otherwise invoke the
      406 + *  saved handler
      407 + */
 387  408  static void
 388  409  __fex_hdlr(int sig, siginfo_t *sip, ucontext_t *uap)
 389  410  {
 390      -        struct fex_handler_data *thr_handlers;
 391      -        struct sigaction        act;
 392      -        void                    (*handler)() = NULL, (*simd_handler[4])();
 393      -        int                     mode, simd_mode[4], i, len, accrued, *ap;
 394      -        unsigned int            cwsw, oldcwsw, mxcsr, oldmxcsr;
 395      -        enum fex_exception      e, simd_e[4];
 396      -        fex_info_t              info, simd_info[4];
 397      -        unsigned long           addr;
 398      -        siginfo_t               osip = *sip;
 399      -        sseinst_t               inst;
      411 +        struct fex_handler_data *thr_handlers;
      412 +        struct sigaction act;
      413 +
      414 +        void (*handler)() = NULL, (*simd_handler[4])();
      415 +
      416 +        int mode, simd_mode[4], i, len, accrued, *ap;
      417 +        unsigned int cwsw, oldcwsw, mxcsr, oldmxcsr;
      418 +        enum fex_exception e, simd_e[4];
      419 +        fex_info_t info, simd_info[4];
      420 +        unsigned long addr;
      421 +        siginfo_t osip = *sip;
      422 +        sseinst_t inst;
 400  423  
 401  424          /* check for an exception caused by an SSE instruction */
 402  425          if (!(uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.status & 0x80)) {
 403  426                  len = __fex_parse_sse(uap, &inst);
      427 +
 404  428                  if (len == 0)
 405  429                          goto not_ieee;
 406  430  
 407  431                  /* disable all traps and clear flags */
 408  432                  __fenv_getcwsw(&oldcwsw);
 409  433                  cwsw = (oldcwsw & ~0x3f) | 0x003f0000;
 410  434                  __fenv_setcwsw(&cwsw);
 411  435                  __fenv_getmxcsr(&oldmxcsr);
 412  436                  mxcsr = (oldmxcsr & ~0x3f) | 0x1f80;
 413  437                  __fenv_setmxcsr(&mxcsr);
 414  438  
 415  439                  if ((int)inst.op & SIMD) {
 416  440                          __fex_get_simd_op(uap, &inst, simd_e, simd_info);
 417  441  
 418  442                          thr_handlers = __fex_get_thr_handlers();
 419  443                          addr = (unsigned long)uap->uc_mcontext.gregs[REG_PC];
 420      -                        accrued = uap->uc_mcontext.fpregs.fp_reg_set.
 421      -                            fpchip_state.mxcsr;
      444 +                        accrued =
      445 +                            uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.
      446 +                            mxcsr;
 422  447  
 423  448                          e = (enum fex_exception)-1;
 424  449                          mode = FEX_NONSTOP;
      450 +
 425  451                          for (i = 0; i < 4; i++) {
 426  452                                  if ((int)simd_e[i] < 0)
 427  453                                          continue;
 428  454  
 429  455                                  e = simd_e[i];
 430  456                                  simd_mode[i] = FEX_NOHANDLER;
 431  457                                  simd_handler[i] = oact.sa_handler;
      458 +
 432  459                                  if (thr_handlers &&
 433  460                                      thr_handlers[(int)e].__mode !=
 434  461                                      FEX_NOHANDLER) {
 435  462                                          simd_mode[i] =
 436  463                                              thr_handlers[(int)e].__mode;
 437  464                                          simd_handler[i] =
 438  465                                              thr_handlers[(int)e].__handler;
 439  466                                  }
      467 +
 440  468                                  accrued &= ~te_bit[(int)e];
      469 +
 441  470                                  switch (simd_mode[i]) {
 442  471                                  case FEX_ABORT:
 443  472                                          mode = FEX_ABORT;
 444  473                                          break;
 445  474                                  case FEX_SIGNAL:
      475 +
 446  476                                          if (mode != FEX_ABORT)
 447  477                                                  mode = FEX_SIGNAL;
      478 +
 448  479                                          handler = simd_handler[i];
 449  480                                          break;
 450  481                                  case FEX_NOHANDLER:
      482 +
 451  483                                          if (mode != FEX_ABORT && mode !=
 452  484                                              FEX_SIGNAL)
 453  485                                                  mode = FEX_NOHANDLER;
      486 +
 454  487                                          break;
 455  488                                  }
 456  489                          }
      490 +
 457  491                          if (e == (enum fex_exception)-1) {
 458  492                                  __fenv_setcwsw(&oldcwsw);
 459  493                                  __fenv_setmxcsr(&oldmxcsr);
 460  494                                  goto not_ieee;
 461  495                          }
 462      -                        accrued |= uap->uc_mcontext.fpregs.fp_reg_set.
 463      -                            fpchip_state.status;
      496 +
      497 +                        accrued |=
      498 +                            uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.
      499 +                            status;
 464  500                          ap = __fex_accrued();
 465  501                          accrued |= *ap;
 466  502                          accrued &= 0x3d;
 467  503  
 468  504                          for (i = 0; i < 4; i++) {
 469  505                                  if ((int)simd_e[i] < 0)
 470  506                                          continue;
 471  507  
 472  508                                  __fex_mklog(uap, (char *)addr, accrued,
 473  509                                      simd_e[i], simd_mode[i],
↓ open down ↓ 7 lines elided ↑ open up ↑
 481  517                          } else if (mode == FEX_ABORT) {
 482  518                                  abort();
 483  519                          } else if (mode == FEX_SIGNAL) {
 484  520                                  __fenv_setcwsw(&oldcwsw);
 485  521                                  __fenv_setmxcsr(&oldmxcsr);
 486  522                                  handler(sig, &osip, uap);
 487  523                                  return;
 488  524                          }
 489  525  
 490  526                          *ap = 0;
      527 +
 491  528                          for (i = 0; i < 4; i++) {
 492  529                                  if ((int)simd_e[i] < 0)
 493  530                                          continue;
 494  531  
 495  532                                  if (simd_mode[i] == FEX_CUSTOM) {
 496  533                                          handler(1 << (int)simd_e[i],
 497  534                                              &simd_info[i]);
 498  535                                          __fenv_setcwsw(&cwsw);
 499  536                                          __fenv_setmxcsr(&mxcsr);
 500  537                                  }
 501  538                          }
 502  539  
 503  540                          __fex_st_simd_result(uap, &inst, simd_e, simd_info);
      541 +
 504  542                          for (i = 0; i < 4; i++) {
 505  543                                  if ((int)simd_e[i] < 0)
 506  544                                          continue;
 507  545  
 508  546                                  accrued |= simd_info[i].flags;
 509  547                          }
 510  548  
 511  549                          if ((int)inst.op & INTREG) {
 512  550                                  /* set MMX mode */
 513  551  #if defined(__amd64)
 514      -                                uap->uc_mcontext.fpregs.fp_reg_set.
 515      -                                    fpchip_state.sw &= ~0x3800;
 516      -                                uap->uc_mcontext.fpregs.fp_reg_set.
 517      -                                    fpchip_state.fctw = 0;
      552 +                                uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.
      553 +                                    sw &= ~0x3800;
      554 +                                uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.
      555 +                                    fctw = 0;
 518  556  #else
 519      -                                uap->uc_mcontext.fpregs.fp_reg_set.
 520      -                                    fpchip_state.state[1] &= ~0x3800;
 521      -                                uap->uc_mcontext.fpregs.fp_reg_set.
 522      -                                    fpchip_state.state[2] = 0;
      557 +                                uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.
      558 +                                    state[1] &= ~0x3800;
      559 +                                uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.
      560 +                                    state[2] = 0;
 523  561  #endif
 524  562                          }
 525  563                  } else {
 526  564                          e = __fex_get_sse_op(uap, &inst, &info);
      565 +
 527  566                          if ((int)e < 0) {
 528  567                                  __fenv_setcwsw(&oldcwsw);
 529  568                                  __fenv_setmxcsr(&oldmxcsr);
 530  569                                  goto not_ieee;
 531  570                          }
 532  571  
 533  572                          mode = FEX_NOHANDLER;
 534  573                          handler = oact.sa_handler;
 535  574                          thr_handlers = __fex_get_thr_handlers();
      575 +
 536  576                          if (thr_handlers && thr_handlers[(int)e].__mode !=
 537  577                              FEX_NOHANDLER) {
 538  578                                  mode = thr_handlers[(int)e].__mode;
 539  579                                  handler = thr_handlers[(int)e].__handler;
 540  580                          }
 541  581  
 542  582                          addr = (unsigned long)uap->uc_mcontext.gregs[REG_PC];
 543      -                        accrued = uap->uc_mcontext.fpregs.fp_reg_set.
 544      -                            fpchip_state.mxcsr & ~te_bit[(int)e];
 545      -                        accrued |= uap->uc_mcontext.fpregs.fp_reg_set.
 546      -                            fpchip_state.status;
      583 +                        accrued =
      584 +                            uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.
      585 +                            mxcsr & ~te_bit[(int)e];
      586 +                        accrued |=
      587 +                            uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.
      588 +                            status;
 547  589                          ap = __fex_accrued();
 548  590                          accrued |= *ap;
 549  591                          accrued &= 0x3d;
 550  592                          __fex_mklog(uap, (char *)addr, accrued, e, mode,
 551  593                              (void *)handler);
 552  594  
 553  595                          if (mode == FEX_NOHANDLER) {
 554  596                                  __fenv_setcwsw(&oldcwsw);
 555  597                                  __fenv_setmxcsr(&oldmxcsr);
 556  598                                  goto not_ieee;
 557  599                          } else if (mode == FEX_ABORT) {
 558  600                                  abort();
 559  601                          } else if (mode == FEX_SIGNAL) {
 560  602                                  __fenv_setcwsw(&oldcwsw);
 561  603                                  __fenv_setmxcsr(&oldmxcsr);
 562  604                                  handler(sig, &osip, uap);
 563  605                                  return;
 564  606                          } else if (mode == FEX_CUSTOM) {
 565  607                                  *ap = 0;
      608 +
 566  609                                  if (addr >= (unsigned long)feraiseexcept &&
 567  610                                      addr < (unsigned long)fetestexcept) {
 568  611                                          info.op = fex_other;
 569  612                                          info.op1.type = info.op2.type =
 570  613                                              info.res.type = fex_nodata;
 571  614                                  }
      615 +
 572  616                                  handler(1 << (int)e, &info);
 573  617                                  __fenv_setcwsw(&cwsw);
 574  618                                  __fenv_setmxcsr(&mxcsr);
 575  619                          }
 576  620  
 577  621                          __fex_st_sse_result(uap, &inst, e, &info);
 578  622                          accrued |= info.flags;
 579  623  
 580  624  #if defined(__amd64)
 581  625                          /*
↓ open down ↓ 9 lines elided ↑ open up ↑
 591  635  #endif
 592  636                  }
 593  637  
 594  638                  /* advance the pc past the SSE instruction */
 595  639                  uap->uc_mcontext.gregs[REG_PC] += len;
 596  640                  goto update_state;
 597  641          }
 598  642  
 599  643          /* determine which exception occurred */
 600  644          __fex_get_x86_exc(sip, uap);
      645 +
 601  646          switch (sip->si_code) {
 602  647          case FPE_FLTDIV:
 603  648                  e = fex_division;
 604  649                  break;
 605  650          case FPE_FLTOVF:
 606  651                  e = fex_overflow;
 607  652                  break;
 608  653          case FPE_FLTUND:
 609  654                  e = fex_underflow;
 610  655                  break;
 611  656          case FPE_FLTRES:
 612  657                  e = fex_inexact;
 613  658                  break;
 614  659          case FPE_FLTINV:
      660 +
 615  661                  if ((int)(e = __fex_get_invalid_type(sip, uap)) < 0)
 616  662                          goto not_ieee;
      663 +
 617  664                  break;
 618  665          default:
 619  666                  /* not an IEEE exception */
 620  667                  goto not_ieee;
 621  668          }
 622  669  
 623  670          /* get the handling mode */
 624  671          mode = FEX_NOHANDLER;
 625  672          handler = oact.sa_handler; /* for log; just looking, no need to lock */
 626  673          thr_handlers = __fex_get_thr_handlers();
      674 +
 627  675          if (thr_handlers && thr_handlers[(int)e].__mode != FEX_NOHANDLER) {
 628  676                  mode = thr_handlers[(int)e].__mode;
 629  677                  handler = thr_handlers[(int)e].__handler;
 630  678          }
 631  679  
 632  680          /* make an entry in the log of retro. diag. if need be */
 633  681  #if defined(__amd64)
 634      -        addr = (unsigned long)uap->uc_mcontext.fpregs.fp_reg_set.
 635      -            fpchip_state.rip;
      682 +        addr = (unsigned
      683 +            long)uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.rip;
 636  684  #else
 637      -        addr = (unsigned long)uap->uc_mcontext.fpregs.fp_reg_set.
 638      -            fpchip_state.state[3];
      685 +        addr = (unsigned
      686 +            long)uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[3];
 639  687  #endif
 640      -        accrued = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.status & 
      688 +        accrued = uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.status &
 641  689              ~te_bit[(int)e];
      690 +
 642  691          if (test_sse_hw)
 643      -                accrued |= uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.
 644      -                    mxcsr;
      692 +                accrued |=
      693 +                    uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.mxcsr;
      694 +
 645  695          ap = __fex_accrued();
 646  696          accrued |= *ap;
 647  697          accrued &= 0x3d;
 648  698          __fex_mklog(uap, (char *)addr, accrued, e, mode, (void *)handler);
 649  699  
 650  700          /* handle the exception based on the mode */
 651      -        if (mode == FEX_NOHANDLER)
      701 +        if (mode == FEX_NOHANDLER) {
 652  702                  goto not_ieee;
 653      -        else if (mode == FEX_ABORT)
      703 +        } else if (mode == FEX_ABORT) {
 654  704                  abort();
 655      -        else if (mode == FEX_SIGNAL) {
      705 +        } else if (mode == FEX_SIGNAL) {
 656  706                  handler(sig, &osip, uap);
 657  707                  return;
 658  708          }
 659  709  
 660  710          /* disable all traps and clear flags */
 661  711          __fenv_getcwsw(&cwsw);
 662  712          cwsw = (cwsw & ~0x3f) | 0x003f0000;
 663  713          __fenv_setcwsw(&cwsw);
      714 +
 664  715          if (test_sse_hw) {
 665  716                  __fenv_getmxcsr(&mxcsr);
 666  717                  mxcsr = (mxcsr & ~0x3f) | 0x1f80;
 667  718                  __fenv_setmxcsr(&mxcsr);
 668  719          }
      720 +
 669  721          *ap = 0;
 670  722  
 671  723          /* decode the operation */
 672  724          __fex_get_op(sip, uap, &info);
 673  725  
 674  726          /* if a custom mode handler is installed, invoke it */
 675  727          if (mode == FEX_CUSTOM) {
 676  728                  /* if we got here from feraiseexcept, pass dummy info */
 677      -                if (addr >= (unsigned long)feraiseexcept &&
 678      -                    addr < (unsigned long)fetestexcept) {
      729 +                if (addr >= (unsigned long)feraiseexcept && addr < (unsigned
      730 +                    long)fetestexcept) {
 679  731                          info.op = fex_other;
 680  732                          info.op1.type = info.op2.type = info.res.type =
 681  733                              fex_nodata;
 682  734                  }
 683  735  
 684  736                  handler(1 << (int)e, &info);
 685  737  
 686  738                  /* restore modes in case the user's handler changed them */
 687  739                  __fenv_setcwsw(&cwsw);
      740 +
 688  741                  if (test_sse_hw)
 689  742                          __fenv_setmxcsr(&mxcsr);
 690  743          }
 691  744  
 692  745          /* stuff the result */
 693  746          __fex_st_result(sip, uap, &info);
 694  747          accrued |= info.flags;
 695  748  
 696  749  update_state:
 697  750          accrued &= 0x3d;
 698  751          i = __fex_te_needed(thr_handlers, accrued);
 699  752          *ap = accrued & i;
 700  753  #if defined(__amd64)
 701  754          uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw &= ~0x3d;
 702  755          uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.sw |= (accrued & ~i);
 703  756          uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.cw |= 0x3d;
 704  757          uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.cw &= ~i;
 705  758  #else
 706  759          uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[1] &= ~0x3d;
 707      -        uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[1] |=
 708      -            (accrued & ~i);
      760 +        uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[1] |= (accrued &
      761 +            ~i);
 709  762          uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[0] |= 0x3d;
 710  763          uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.state[0] &= ~i;
 711  764  #endif
      765 +
 712  766          if (test_sse_hw) {
 713  767                  uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.mxcsr &= ~0x3d;
 714  768                  uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.mxcsr |=
 715  769                      0x1e80 | (accrued & ~i);
 716      -                uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.mxcsr &=
 717      -                    ~(i << 7);
      770 +                uap->uc_mcontext.fpregs.fp_reg_set.fpchip_state.mxcsr &= ~(i <<
      771 +                    7);
 718  772          }
      773 +
 719  774          return;
 720  775  
 721  776  not_ieee:
 722  777          /* revert to the saved handler (if any) */
 723  778          mutex_lock(&hdlr_lock);
 724  779          act = oact;
 725  780          mutex_unlock(&hdlr_lock);
      781 +
 726  782          switch ((unsigned long)act.sa_handler) {
 727  783          case (unsigned long)SIG_DFL:
 728  784                  /* simulate trap with no handler installed */
 729  785                  sigaction(SIGFPE, &act, NULL);
 730  786                  kill(getpid(), SIGFPE);
 731  787                  break;
 732  788  #if !defined(__lint)
 733  789          case (unsigned long)SIG_IGN:
 734  790                  break;
 735  791  #endif
 736  792          default:
 737  793                  act.sa_handler(sig, &osip, uap);
 738  794          }
 739  795  }
 740      -
 741  796  #else
 742  797  #error Unknown architecture
 743  798  #endif
 744  799  
 745  800  /*
 746      -*  Return a pointer to the thread-specific handler data, and
 747      -*  initialize it if necessary
 748      -*/
      801 + *  Return a pointer to the thread-specific handler data, and
      802 + *  initialize it if necessary
      803 + */
 749  804  struct fex_handler_data *
 750  805  __fex_get_thr_handlers()
 751  806  {
 752      -        struct fex_handler_data *ptr;
 753      -        unsigned long                   fsr;
 754      -        int                                             i, te;
      807 +        struct fex_handler_data *ptr;
      808 +        unsigned long fsr;
      809 +        int i, te;
 755  810  
 756  811          if (thr_main()) {
 757  812                  if (!handlers_initialized) {
 758      -                        /* initialize to FEX_NOHANDLER if trap is enabled,
 759      -                           FEX_NONSTOP if trap is disabled */
      813 +                        /*
      814 +                         * initialize to FEX_NOHANDLER if trap is enabled,
      815 +                         * FEX_NONSTOP if trap is disabled
      816 +                         */
 760  817                          __fenv_getfsr(&fsr);
 761  818                          te = (int)__fenv_get_te(fsr);
      819 +
 762  820                          for (i = 0; i < FEX_NUM_EXC; i++)
 763      -                                main_handlers[i].__mode =
 764      -                                        ((te & te_bit[i])? FEX_NOHANDLER : FEX_NONSTOP);
      821 +                                main_handlers[i].__mode = ((te & te_bit[i]) ?
      822 +                                    FEX_NOHANDLER : FEX_NONSTOP);
      823 +
 765  824                          handlers_initialized = 1;
 766  825                  }
 767      -                return main_handlers;
 768      -        }
 769      -        else {
      826 +
      827 +                return (main_handlers);
      828 +        } else {
 770  829                  ptr = NULL;
 771  830                  mutex_lock(&handlers_key_lock);
      831 +
 772  832                  if (thr_getspecific(handlers_key, (void **)&ptr) != 0 &&
 773      -                        thr_keycreate(&handlers_key, free) != 0) {
      833 +                    thr_keycreate(&handlers_key, free) != 0) {
 774  834                          mutex_unlock(&handlers_key_lock);
 775      -                        return NULL;
      835 +                        return (NULL);
 776  836                  }
      837 +
 777  838                  mutex_unlock(&handlers_key_lock);
      839 +
 778  840                  if (!ptr) {
 779      -                        if ((ptr = (struct fex_handler_data *)
 780      -                                malloc(sizeof(fex_handler_t))) == NULL) {
 781      -                                return NULL;
 782      -                        }
      841 +                        if ((ptr = malloc(sizeof (fex_handler_t))) == NULL)
      842 +                                return (NULL);
      843 +
 783  844                          if (thr_setspecific(handlers_key, (void *)ptr) != 0) {
 784      -                                (void)free(ptr);
 785      -                                return NULL;
      845 +                                (void) free(ptr);
      846 +                                return (NULL);
 786  847                          }
 787      -                        /* initialize to FEX_NOHANDLER if trap is enabled,
 788      -                           FEX_NONSTOP if trap is disabled */
      848 +
      849 +                        /*
      850 +                         * initialize to FEX_NOHANDLER if trap is enabled,
      851 +                         * FEX_NONSTOP if trap is disabled
      852 +                         */
 789  853                          __fenv_getfsr(&fsr);
 790  854                          te = (int)__fenv_get_te(fsr);
      855 +
 791  856                          for (i = 0; i < FEX_NUM_EXC; i++)
 792      -                                ptr[i].__mode = ((te & te_bit[i])? FEX_NOHANDLER : FEX_NONSTOP);
      857 +                                ptr[i].__mode = ((te & te_bit[i]) ?
      858 +                                    FEX_NOHANDLER : FEX_NONSTOP);
 793  859                  }
 794      -                return ptr;
      860 +
      861 +                return (ptr);
 795  862          }
 796  863  }
 797  864  
 798  865  /*
 799      -*  Update the trap enable bits according to the selected modes
 800      -*/
      866 + *  Update the trap enable bits according to the selected modes
      867 + */
 801  868  void
 802  869  __fex_update_te()
 803  870  {
 804      -        struct fex_handler_data *thr_handlers;
 805      -        struct sigaction                act, tmpact;
 806      -        sigset_t                                blocked;
 807      -        unsigned long                   fsr;
 808      -        int                                             te;
      871 +        struct fex_handler_data *thr_handlers;
      872 +        struct sigaction act, tmpact;
      873 +        sigset_t blocked;
      874 +        unsigned long fsr;
      875 +        int te;
 809  876  
 810  877          /* determine which traps are needed */
 811  878          thr_handlers = __fex_get_thr_handlers();
 812  879          __fenv_getfsr(&fsr);
 813  880          te = __fex_te_needed(thr_handlers, fsr);
 814  881  
 815  882          /* install __fex_hdlr as necessary */
 816  883          if (!hdlr_installed && te) {
 817  884                  act.sa_handler = __fex_hdlr;
 818  885                  sigemptyset(&act.sa_mask);
 819  886                  act.sa_flags = SA_SIGINFO;
 820  887                  sigaction(SIGFPE, &act, &tmpact);
 821      -                if (tmpact.sa_handler != __fex_hdlr)
 822      -                {
      888 +
      889 +                if (tmpact.sa_handler != __fex_hdlr) {
 823  890                          mutex_lock(&hdlr_lock);
 824  891                          oact = tmpact;
 825  892                          mutex_unlock(&hdlr_lock);
 826  893                  }
      894 +
 827  895                  hdlr_installed = 1;
 828  896          }
 829  897  
 830  898          /* set the new trap enable bits (only if SIGFPE is not blocked) */
 831      -        if (sigprocmask(0, NULL, &blocked) == 0 &&
 832      -                !sigismember(&blocked, SIGFPE)) {
      899 +        if (sigprocmask(0, NULL, &blocked) == 0 && !sigismember(&blocked,
      900 +            SIGFPE)) {
 833  901                  __fenv_set_te(fsr, te);
 834  902                  __fenv_setfsr(&fsr);
 835  903          }
 836  904  
 837  905          /* synchronize with libmtsk */
 838  906          __mt_fex_sync = __fex_sync_with_libmtsk;
 839  907  
 840  908          /* synchronize with other projects */
 841  909          __libm_mt_fex_sync = __fex_sync_with_threads;
 842  910  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX