(root)/
glibc-2.38/
sysdeps/
hppa/
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  
      23  /* Please see section 10,
      24     page 10-5 "Delayed Trapping" in the PA-RISC 2.0 Architecture manual */
      25  
      26  int
      27  __feraiseexcept (int excepts)
      28  {
      29    /* Raise exceptions represented by EXCEPTS.  But we must raise only one
      30       signal at a time.  It is important that if the overflow/underflow
      31       exception and the divide by zero exception are given at the same
      32       time, the overflow/underflow exception follows the divide by zero
      33       exception.  */
      34  
      35    /* We do these bits in assembly to be certain GCC doesn't optimize
      36       away something important, and so we can force delayed traps to
      37       occur. */
      38  
      39    /* We use "fldd 0(%%sr0,%%sp),%0" to flush the delayed exception */
      40  
      41    /* First: Invalid exception.  */
      42    if (excepts & FE_INVALID)
      43      {
      44        /* One example of an invalid operation is 0 * Infinity.  */
      45        double d = HUGE_VAL;
      46        __asm__ __volatile__ (
      47  		"	fcpy,dbl %%fr0,%%fr22\n"
      48  		"	fmpy,dbl %0,%%fr22,%0\n"
      49  		"	fldd 0(%%sr0,%%sp),%0"
      50  		: "+f" (d) : : "%fr22" );
      51      }
      52  
      53    /* Second: Division by zero.  */
      54    if (excepts & FE_DIVBYZERO)
      55      {
      56        double d = 1.0;
      57        __asm__ __volatile__ (
      58  		"	fcpy,dbl %%fr0,%%fr22\n"
      59  		"	fdiv,dbl %0,%%fr22,%0\n"
      60  		"	fldd 0(%%sr0,%%sp),%0"
      61  		: "+f" (d) : : "%fr22" );
      62      }
      63  
      64    /* Third: Overflow.  */
      65    if (excepts & FE_OVERFLOW)
      66      {
      67        double d = DBL_MAX;
      68        __asm__ __volatile__ (
      69  		"	fadd,dbl %0,%0,%0\n"
      70  		"	fldd 0(%%sr0,%%sp),%0"
      71  		: "+f" (d) );
      72      }
      73  
      74    /* Fourth: Underflow.  */
      75    if (excepts & FE_UNDERFLOW)
      76      {
      77        double d = DBL_MIN;
      78        double e = 3.0;
      79        __asm__ __volatile__ (
      80  		"	fdiv,dbl %0,%1,%0\n"
      81  		"	fldd 0(%%sr0,%%sp),%0"
      82  		: "+f" (d) : "f" (e) );
      83      }
      84  
      85    /* Fifth: Inexact */
      86    if (excepts & FE_INEXACT)
      87      {
      88        double d = M_PI;
      89        double e = 69.69;
      90        __asm__ __volatile__ (
      91  		"	fdiv,dbl %0,%1,%%fr22\n"
      92  		"	fcnvfxt,dbl,sgl %%fr22,%%fr22L\n"
      93  		"	fldd 0(%%sr0,%%sp),%%fr22"
      94  		: : "f" (d), "f" (e) : "%fr22" );
      95      }
      96  
      97    /* Success.  */
      98    return 0;
      99  }
     100  libm_hidden_def (__feraiseexcept)
     101  weak_alias (__feraiseexcept, feraiseexcept)
     102  libm_hidden_weak (feraiseexcept)