Blame sysdeps/ieee754/ldbl-128ibm/s_fpclassifyl.c

Packit 6c4009
/* Return classification value corresponding to argument.
Packit 6c4009
   Copyright (C) 1997-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997 and
Packit 6c4009
		  Jakub Jelinek <jj@ultra.linux.cz>, 1999.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <math.h>
Packit 6c4009
Packit 6c4009
#include <math_private.h>
Packit 6c4009
#include <math_ldbl_opt.h>
Packit 6c4009
Packit 6c4009
  /*
Packit 6c4009
   *		hx                  lx
Packit 6c4009
   * +NaN	7ffn nnnn nnnn nnnn xxxx xxxx xxxx xxxx
Packit 6c4009
   * -NaN	fffn nnnn nnnn nnnn xxxx xxxx xxxx xxxx
Packit 6c4009
   * +Inf	7ff0 0000 0000 0000 xxxx xxxx xxxx xxxx
Packit 6c4009
   * -Inf	fff0 0000 0000 0000 xxxx xxxx xxxx xxxx
Packit 6c4009
   * +0		0000 0000 0000 0000 xxxx xxxx xxxx xxxx
Packit 6c4009
   * -0		8000 0000 0000 0000 xxxx xxxx xxxx xxxx
Packit 6c4009
   * +normal	0360 0000 0000 0000 0000 0000 0000 0000 (smallest)
Packit 6c4009
   * -normal	8360 0000 0000 0000 0000 0000 0000 0000 (smallest)
Packit 6c4009
   * +normal	7fef ffff ffff ffff 7c8f ffff ffff fffe (largest)
Packit 6c4009
   * +normal	ffef ffff ffff ffff fc8f ffff ffff fffe (largest)
Packit 6c4009
   * +denorm	0360 0000 0000 0000 8000 0000 0000 0001 (largest)
Packit 6c4009
   * -denorm	8360 0000 0000 0000 0000 0000 0000 0001 (largest)
Packit 6c4009
   * +denorm	000n nnnn nnnn nnnn xxxx xxxx xxxx xxxx
Packit 6c4009
   * -denorm	800n nnnn nnnn nnnn xxxx xxxx xxxx xxxx
Packit 6c4009
   */
Packit 6c4009
Packit 6c4009
int
Packit 6c4009
___fpclassifyl (long double x)
Packit 6c4009
{
Packit 6c4009
  uint64_t hx, lx;
Packit 6c4009
  int retval = FP_NORMAL;
Packit 6c4009
  double xhi, xlo;
Packit 6c4009
Packit 6c4009
  ldbl_unpack (x, &xhi, &xlo;;
Packit 6c4009
  EXTRACT_WORDS64 (hx, xhi);
Packit 6c4009
  if ((hx & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL) {
Packit 6c4009
      /* +/-NaN or +/-Inf */
Packit 6c4009
      if (hx & 0x000fffffffffffffULL) {
Packit 6c4009
	  /* +/-NaN */
Packit 6c4009
	  retval = FP_NAN;
Packit 6c4009
      } else {
Packit 6c4009
	  retval = FP_INFINITE;
Packit 6c4009
      }
Packit 6c4009
  } else {
Packit 6c4009
      /* +/-zero or +/- normal or +/- denormal */
Packit 6c4009
      if (hx & 0x7fffffffffffffffULL) {
Packit 6c4009
	  /* +/- normal or +/- denormal */
Packit 6c4009
	  if ((hx & 0x7ff0000000000000ULL) > 0x0360000000000000ULL) {
Packit 6c4009
	      /* +/- normal */
Packit 6c4009
	      retval = FP_NORMAL;
Packit 6c4009
	  } else {
Packit 6c4009
	      if ((hx & 0x7ff0000000000000ULL) == 0x0360000000000000ULL) {
Packit 6c4009
		  EXTRACT_WORDS64 (lx, xlo);
Packit 6c4009
		  if ((lx & 0x7fffffffffffffff)	/* lower is non-zero */
Packit 6c4009
		  && ((lx^hx) & 0x8000000000000000ULL)) { /* and sign differs */
Packit 6c4009
		      /* +/- denormal */
Packit 6c4009
		      retval = FP_SUBNORMAL;
Packit 6c4009
		  } else {
Packit 6c4009
		      /* +/- normal */
Packit 6c4009
		      retval = FP_NORMAL;
Packit 6c4009
		  }
Packit 6c4009
	      } else {
Packit 6c4009
		  /* +/- denormal */
Packit 6c4009
		  retval = FP_SUBNORMAL;
Packit 6c4009
	      }
Packit 6c4009
	  }
Packit 6c4009
      } else {
Packit 6c4009
	  /* +/- zero */
Packit 6c4009
	  retval = FP_ZERO;
Packit 6c4009
      }
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  return retval;
Packit 6c4009
}
Packit 6c4009
long_double_symbol (libm, ___fpclassifyl, __fpclassifyl);
Packit 6c4009
#ifdef __LONG_DOUBLE_MATH_OPTIONAL
Packit 6c4009
libm_hidden_ver (___fpclassifyl, __fpclassifyl)
Packit 6c4009
#else
Packit 6c4009
libm_hidden_def (__fpclassifyl)
Packit 6c4009
#endif