(root)/
glibc-2.38/
sysdeps/
sparc/
fpu/
fraiseexcpt.c
       1  /* Raise given exceptions.
       2     Copyright (C) 1997-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <fenv.h>
      20  #include <float.h>
      21  #include <math.h>
      22  #include <shlib-compat.h>
      23  
      24  int
      25  __feraiseexcept (int excepts)
      26  {
      27    static const struct {
      28      double zero, one, max, min, pi;
      29    } c = {
      30      0.0, 1.0, DBL_MAX, DBL_MIN, M_PI
      31    };
      32    double d;
      33  
      34    /* Raise exceptions represented by EXPECTS.  But we must raise only
      35       one signal at a time.  It is important the if the overflow/underflow
      36       exception and the inexact exception are given at the same time,
      37       the overflow/underflow exception follows the inexact exception.  */
      38  
      39    /* First: invalid exception.  */
      40    if ((FE_INVALID & excepts) != 0)
      41      {
      42        /* One example of an invalid operation is 0/0.  */
      43        __asm ("" : "=e" (d) : "0" (c.zero));
      44        d /= c.zero;
      45        __asm __volatile ("" : : "e" (d));
      46      }
      47  
      48    /* Next: division by zero.  */
      49    if ((FE_DIVBYZERO & excepts) != 0)
      50      {
      51        __asm ("" : "=e" (d) : "0" (c.one));
      52        d /= c.zero;
      53        __asm __volatile ("" : : "e" (d));
      54      }
      55  
      56    /* Next: overflow.  */
      57    if ((FE_OVERFLOW & excepts) != 0)
      58      {
      59        __asm ("" : "=e" (d) : "0" (c.max));
      60        d *= d;
      61        __asm __volatile ("" : : "e" (d));
      62      }
      63  
      64    /* Next: underflow.  */
      65    if ((FE_UNDERFLOW & excepts) != 0)
      66      {
      67        __asm ("" : "=e" (d) : "0" (c.min));
      68        d *= d;
      69        __asm __volatile ("" : : "e" (d));
      70      }
      71  
      72    /* Last: inexact.  */
      73    if ((FE_INEXACT & excepts) != 0)
      74      {
      75        __asm ("" : "=e" (d) : "0" (c.one));
      76        d /= c.pi;
      77        __asm __volatile ("" : : "e" (d));
      78      }
      79  
      80    /* Success.  */
      81    return 0;
      82  }
      83  
      84  #if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
      85  strong_alias (__feraiseexcept, __old_feraiseexcept)
      86  compat_symbol (libm, __old_feraiseexcept, feraiseexcept, GLIBC_2_1);
      87  #endif
      88  
      89  libm_hidden_def (__feraiseexcept)
      90  libm_hidden_ver (__feraiseexcept, feraiseexcept)
      91  versioned_symbol (libm, __feraiseexcept, feraiseexcept, GLIBC_2_2);