(root)/
glibc-2.38/
sysdeps/
ieee754/
k_standardl.c
       1  /* Implement __kernel_standard_l.
       2     Copyright (C) 2012-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     Parts based on k_standard.c from fdlibm: */
      20  
      21  /* @(#)k_standard.c 5.1 93/09/24 */
      22  /*
      23   * ====================================================
      24   * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
      25   *
      26   * Developed at SunPro, a Sun Microsystems, Inc. business.
      27   * Permission to use, copy, modify, and distribute this
      28   * software is freely granted, provided that this notice
      29   * is preserved.
      30   * ====================================================
      31   */
      32  
      33  #include <math.h>
      34  #include <math-barriers.h>
      35  #include <math-svid-compat.h>
      36  #include <fenv.h>
      37  #include <float.h>
      38  #include <errno.h>
      39  
      40  
      41  #if LIBM_SVID_COMPAT
      42  
      43  static double zero = 0.0;
      44  
      45  /* Handle errors for a libm function as specified by TYPE (see
      46     comments in k_standard.c for details), with arguments X and Y,
      47     returning the appropriate return value for that function.  */
      48  
      49  long double
      50  __kernel_standard_l (long double x, long double y, int type)
      51  {
      52    double dx, dy;
      53    struct exception exc;
      54    fenv_t env;
      55  
      56    feholdexcept (&env);
      57    dx = x;
      58    dy = y;
      59    math_force_eval (dx);
      60    math_force_eval (dy);
      61    fesetenv (&env);
      62  
      63    switch (type)
      64      {
      65      case 221:
      66        /* powl (x, y) overflow.  */
      67        exc.arg1 = dx;
      68        exc.arg2 = dy;
      69        exc.type = OVERFLOW;
      70        exc.name = (char *) "powl";
      71        if (_LIB_VERSION == _SVID_)
      72  	{
      73  	  exc.retval = HUGE;
      74  	  y *= 0.5;
      75  	  if (x < zero && rintl (y) != y)
      76  	    exc.retval = -HUGE;
      77  	}
      78        else
      79  	{
      80  	  exc.retval = HUGE_VAL;
      81  	  y *= 0.5;
      82  	  if (x < zero && rintl (y) != y)
      83  	    exc.retval = -HUGE_VAL;
      84  	}
      85        if (_LIB_VERSION == _POSIX_)
      86  	__set_errno (ERANGE);
      87        else if (!matherr (&exc))
      88  	__set_errno (ERANGE);
      89        return exc.retval;
      90  
      91      case 222:
      92        /* powl (x, y) underflow.  */
      93        exc.arg1 = dx;
      94        exc.arg2 = dy;
      95        exc.type = UNDERFLOW;
      96        exc.name = (char *) "powl";
      97        exc.retval = zero;
      98        y *= 0.5;
      99        if (x < zero && rintl (y) != y)
     100  	exc.retval = -zero;
     101        if (_LIB_VERSION == _POSIX_)
     102  	__set_errno (ERANGE);
     103        else if (!matherr (&exc))
     104  	__set_errno (ERANGE);
     105        return exc.retval;
     106  
     107      default:
     108        return __kernel_standard (dx, dy, type);
     109      }
     110  }
     111  #endif