Blame soft-fp/op-common.h

Packit 6c4009
/* Software floating-point emulation. Common operations.
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 Richard Henderson (rth@cygnus.com),
Packit 6c4009
		  Jakub Jelinek (jj@ultra.linux.cz),
Packit 6c4009
		  David S. Miller (davem@redhat.com) and
Packit 6c4009
		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
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
   In addition to the permissions in the GNU Lesser General Public
Packit 6c4009
   License, the Free Software Foundation gives you unlimited
Packit 6c4009
   permission to link the compiled version of this file into
Packit 6c4009
   combinations with other programs, and to distribute those
Packit 6c4009
   combinations without any restriction coming from the use of this
Packit 6c4009
   file.  (The Lesser General Public License restrictions do apply in
Packit 6c4009
   other respects; for example, they cover modification of the file,
Packit 6c4009
   and distribution when not linked into a combine executable.)
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
#ifndef SOFT_FP_OP_COMMON_H
Packit 6c4009
#define SOFT_FP_OP_COMMON_H	1
Packit 6c4009
Packit 6c4009
#define _FP_DECL(wc, X)						\
Packit 6c4009
  _FP_I_TYPE X##_c __attribute__ ((unused)) _FP_ZERO_INIT;	\
Packit 6c4009
  _FP_I_TYPE X##_s __attribute__ ((unused)) _FP_ZERO_INIT;	\
Packit 6c4009
  _FP_I_TYPE X##_e __attribute__ ((unused)) _FP_ZERO_INIT;	\
Packit 6c4009
  _FP_FRAC_DECL_##wc (X)
Packit 6c4009
Packit 6c4009
/* Test whether the qNaN bit denotes a signaling NaN.  */
Packit 6c4009
#define _FP_FRAC_SNANP(fs, X)				\
Packit 6c4009
  ((_FP_QNANNEGATEDP)					\
Packit 6c4009
   ? (_FP_FRAC_HIGH_RAW_##fs (X) & _FP_QNANBIT_##fs)	\
Packit 6c4009
   : !(_FP_FRAC_HIGH_RAW_##fs (X) & _FP_QNANBIT_##fs))
Packit 6c4009
#define _FP_FRAC_SNANP_SEMIRAW(fs, X)			\
Packit 6c4009
  ((_FP_QNANNEGATEDP)					\
Packit 6c4009
   ? (_FP_FRAC_HIGH_##fs (X) & _FP_QNANBIT_SH_##fs)	\
Packit 6c4009
   : !(_FP_FRAC_HIGH_##fs (X) & _FP_QNANBIT_SH_##fs))
Packit 6c4009
Packit 6c4009
/* Finish truly unpacking a native fp value by classifying the kind
Packit 6c4009
   of fp value and normalizing both the exponent and the fraction.  */
Packit 6c4009
Packit 6c4009
#define _FP_UNPACK_CANONICAL(fs, wc, X)				\
Packit 6c4009
  do								\
Packit 6c4009
    {								\
Packit 6c4009
      switch (X##_e)						\
Packit 6c4009
	{							\
Packit 6c4009
	default:						\
Packit 6c4009
	  _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs;	\
Packit 6c4009
	  _FP_FRAC_SLL_##wc (X, _FP_WORKBITS);			\
Packit 6c4009
	  X##_e -= _FP_EXPBIAS_##fs;				\
Packit 6c4009
	  X##_c = FP_CLS_NORMAL;				\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	case 0:							\
Packit 6c4009
	  if (_FP_FRAC_ZEROP_##wc (X))				\
Packit 6c4009
	    X##_c = FP_CLS_ZERO;				\
Packit 6c4009
	  else if (FP_DENORM_ZERO)				\
Packit 6c4009
	    {							\
Packit 6c4009
	      X##_c = FP_CLS_ZERO;				\
Packit 6c4009
	      _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);		\
Packit 6c4009
	      FP_SET_EXCEPTION (FP_EX_DENORM);			\
Packit 6c4009
	    }							\
Packit 6c4009
	  else							\
Packit 6c4009
	    {							\
Packit 6c4009
	      /* A denormalized number.  */			\
Packit 6c4009
	      _FP_I_TYPE _FP_UNPACK_CANONICAL_shift;		\
Packit 6c4009
	      _FP_FRAC_CLZ_##wc (_FP_UNPACK_CANONICAL_shift,	\
Packit 6c4009
				 X);				\
Packit 6c4009
	      _FP_UNPACK_CANONICAL_shift -= _FP_FRACXBITS_##fs;	\
Packit 6c4009
	      _FP_FRAC_SLL_##wc (X, (_FP_UNPACK_CANONICAL_shift \
Packit 6c4009
				     + _FP_WORKBITS));		\
Packit 6c4009
	      X##_e -= (_FP_EXPBIAS_##fs - 1			\
Packit 6c4009
			+ _FP_UNPACK_CANONICAL_shift);		\
Packit 6c4009
	      X##_c = FP_CLS_NORMAL;				\
Packit 6c4009
	      FP_SET_EXCEPTION (FP_EX_DENORM);			\
Packit 6c4009
	    }							\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	case _FP_EXPMAX_##fs:					\
Packit 6c4009
	  if (_FP_FRAC_ZEROP_##wc (X))				\
Packit 6c4009
	    X##_c = FP_CLS_INF;					\
Packit 6c4009
	  else							\
Packit 6c4009
	    {							\
Packit 6c4009
	      X##_c = FP_CLS_NAN;				\
Packit 6c4009
	      /* Check for signaling NaN.  */			\
Packit 6c4009
	      if (_FP_FRAC_SNANP (fs, X))			\
Packit 6c4009
		FP_SET_EXCEPTION (FP_EX_INVALID			\
Packit 6c4009
				  | FP_EX_INVALID_SNAN);	\
Packit 6c4009
	    }							\
Packit 6c4009
	  break;						\
Packit 6c4009
	}							\
Packit 6c4009
    }								\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Finish unpacking an fp value in semi-raw mode: the mantissa is
Packit 6c4009
   shifted by _FP_WORKBITS but the implicit MSB is not inserted and
Packit 6c4009
   other classification is not done.  */
Packit 6c4009
#define _FP_UNPACK_SEMIRAW(fs, wc, X)	_FP_FRAC_SLL_##wc (X, _FP_WORKBITS)
Packit 6c4009
Packit 6c4009
/* Check whether a raw or semi-raw input value should be flushed to
Packit 6c4009
   zero, and flush it to zero if so.  */
Packit 6c4009
#define _FP_CHECK_FLUSH_ZERO(fs, wc, X)			\
Packit 6c4009
  do							\
Packit 6c4009
    {							\
Packit 6c4009
      if (FP_DENORM_ZERO				\
Packit 6c4009
	  && X##_e == 0					\
Packit 6c4009
	  && !_FP_FRAC_ZEROP_##wc (X))			\
Packit 6c4009
	{						\
Packit 6c4009
	  _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);	\
Packit 6c4009
	  FP_SET_EXCEPTION (FP_EX_DENORM);		\
Packit 6c4009
	}						\
Packit 6c4009
    }							\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* A semi-raw value has overflowed to infinity.  Adjust the mantissa
Packit 6c4009
   and exponent appropriately.  */
Packit 6c4009
#define _FP_OVERFLOW_SEMIRAW(fs, wc, X)			\
Packit 6c4009
  do							\
Packit 6c4009
    {							\
Packit 6c4009
      if (FP_ROUNDMODE == FP_RND_NEAREST		\
Packit 6c4009
	  || (FP_ROUNDMODE == FP_RND_PINF && !X##_s)	\
Packit 6c4009
	  || (FP_ROUNDMODE == FP_RND_MINF && X##_s))	\
Packit 6c4009
	{						\
Packit 6c4009
	  X##_e = _FP_EXPMAX_##fs;			\
Packit 6c4009
	  _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);	\
Packit 6c4009
	}						\
Packit 6c4009
      else						\
Packit 6c4009
	{						\
Packit 6c4009
	  X##_e = _FP_EXPMAX_##fs - 1;			\
Packit 6c4009
	  _FP_FRAC_SET_##wc (X, _FP_MAXFRAC_##wc);	\
Packit 6c4009
	}						\
Packit 6c4009
      FP_SET_EXCEPTION (FP_EX_INEXACT);			\
Packit 6c4009
      FP_SET_EXCEPTION (FP_EX_OVERFLOW);		\
Packit 6c4009
    }							\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Check for a semi-raw value being a signaling NaN and raise the
Packit 6c4009
   invalid exception if so.  */
Packit 6c4009
#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X)			\
Packit 6c4009
  do								\
Packit 6c4009
    {								\
Packit 6c4009
      if (X##_e == _FP_EXPMAX_##fs				\
Packit 6c4009
	  && !_FP_FRAC_ZEROP_##wc (X)				\
Packit 6c4009
	  && _FP_FRAC_SNANP_SEMIRAW (fs, X))			\
Packit 6c4009
	FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_SNAN);	\
Packit 6c4009
    }								\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Choose a NaN result from an operation on two semi-raw NaN
Packit 6c4009
   values.  */
Packit 6c4009
#define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP)			\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      /* _FP_CHOOSENAN expects raw values, so shift as required.  */	\
Packit 6c4009
      _FP_FRAC_SRL_##wc (X, _FP_WORKBITS);				\
Packit 6c4009
      _FP_FRAC_SRL_##wc (Y, _FP_WORKBITS);				\
Packit 6c4009
      _FP_CHOOSENAN (fs, wc, R, X, Y, OP);				\
Packit 6c4009
      _FP_FRAC_SLL_##wc (R, _FP_WORKBITS);				\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Make the fractional part a quiet NaN, preserving the payload
Packit 6c4009
   if possible, otherwise make it the canonical quiet NaN and set
Packit 6c4009
   the sign bit accordingly.  */
Packit 6c4009
#define _FP_SETQNAN(fs, wc, X)					\
Packit 6c4009
  do								\
Packit 6c4009
    {								\
Packit 6c4009
      if (_FP_QNANNEGATEDP)					\
Packit 6c4009
	{							\
Packit 6c4009
	  _FP_FRAC_HIGH_RAW_##fs (X) &= _FP_QNANBIT_##fs - 1;	\
Packit 6c4009
	  if (_FP_FRAC_ZEROP_##wc (X))				\
Packit 6c4009
	    {							\
Packit 6c4009
	      X##_s = _FP_NANSIGN_##fs;				\
Packit 6c4009
	      _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs);		\
Packit 6c4009
	    }							\
Packit 6c4009
	}							\
Packit 6c4009
      else							\
Packit 6c4009
	_FP_FRAC_HIGH_RAW_##fs (X) |= _FP_QNANBIT_##fs;		\
Packit 6c4009
    }								\
Packit 6c4009
  while (0)
Packit 6c4009
#define _FP_SETQNAN_SEMIRAW(fs, wc, X)				\
Packit 6c4009
  do								\
Packit 6c4009
    {								\
Packit 6c4009
      if (_FP_QNANNEGATEDP)					\
Packit 6c4009
	{							\
Packit 6c4009
	  _FP_FRAC_HIGH_##fs (X) &= _FP_QNANBIT_SH_##fs - 1;	\
Packit 6c4009
	  if (_FP_FRAC_ZEROP_##wc (X))				\
Packit 6c4009
	    {							\
Packit 6c4009
	      X##_s = _FP_NANSIGN_##fs;				\
Packit 6c4009
	      _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs);		\
Packit 6c4009
	      _FP_FRAC_SLL_##wc (X, _FP_WORKBITS);		\
Packit 6c4009
	    }							\
Packit 6c4009
	}							\
Packit 6c4009
      else							\
Packit 6c4009
	_FP_FRAC_HIGH_##fs (X) |= _FP_QNANBIT_SH_##fs;		\
Packit 6c4009
    }								\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Test whether a biased exponent is normal (not zero or maximum).  */
Packit 6c4009
#define _FP_EXP_NORMAL(fs, wc, X)	(((X##_e + 1) & _FP_EXPMAX_##fs) > 1)
Packit 6c4009
Packit 6c4009
/* Prepare to pack an fp value in semi-raw mode: the mantissa is
Packit 6c4009
   rounded and shifted right, with the rounding possibly increasing
Packit 6c4009
   the exponent (including changing a finite value to infinity).  */
Packit 6c4009
#define _FP_PACK_SEMIRAW(fs, wc, X)				\
Packit 6c4009
  do								\
Packit 6c4009
    {								\
Packit 6c4009
      int _FP_PACK_SEMIRAW_is_tiny				\
Packit 6c4009
	= X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X);		\
Packit 6c4009
      if (_FP_TININESS_AFTER_ROUNDING				\
Packit 6c4009
	  && _FP_PACK_SEMIRAW_is_tiny)				\
Packit 6c4009
	{							\
Packit 6c4009
	  FP_DECL_##fs (_FP_PACK_SEMIRAW_T);			\
Packit 6c4009
	  _FP_FRAC_COPY_##wc (_FP_PACK_SEMIRAW_T, X);		\
Packit 6c4009
	  _FP_PACK_SEMIRAW_T##_s = X##_s;			\
Packit 6c4009
	  _FP_PACK_SEMIRAW_T##_e = X##_e;			\
Packit 6c4009
	  _FP_FRAC_SLL_##wc (_FP_PACK_SEMIRAW_T, 1);		\
Packit 6c4009
	  _FP_ROUND (wc, _FP_PACK_SEMIRAW_T);			\
Packit 6c4009
	  if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_SEMIRAW_T))	\
Packit 6c4009
	    _FP_PACK_SEMIRAW_is_tiny = 0;			\
Packit 6c4009
	}							\
Packit 6c4009
      _FP_ROUND (wc, X);					\
Packit 6c4009
      if (_FP_PACK_SEMIRAW_is_tiny)				\
Packit 6c4009
	{							\
Packit 6c4009
	  if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT)		\
Packit 6c4009
	      || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))	\
Packit 6c4009
	    FP_SET_EXCEPTION (FP_EX_UNDERFLOW);			\
Packit 6c4009
	}							\
Packit 6c4009
      if (_FP_FRAC_HIGH_##fs (X)				\
Packit 6c4009
	  & (_FP_OVERFLOW_##fs >> 1))				\
Packit 6c4009
	{							\
Packit 6c4009
	  _FP_FRAC_HIGH_##fs (X) &= ~(_FP_OVERFLOW_##fs >> 1);	\
Packit 6c4009
	  X##_e++;						\
Packit 6c4009
	  if (X##_e == _FP_EXPMAX_##fs)				\
Packit 6c4009
	    _FP_OVERFLOW_SEMIRAW (fs, wc, X);			\
Packit 6c4009
	}							\
Packit 6c4009
      _FP_FRAC_SRL_##wc (X, _FP_WORKBITS);			\
Packit 6c4009
      if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X))	\
Packit 6c4009
	{							\
Packit 6c4009
	  if (!_FP_KEEPNANFRACP)				\
Packit 6c4009
	    {							\
Packit 6c4009
	      _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs);		\
Packit 6c4009
	      X##_s = _FP_NANSIGN_##fs;				\
Packit 6c4009
	    }							\
Packit 6c4009
	  else							\
Packit 6c4009
	    _FP_SETQNAN (fs, wc, X);				\
Packit 6c4009
	}							\
Packit 6c4009
    }								\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Before packing the bits back into the native fp result, take care
Packit 6c4009
   of such mundane things as rounding and overflow.  Also, for some
Packit 6c4009
   kinds of fp values, the original parts may not have been fully
Packit 6c4009
   extracted -- but that is ok, we can regenerate them now.  */
Packit 6c4009
Packit 6c4009
#define _FP_PACK_CANONICAL(fs, wc, X)					\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      switch (X##_c)							\
Packit 6c4009
	{								\
Packit 6c4009
	case FP_CLS_NORMAL:						\
Packit 6c4009
	  X##_e += _FP_EXPBIAS_##fs;					\
Packit 6c4009
	  if (X##_e > 0)						\
Packit 6c4009
	    {								\
Packit 6c4009
	      _FP_ROUND (wc, X);					\
Packit 6c4009
	      if (_FP_FRAC_OVERP_##wc (fs, X))				\
Packit 6c4009
		{							\
Packit 6c4009
		  _FP_FRAC_CLEAR_OVERP_##wc (fs, X);			\
Packit 6c4009
		  X##_e++;						\
Packit 6c4009
		}							\
Packit 6c4009
	      _FP_FRAC_SRL_##wc (X, _FP_WORKBITS);			\
Packit 6c4009
	      if (X##_e >= _FP_EXPMAX_##fs)				\
Packit 6c4009
		{							\
Packit 6c4009
		  /* Overflow.  */					\
Packit 6c4009
		  switch (FP_ROUNDMODE)					\
Packit 6c4009
		    {							\
Packit 6c4009
		    case FP_RND_NEAREST:				\
Packit 6c4009
		      X##_c = FP_CLS_INF;				\
Packit 6c4009
		      break;						\
Packit 6c4009
		    case FP_RND_PINF:					\
Packit 6c4009
		      if (!X##_s)					\
Packit 6c4009
			X##_c = FP_CLS_INF;				\
Packit 6c4009
		      break;						\
Packit 6c4009
		    case FP_RND_MINF:					\
Packit 6c4009
		      if (X##_s)					\
Packit 6c4009
			X##_c = FP_CLS_INF;				\
Packit 6c4009
		      break;						\
Packit 6c4009
		    }							\
Packit 6c4009
		  if (X##_c == FP_CLS_INF)				\
Packit 6c4009
		    {							\
Packit 6c4009
		      /* Overflow to infinity.  */			\
Packit 6c4009
		      X##_e = _FP_EXPMAX_##fs;				\
Packit 6c4009
		      _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);		\
Packit 6c4009
		    }							\
Packit 6c4009
		  else							\
Packit 6c4009
		    {							\
Packit 6c4009
		      /* Overflow to maximum normal.  */		\
Packit 6c4009
		      X##_e = _FP_EXPMAX_##fs - 1;			\
Packit 6c4009
		      _FP_FRAC_SET_##wc (X, _FP_MAXFRAC_##wc);		\
Packit 6c4009
		    }							\
Packit 6c4009
		  FP_SET_EXCEPTION (FP_EX_OVERFLOW);			\
Packit 6c4009
		  FP_SET_EXCEPTION (FP_EX_INEXACT);			\
Packit 6c4009
		}							\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      /* We've got a denormalized number.  */			\
Packit 6c4009
	      int _FP_PACK_CANONICAL_is_tiny = 1;			\
Packit 6c4009
	      if (_FP_TININESS_AFTER_ROUNDING && X##_e == 0)		\
Packit 6c4009
		{							\
Packit 6c4009
		  FP_DECL_##fs (_FP_PACK_CANONICAL_T);			\
Packit 6c4009
		  _FP_FRAC_COPY_##wc (_FP_PACK_CANONICAL_T, X);		\
Packit 6c4009
		  _FP_PACK_CANONICAL_T##_s = X##_s;			\
Packit 6c4009
		  _FP_PACK_CANONICAL_T##_e = X##_e;			\
Packit 6c4009
		  _FP_ROUND (wc, _FP_PACK_CANONICAL_T);			\
Packit 6c4009
		  if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_CANONICAL_T))	\
Packit 6c4009
		    _FP_PACK_CANONICAL_is_tiny = 0;			\
Packit 6c4009
		}							\
Packit 6c4009
	      X##_e = -X##_e + 1;					\
Packit 6c4009
	      if (X##_e <= _FP_WFRACBITS_##fs)				\
Packit 6c4009
		{							\
Packit 6c4009
		  _FP_FRAC_SRS_##wc (X, X##_e, _FP_WFRACBITS_##fs);	\
Packit 6c4009
		  _FP_ROUND (wc, X);					\
Packit 6c4009
		  if (_FP_FRAC_HIGH_##fs (X)				\
Packit 6c4009
		      & (_FP_OVERFLOW_##fs >> 1))			\
Packit 6c4009
		    {							\
Packit 6c4009
		      X##_e = 1;					\
Packit 6c4009
		      _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);		\
Packit 6c4009
		      FP_SET_EXCEPTION (FP_EX_INEXACT);			\
Packit 6c4009
		    }							\
Packit 6c4009
		  else							\
Packit 6c4009
		    {							\
Packit 6c4009
		      X##_e = 0;					\
Packit 6c4009
		      _FP_FRAC_SRL_##wc (X, _FP_WORKBITS);		\
Packit 6c4009
		    }							\
Packit 6c4009
		  if (_FP_PACK_CANONICAL_is_tiny			\
Packit 6c4009
		      && ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT)		\
Packit 6c4009
			  || (FP_TRAPPING_EXCEPTIONS			\
Packit 6c4009
			      & FP_EX_UNDERFLOW)))			\
Packit 6c4009
		    FP_SET_EXCEPTION (FP_EX_UNDERFLOW);			\
Packit 6c4009
		}							\
Packit 6c4009
	      else							\
Packit 6c4009
		{							\
Packit 6c4009
		  /* Underflow to zero.  */				\
Packit 6c4009
		  X##_e = 0;						\
Packit 6c4009
		  if (!_FP_FRAC_ZEROP_##wc (X))				\
Packit 6c4009
		    {							\
Packit 6c4009
		      _FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc);		\
Packit 6c4009
		      _FP_ROUND (wc, X);				\
Packit 6c4009
		      _FP_FRAC_LOW_##wc (X) >>= (_FP_WORKBITS);		\
Packit 6c4009
		    }							\
Packit 6c4009
		  FP_SET_EXCEPTION (FP_EX_UNDERFLOW);			\
Packit 6c4009
		}							\
Packit 6c4009
	    }								\
Packit 6c4009
	  break;							\
Packit 6c4009
									\
Packit 6c4009
	case FP_CLS_ZERO:						\
Packit 6c4009
	  X##_e = 0;							\
Packit 6c4009
	  _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);			\
Packit 6c4009
	  break;							\
Packit 6c4009
									\
Packit 6c4009
	case FP_CLS_INF:						\
Packit 6c4009
	  X##_e = _FP_EXPMAX_##fs;					\
Packit 6c4009
	  _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);			\
Packit 6c4009
	  break;							\
Packit 6c4009
									\
Packit 6c4009
	case FP_CLS_NAN:						\
Packit 6c4009
	  X##_e = _FP_EXPMAX_##fs;					\
Packit 6c4009
	  if (!_FP_KEEPNANFRACP)					\
Packit 6c4009
	    {								\
Packit 6c4009
	      _FP_FRAC_SET_##wc (X, _FP_NANFRAC_##fs);			\
Packit 6c4009
	      X##_s = _FP_NANSIGN_##fs;					\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    _FP_SETQNAN (fs, wc, X);					\
Packit 6c4009
	  break;							\
Packit 6c4009
	}								\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* This one accepts raw argument and not cooked,  returns
Packit 6c4009
   1 if X is a signaling NaN.  */
Packit 6c4009
#define _FP_ISSIGNAN(fs, wc, X)			\
Packit 6c4009
  ({						\
Packit 6c4009
    int _FP_ISSIGNAN_ret = 0;			\
Packit 6c4009
    if (X##_e == _FP_EXPMAX_##fs)		\
Packit 6c4009
      {						\
Packit 6c4009
	if (!_FP_FRAC_ZEROP_##wc (X)		\
Packit 6c4009
	    && _FP_FRAC_SNANP (fs, X))		\
Packit 6c4009
	  _FP_ISSIGNAN_ret = 1;			\
Packit 6c4009
      }						\
Packit 6c4009
    _FP_ISSIGNAN_ret;				\
Packit 6c4009
  })
Packit 6c4009
Packit 6c4009
Packit 6c4009
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Addition on semi-raw values.  */
Packit 6c4009
#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP)				\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      _FP_CHECK_FLUSH_ZERO (fs, wc, X);					\
Packit 6c4009
      _FP_CHECK_FLUSH_ZERO (fs, wc, Y);					\
Packit 6c4009
      if (X##_s == Y##_s)						\
Packit 6c4009
	{								\
Packit 6c4009
	  /* Addition.  */						\
Packit 6c4009
	  __label__ add1, add2, add3, add_done;				\
Packit 6c4009
	  R##_s = X##_s;						\
Packit 6c4009
	  int _FP_ADD_INTERNAL_ediff = X##_e - Y##_e;			\
Packit 6c4009
	  if (_FP_ADD_INTERNAL_ediff > 0)				\
Packit 6c4009
	    {								\
Packit 6c4009
	      R##_e = X##_e;						\
Packit 6c4009
	      if (Y##_e == 0)						\
Packit 6c4009
		{							\
Packit 6c4009
		  /* Y is zero or denormalized.  */			\
Packit 6c4009
		  if (_FP_FRAC_ZEROP_##wc (Y))				\
Packit 6c4009
		    {							\
Packit 6c4009
		      _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);		\
Packit 6c4009
		      _FP_FRAC_COPY_##wc (R, X);			\
Packit 6c4009
		      goto add_done;					\
Packit 6c4009
		    }							\
Packit 6c4009
		  else							\
Packit 6c4009
		    {							\
Packit 6c4009
		      FP_SET_EXCEPTION (FP_EX_DENORM);			\
Packit 6c4009
		      _FP_ADD_INTERNAL_ediff--;				\
Packit 6c4009
		      if (_FP_ADD_INTERNAL_ediff == 0)			\
Packit 6c4009
			{						\
Packit 6c4009
			  _FP_FRAC_ADD_##wc (R, X, Y);			\
Packit 6c4009
			  goto add3;					\
Packit 6c4009
			}						\
Packit 6c4009
		      if (X##_e == _FP_EXPMAX_##fs)			\
Packit 6c4009
			{						\
Packit 6c4009
			  _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);		\
Packit 6c4009
			  _FP_FRAC_COPY_##wc (R, X);			\
Packit 6c4009
			  goto add_done;				\
Packit 6c4009
			}						\
Packit 6c4009
		      goto add1;					\
Packit 6c4009
		    }							\
Packit 6c4009
		}							\
Packit 6c4009
	      else if (X##_e == _FP_EXPMAX_##fs)			\
Packit 6c4009
		{							\
Packit 6c4009
		  /* X is NaN or Inf, Y is normal.  */			\
Packit 6c4009
		  _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);			\
Packit 6c4009
		  _FP_FRAC_COPY_##wc (R, X);				\
Packit 6c4009
		  goto add_done;					\
Packit 6c4009
		}							\
Packit 6c4009
									\
Packit 6c4009
	      /* Insert implicit MSB of Y.  */				\
Packit 6c4009
	      _FP_FRAC_HIGH_##fs (Y) |= _FP_IMPLBIT_SH_##fs;		\
Packit 6c4009
									\
Packit 6c4009
	    add1:							\
Packit 6c4009
	      /* Shift the mantissa of Y to the right			\
Packit 6c4009
		 _FP_ADD_INTERNAL_EDIFF steps; remember to account	\
Packit 6c4009
		 later for the implicit MSB of X.  */			\
Packit 6c4009
	      if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs)		\
Packit 6c4009
		_FP_FRAC_SRS_##wc (Y, _FP_ADD_INTERNAL_ediff,		\
Packit 6c4009
				   _FP_WFRACBITS_##fs);			\
Packit 6c4009
	      else if (!_FP_FRAC_ZEROP_##wc (Y))			\
Packit 6c4009
		_FP_FRAC_SET_##wc (Y, _FP_MINFRAC_##wc);		\
Packit 6c4009
	      _FP_FRAC_ADD_##wc (R, X, Y);				\
Packit 6c4009
	    }								\
Packit 6c4009
	  else if (_FP_ADD_INTERNAL_ediff < 0)				\
Packit 6c4009
	    {								\
Packit 6c4009
	      _FP_ADD_INTERNAL_ediff = -_FP_ADD_INTERNAL_ediff;		\
Packit 6c4009
	      R##_e = Y##_e;						\
Packit 6c4009
	      if (X##_e == 0)						\
Packit 6c4009
		{							\
Packit 6c4009
		  /* X is zero or denormalized.  */			\
Packit 6c4009
		  if (_FP_FRAC_ZEROP_##wc (X))				\
Packit 6c4009
		    {							\
Packit 6c4009
		      _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);		\
Packit 6c4009
		      _FP_FRAC_COPY_##wc (R, Y);			\
Packit 6c4009
		      goto add_done;					\
Packit 6c4009
		    }							\
Packit 6c4009
		  else							\
Packit 6c4009
		    {							\
Packit 6c4009
		      FP_SET_EXCEPTION (FP_EX_DENORM);			\
Packit 6c4009
		      _FP_ADD_INTERNAL_ediff--;				\
Packit 6c4009
		      if (_FP_ADD_INTERNAL_ediff == 0)			\
Packit 6c4009
			{						\
Packit 6c4009
			  _FP_FRAC_ADD_##wc (R, Y, X);			\
Packit 6c4009
			  goto add3;					\
Packit 6c4009
			}						\
Packit 6c4009
		      if (Y##_e == _FP_EXPMAX_##fs)			\
Packit 6c4009
			{						\
Packit 6c4009
			  _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);		\
Packit 6c4009
			  _FP_FRAC_COPY_##wc (R, Y);			\
Packit 6c4009
			  goto add_done;				\
Packit 6c4009
			}						\
Packit 6c4009
		      goto add2;					\
Packit 6c4009
		    }							\
Packit 6c4009
		}							\
Packit 6c4009
	      else if (Y##_e == _FP_EXPMAX_##fs)			\
Packit 6c4009
		{							\
Packit 6c4009
		  /* Y is NaN or Inf, X is normal.  */			\
Packit 6c4009
		  _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);			\
Packit 6c4009
		  _FP_FRAC_COPY_##wc (R, Y);				\
Packit 6c4009
		  goto add_done;					\
Packit 6c4009
		}							\
Packit 6c4009
									\
Packit 6c4009
	      /* Insert implicit MSB of X.  */				\
Packit 6c4009
	      _FP_FRAC_HIGH_##fs (X) |= _FP_IMPLBIT_SH_##fs;		\
Packit 6c4009
									\
Packit 6c4009
	    add2:							\
Packit 6c4009
	      /* Shift the mantissa of X to the right			\
Packit 6c4009
		 _FP_ADD_INTERNAL_EDIFF steps; remember to account	\
Packit 6c4009
		 later for the implicit MSB of Y.  */			\
Packit 6c4009
	      if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs)		\
Packit 6c4009
		_FP_FRAC_SRS_##wc (X, _FP_ADD_INTERNAL_ediff,		\
Packit 6c4009
				   _FP_WFRACBITS_##fs);			\
Packit 6c4009
	      else if (!_FP_FRAC_ZEROP_##wc (X))			\
Packit 6c4009
		_FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc);		\
Packit 6c4009
	      _FP_FRAC_ADD_##wc (R, Y, X);				\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      /* _FP_ADD_INTERNAL_ediff == 0.  */			\
Packit 6c4009
	      if (!_FP_EXP_NORMAL (fs, wc, X))				\
Packit 6c4009
		{							\
Packit 6c4009
		  if (X##_e == 0)					\
Packit 6c4009
		    {							\
Packit 6c4009
		      /* X and Y are zero or denormalized.  */		\
Packit 6c4009
		      R##_e = 0;					\
Packit 6c4009
		      if (_FP_FRAC_ZEROP_##wc (X))			\
Packit 6c4009
			{						\
Packit 6c4009
			  if (!_FP_FRAC_ZEROP_##wc (Y))			\
Packit 6c4009
			    FP_SET_EXCEPTION (FP_EX_DENORM);		\
Packit 6c4009
			  _FP_FRAC_COPY_##wc (R, Y);			\
Packit 6c4009
			  goto add_done;				\
Packit 6c4009
			}						\
Packit 6c4009
		      else if (_FP_FRAC_ZEROP_##wc (Y))			\
Packit 6c4009
			{						\
Packit 6c4009
			  FP_SET_EXCEPTION (FP_EX_DENORM);		\
Packit 6c4009
			  _FP_FRAC_COPY_##wc (R, X);			\
Packit 6c4009
			  goto add_done;				\
Packit 6c4009
			}						\
Packit 6c4009
		      else						\
Packit 6c4009
			{						\
Packit 6c4009
			  FP_SET_EXCEPTION (FP_EX_DENORM);		\
Packit 6c4009
			  _FP_FRAC_ADD_##wc (R, X, Y);			\
Packit 6c4009
			  if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
Packit 6c4009
			    {						\
Packit 6c4009
			      /* Normalized result.  */			\
Packit 6c4009
			      _FP_FRAC_HIGH_##fs (R)			\
Packit 6c4009
				&= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs;	\
Packit 6c4009
			      R##_e = 1;				\
Packit 6c4009
			    }						\
Packit 6c4009
			  goto add_done;				\
Packit 6c4009
			}						\
Packit 6c4009
		    }							\
Packit 6c4009
		  else							\
Packit 6c4009
		    {							\
Packit 6c4009
		      /* X and Y are NaN or Inf.  */			\
Packit 6c4009
		      _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);		\
Packit 6c4009
		      _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);		\
Packit 6c4009
		      R##_e = _FP_EXPMAX_##fs;				\
Packit 6c4009
		      if (_FP_FRAC_ZEROP_##wc (X))			\
Packit 6c4009
			_FP_FRAC_COPY_##wc (R, Y);			\
Packit 6c4009
		      else if (_FP_FRAC_ZEROP_##wc (Y))			\
Packit 6c4009
			_FP_FRAC_COPY_##wc (R, X);			\
Packit 6c4009
		      else						\
Packit 6c4009
			_FP_CHOOSENAN_SEMIRAW (fs, wc, R, X, Y, OP);	\
Packit 6c4009
		      goto add_done;					\
Packit 6c4009
		    }							\
Packit 6c4009
		}							\
Packit 6c4009
	      /* The exponents of X and Y, both normal, are equal.  The	\
Packit 6c4009
		 implicit MSBs will always add to increase the		\
Packit 6c4009
		 exponent.  */						\
Packit 6c4009
	      _FP_FRAC_ADD_##wc (R, X, Y);				\
Packit 6c4009
	      R##_e = X##_e + 1;					\
Packit 6c4009
	      _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs);		\
Packit 6c4009
	      if (R##_e == _FP_EXPMAX_##fs)				\
Packit 6c4009
		/* Overflow to infinity (depending on rounding mode).  */ \
Packit 6c4009
		_FP_OVERFLOW_SEMIRAW (fs, wc, R);			\
Packit 6c4009
	      goto add_done;						\
Packit 6c4009
	    }								\
Packit 6c4009
	add3:								\
Packit 6c4009
	  if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs)		\
Packit 6c4009
	    {								\
Packit 6c4009
	      /* Overflow.  */						\
Packit 6c4009
	      _FP_FRAC_HIGH_##fs (R) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
Packit 6c4009
	      R##_e++;							\
Packit 6c4009
	      _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs);		\
Packit 6c4009
	      if (R##_e == _FP_EXPMAX_##fs)				\
Packit 6c4009
		/* Overflow to infinity (depending on rounding mode).  */ \
Packit 6c4009
		_FP_OVERFLOW_SEMIRAW (fs, wc, R);			\
Packit 6c4009
	    }								\
Packit 6c4009
	add_done: ;							\
Packit 6c4009
	}								\
Packit 6c4009
      else								\
Packit 6c4009
	{								\
Packit 6c4009
	  /* Subtraction.  */						\
Packit 6c4009
	  __label__ sub1, sub2, sub3, norm, sub_done;			\
Packit 6c4009
	  int _FP_ADD_INTERNAL_ediff = X##_e - Y##_e;			\
Packit 6c4009
	  if (_FP_ADD_INTERNAL_ediff > 0)				\
Packit 6c4009
	    {								\
Packit 6c4009
	      R##_e = X##_e;						\
Packit 6c4009
	      R##_s = X##_s;						\
Packit 6c4009
	      if (Y##_e == 0)						\
Packit 6c4009
		{							\
Packit 6c4009
		  /* Y is zero or denormalized.  */			\
Packit 6c4009
		  if (_FP_FRAC_ZEROP_##wc (Y))				\
Packit 6c4009
		    {							\
Packit 6c4009
		      _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);		\
Packit 6c4009
		      _FP_FRAC_COPY_##wc (R, X);			\
Packit 6c4009
		      goto sub_done;					\
Packit 6c4009
		    }							\
Packit 6c4009
		  else							\
Packit 6c4009
		    {							\
Packit 6c4009
		      FP_SET_EXCEPTION (FP_EX_DENORM);			\
Packit 6c4009
		      _FP_ADD_INTERNAL_ediff--;				\
Packit 6c4009
		      if (_FP_ADD_INTERNAL_ediff == 0)			\
Packit 6c4009
			{						\
Packit 6c4009
			  _FP_FRAC_SUB_##wc (R, X, Y);			\
Packit 6c4009
			  goto sub3;					\
Packit 6c4009
			}						\
Packit 6c4009
		      if (X##_e == _FP_EXPMAX_##fs)			\
Packit 6c4009
			{						\
Packit 6c4009
			  _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);		\
Packit 6c4009
			  _FP_FRAC_COPY_##wc (R, X);			\
Packit 6c4009
			  goto sub_done;				\
Packit 6c4009
			}						\
Packit 6c4009
		      goto sub1;					\
Packit 6c4009
		    }							\
Packit 6c4009
		}							\
Packit 6c4009
	      else if (X##_e == _FP_EXPMAX_##fs)			\
Packit 6c4009
		{							\
Packit 6c4009
		  /* X is NaN or Inf, Y is normal.  */			\
Packit 6c4009
		  _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);			\
Packit 6c4009
		  _FP_FRAC_COPY_##wc (R, X);				\
Packit 6c4009
		  goto sub_done;					\
Packit 6c4009
		}							\
Packit 6c4009
									\
Packit 6c4009
	      /* Insert implicit MSB of Y.  */				\
Packit 6c4009
	      _FP_FRAC_HIGH_##fs (Y) |= _FP_IMPLBIT_SH_##fs;		\
Packit 6c4009
									\
Packit 6c4009
	    sub1:							\
Packit 6c4009
	      /* Shift the mantissa of Y to the right			\
Packit 6c4009
		 _FP_ADD_INTERNAL_EDIFF steps; remember to account	\
Packit 6c4009
		 later for the implicit MSB of X.  */			\
Packit 6c4009
	      if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs)		\
Packit 6c4009
		_FP_FRAC_SRS_##wc (Y, _FP_ADD_INTERNAL_ediff,		\
Packit 6c4009
				   _FP_WFRACBITS_##fs);			\
Packit 6c4009
	      else if (!_FP_FRAC_ZEROP_##wc (Y))			\
Packit 6c4009
		_FP_FRAC_SET_##wc (Y, _FP_MINFRAC_##wc);		\
Packit 6c4009
	      _FP_FRAC_SUB_##wc (R, X, Y);				\
Packit 6c4009
	    }								\
Packit 6c4009
	  else if (_FP_ADD_INTERNAL_ediff < 0)				\
Packit 6c4009
	    {								\
Packit 6c4009
	      _FP_ADD_INTERNAL_ediff = -_FP_ADD_INTERNAL_ediff;		\
Packit 6c4009
	      R##_e = Y##_e;						\
Packit 6c4009
	      R##_s = Y##_s;						\
Packit 6c4009
	      if (X##_e == 0)						\
Packit 6c4009
		{							\
Packit 6c4009
		  /* X is zero or denormalized.  */			\
Packit 6c4009
		  if (_FP_FRAC_ZEROP_##wc (X))				\
Packit 6c4009
		    {							\
Packit 6c4009
		      _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);		\
Packit 6c4009
		      _FP_FRAC_COPY_##wc (R, Y);			\
Packit 6c4009
		      goto sub_done;					\
Packit 6c4009
		    }							\
Packit 6c4009
		  else							\
Packit 6c4009
		    {							\
Packit 6c4009
		      FP_SET_EXCEPTION (FP_EX_DENORM);			\
Packit 6c4009
		      _FP_ADD_INTERNAL_ediff--;				\
Packit 6c4009
		      if (_FP_ADD_INTERNAL_ediff == 0)			\
Packit 6c4009
			{						\
Packit 6c4009
			  _FP_FRAC_SUB_##wc (R, Y, X);			\
Packit 6c4009
			  goto sub3;					\
Packit 6c4009
			}						\
Packit 6c4009
		      if (Y##_e == _FP_EXPMAX_##fs)			\
Packit 6c4009
			{						\
Packit 6c4009
			  _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);		\
Packit 6c4009
			  _FP_FRAC_COPY_##wc (R, Y);			\
Packit 6c4009
			  goto sub_done;				\
Packit 6c4009
			}						\
Packit 6c4009
		      goto sub2;					\
Packit 6c4009
		    }							\
Packit 6c4009
		}							\
Packit 6c4009
	      else if (Y##_e == _FP_EXPMAX_##fs)			\
Packit 6c4009
		{							\
Packit 6c4009
		  /* Y is NaN or Inf, X is normal.  */			\
Packit 6c4009
		  _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);			\
Packit 6c4009
		  _FP_FRAC_COPY_##wc (R, Y);				\
Packit 6c4009
		  goto sub_done;					\
Packit 6c4009
		}							\
Packit 6c4009
									\
Packit 6c4009
	      /* Insert implicit MSB of X.  */				\
Packit 6c4009
	      _FP_FRAC_HIGH_##fs (X) |= _FP_IMPLBIT_SH_##fs;		\
Packit 6c4009
									\
Packit 6c4009
	    sub2:							\
Packit 6c4009
	      /* Shift the mantissa of X to the right			\
Packit 6c4009
		 _FP_ADD_INTERNAL_EDIFF steps; remember to account	\
Packit 6c4009
		 later for the implicit MSB of Y.  */			\
Packit 6c4009
	      if (_FP_ADD_INTERNAL_ediff <= _FP_WFRACBITS_##fs)		\
Packit 6c4009
		_FP_FRAC_SRS_##wc (X, _FP_ADD_INTERNAL_ediff,		\
Packit 6c4009
				   _FP_WFRACBITS_##fs);			\
Packit 6c4009
	      else if (!_FP_FRAC_ZEROP_##wc (X))			\
Packit 6c4009
		_FP_FRAC_SET_##wc (X, _FP_MINFRAC_##wc);		\
Packit 6c4009
	      _FP_FRAC_SUB_##wc (R, Y, X);				\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      /* ediff == 0.  */					\
Packit 6c4009
	      if (!_FP_EXP_NORMAL (fs, wc, X))				\
Packit 6c4009
		{							\
Packit 6c4009
		  if (X##_e == 0)					\
Packit 6c4009
		    {							\
Packit 6c4009
		      /* X and Y are zero or denormalized.  */		\
Packit 6c4009
		      R##_e = 0;					\
Packit 6c4009
		      if (_FP_FRAC_ZEROP_##wc (X))			\
Packit 6c4009
			{						\
Packit 6c4009
			  _FP_FRAC_COPY_##wc (R, Y);			\
Packit 6c4009
			  if (_FP_FRAC_ZEROP_##wc (Y))			\
Packit 6c4009
			    R##_s = (FP_ROUNDMODE == FP_RND_MINF);	\
Packit 6c4009
			  else						\
Packit 6c4009
			    {						\
Packit 6c4009
			      FP_SET_EXCEPTION (FP_EX_DENORM);		\
Packit 6c4009
			      R##_s = Y##_s;				\
Packit 6c4009
			    }						\
Packit 6c4009
			  goto sub_done;				\
Packit 6c4009
			}						\
Packit 6c4009
		      else if (_FP_FRAC_ZEROP_##wc (Y))			\
Packit 6c4009
			{						\
Packit 6c4009
			  FP_SET_EXCEPTION (FP_EX_DENORM);		\
Packit 6c4009
			  _FP_FRAC_COPY_##wc (R, X);			\
Packit 6c4009
			  R##_s = X##_s;				\
Packit 6c4009
			  goto sub_done;				\
Packit 6c4009
			}						\
Packit 6c4009
		      else						\
Packit 6c4009
			{						\
Packit 6c4009
			  FP_SET_EXCEPTION (FP_EX_DENORM);		\
Packit 6c4009
			  _FP_FRAC_SUB_##wc (R, X, Y);			\
Packit 6c4009
			  R##_s = X##_s;				\
Packit 6c4009
			  if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs) \
Packit 6c4009
			    {						\
Packit 6c4009
			      /* |X| < |Y|, negate result.  */		\
Packit 6c4009
			      _FP_FRAC_SUB_##wc (R, Y, X);		\
Packit 6c4009
			      R##_s = Y##_s;				\
Packit 6c4009
			    }						\
Packit 6c4009
			  else if (_FP_FRAC_ZEROP_##wc (R))		\
Packit 6c4009
			    R##_s = (FP_ROUNDMODE == FP_RND_MINF);	\
Packit 6c4009
			  goto sub_done;				\
Packit 6c4009
			}						\
Packit 6c4009
		    }							\
Packit 6c4009
		  else							\
Packit 6c4009
		    {							\
Packit 6c4009
		      /* X and Y are NaN or Inf, of opposite signs.  */	\
Packit 6c4009
		      _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, X);		\
Packit 6c4009
		      _FP_CHECK_SIGNAN_SEMIRAW (fs, wc, Y);		\
Packit 6c4009
		      R##_e = _FP_EXPMAX_##fs;				\
Packit 6c4009
		      if (_FP_FRAC_ZEROP_##wc (X))			\
Packit 6c4009
			{						\
Packit 6c4009
			  if (_FP_FRAC_ZEROP_##wc (Y))			\
Packit 6c4009
			    {						\
Packit 6c4009
			      /* Inf - Inf.  */				\
Packit 6c4009
			      R##_s = _FP_NANSIGN_##fs;			\
Packit 6c4009
			      _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs);	\
Packit 6c4009
			      _FP_FRAC_SLL_##wc (R, _FP_WORKBITS);	\
Packit 6c4009
			      FP_SET_EXCEPTION (FP_EX_INVALID		\
Packit 6c4009
						| FP_EX_INVALID_ISI);	\
Packit 6c4009
			    }						\
Packit 6c4009
			  else						\
Packit 6c4009
			    {						\
Packit 6c4009
			      /* Inf - NaN.  */				\
Packit 6c4009
			      R##_s = Y##_s;				\
Packit 6c4009
			      _FP_FRAC_COPY_##wc (R, Y);		\
Packit 6c4009
			    }						\
Packit 6c4009
			}						\
Packit 6c4009
		      else						\
Packit 6c4009
			{						\
Packit 6c4009
			  if (_FP_FRAC_ZEROP_##wc (Y))			\
Packit 6c4009
			    {						\
Packit 6c4009
			      /* NaN - Inf.  */				\
Packit 6c4009
			      R##_s = X##_s;				\
Packit 6c4009
			      _FP_FRAC_COPY_##wc (R, X);		\
Packit 6c4009
			    }						\
Packit 6c4009
			  else						\
Packit 6c4009
			    {						\
Packit 6c4009
			      /* NaN - NaN.  */				\
Packit 6c4009
			      _FP_CHOOSENAN_SEMIRAW (fs, wc, R, X, Y, OP); \
Packit 6c4009
			    }						\
Packit 6c4009
			}						\
Packit 6c4009
		      goto sub_done;					\
Packit 6c4009
		    }							\
Packit 6c4009
		}							\
Packit 6c4009
	      /* The exponents of X and Y, both normal, are equal.  The	\
Packit 6c4009
		 implicit MSBs cancel.  */				\
Packit 6c4009
	      R##_e = X##_e;						\
Packit 6c4009
	      _FP_FRAC_SUB_##wc (R, X, Y);				\
Packit 6c4009
	      R##_s = X##_s;						\
Packit 6c4009
	      if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs)		\
Packit 6c4009
		{							\
Packit 6c4009
		  /* |X| < |Y|, negate result.  */			\
Packit 6c4009
		  _FP_FRAC_SUB_##wc (R, Y, X);				\
Packit 6c4009
		  R##_s = Y##_s;					\
Packit 6c4009
		}							\
Packit 6c4009
	      else if (_FP_FRAC_ZEROP_##wc (R))				\
Packit 6c4009
		{							\
Packit 6c4009
		  R##_e = 0;						\
Packit 6c4009
		  R##_s = (FP_ROUNDMODE == FP_RND_MINF);		\
Packit 6c4009
		  goto sub_done;					\
Packit 6c4009
		}							\
Packit 6c4009
	      goto norm;						\
Packit 6c4009
	    }								\
Packit 6c4009
	sub3:								\
Packit 6c4009
	  if (_FP_FRAC_HIGH_##fs (R) & _FP_IMPLBIT_SH_##fs)		\
Packit 6c4009
	    {								\
Packit 6c4009
	      int _FP_ADD_INTERNAL_diff;				\
Packit 6c4009
	      /* Carry into most significant bit of larger one of X and Y, \
Packit 6c4009
		 canceling it; renormalize.  */				\
Packit 6c4009
	      _FP_FRAC_HIGH_##fs (R) &= _FP_IMPLBIT_SH_##fs - 1;	\
Packit 6c4009
	    norm:							\
Packit 6c4009
	      _FP_FRAC_CLZ_##wc (_FP_ADD_INTERNAL_diff, R);		\
Packit 6c4009
	      _FP_ADD_INTERNAL_diff -= _FP_WFRACXBITS_##fs;		\
Packit 6c4009
	      _FP_FRAC_SLL_##wc (R, _FP_ADD_INTERNAL_diff);		\
Packit 6c4009
	      if (R##_e <= _FP_ADD_INTERNAL_diff)			\
Packit 6c4009
		{							\
Packit 6c4009
		  /* R is denormalized.  */				\
Packit 6c4009
		  _FP_ADD_INTERNAL_diff					\
Packit 6c4009
		    = _FP_ADD_INTERNAL_diff - R##_e + 1;		\
Packit 6c4009
		  _FP_FRAC_SRS_##wc (R, _FP_ADD_INTERNAL_diff,		\
Packit 6c4009
				     _FP_WFRACBITS_##fs);		\
Packit 6c4009
		  R##_e = 0;						\
Packit 6c4009
		}							\
Packit 6c4009
	      else							\
Packit 6c4009
		{							\
Packit 6c4009
		  R##_e -= _FP_ADD_INTERNAL_diff;			\
Packit 6c4009
		  _FP_FRAC_HIGH_##fs (R) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
Packit 6c4009
		}							\
Packit 6c4009
	    }								\
Packit 6c4009
	sub_done: ;							\
Packit 6c4009
	}								\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL (fs, wc, R, X, Y, '+')
Packit 6c4009
#define _FP_SUB(fs, wc, R, X, Y)					\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y)))	\
Packit 6c4009
	Y##_s ^= 1;							\
Packit 6c4009
      _FP_ADD_INTERNAL (fs, wc, R, X, Y, '-');				\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Main negation routine.  The input value is raw.  */
Packit 6c4009
Packit 6c4009
#define _FP_NEG(fs, wc, R, X)			\
Packit 6c4009
  do						\
Packit 6c4009
    {						\
Packit 6c4009
      _FP_FRAC_COPY_##wc (R, X);		\
Packit 6c4009
      R##_e = X##_e;				\
Packit 6c4009
      R##_s = 1 ^ X##_s;			\
Packit 6c4009
    }						\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Main multiplication routine.  The input values should be cooked.  */
Packit 6c4009
Packit 6c4009
#define _FP_MUL(fs, wc, R, X, Y)				\
Packit 6c4009
  do								\
Packit 6c4009
    {								\
Packit 6c4009
      R##_s = X##_s ^ Y##_s;					\
Packit 6c4009
      R##_e = X##_e + Y##_e + 1;				\
Packit 6c4009
      switch (_FP_CLS_COMBINE (X##_c, Y##_c))			\
Packit 6c4009
	{							\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL):	\
Packit 6c4009
	  R##_c = FP_CLS_NORMAL;				\
Packit 6c4009
								\
Packit 6c4009
	  _FP_MUL_MEAT_##fs (R, X, Y);				\
Packit 6c4009
								\
Packit 6c4009
	  if (_FP_FRAC_OVERP_##wc (fs, R))			\
Packit 6c4009
	    _FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs);	\
Packit 6c4009
	  else							\
Packit 6c4009
	    R##_e--;						\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN):		\
Packit 6c4009
	  _FP_CHOOSENAN (fs, wc, R, X, Y, '*');			\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL):	\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO):		\
Packit 6c4009
	  R##_s = X##_s;					\
Packit 6c4009
	  /* FALLTHRU */					\
Packit 6c4009
								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL):	\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL):	\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO):	\
Packit 6c4009
	  _FP_FRAC_COPY_##wc (R, X);				\
Packit 6c4009
	  R##_c = X##_c;					\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN):	\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN):		\
Packit 6c4009
	  R##_s = Y##_s;					\
Packit 6c4009
	  /* FALLTHRU */					\
Packit 6c4009
								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF):	\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO):	\
Packit 6c4009
	  _FP_FRAC_COPY_##wc (R, Y);				\
Packit 6c4009
	  R##_c = Y##_c;					\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF):		\
Packit 6c4009
	  R##_s = _FP_NANSIGN_##fs;				\
Packit 6c4009
	  R##_c = FP_CLS_NAN;					\
Packit 6c4009
	  _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs);		\
Packit 6c4009
	  FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_IMZ);	\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	default:						\
Packit 6c4009
	  _FP_UNREACHABLE;					\
Packit 6c4009
	}							\
Packit 6c4009
    }								\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Fused multiply-add.  The input values should be cooked.  */
Packit 6c4009
Packit 6c4009
#define _FP_FMA(fs, wc, dwc, R, X, Y, Z)				\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      __label__ done_fma;						\
Packit 6c4009
      FP_DECL_##fs (_FP_FMA_T);						\
Packit 6c4009
      _FP_FMA_T##_s = X##_s ^ Y##_s;					\
Packit 6c4009
      _FP_FMA_T##_e = X##_e + Y##_e + 1;				\
Packit 6c4009
      switch (_FP_CLS_COMBINE (X##_c, Y##_c))				\
Packit 6c4009
	{								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL):		\
Packit 6c4009
	  switch (Z##_c)						\
Packit 6c4009
	    {								\
Packit 6c4009
	    case FP_CLS_INF:						\
Packit 6c4009
	    case FP_CLS_NAN:						\
Packit 6c4009
	      R##_s = Z##_s;						\
Packit 6c4009
	      _FP_FRAC_COPY_##wc (R, Z);				\
Packit 6c4009
	      R##_c = Z##_c;						\
Packit 6c4009
	      break;							\
Packit 6c4009
									\
Packit 6c4009
	    case FP_CLS_ZERO:						\
Packit 6c4009
	      R##_c = FP_CLS_NORMAL;					\
Packit 6c4009
	      R##_s = _FP_FMA_T##_s;					\
Packit 6c4009
	      R##_e = _FP_FMA_T##_e;					\
Packit 6c4009
									\
Packit 6c4009
	      _FP_MUL_MEAT_##fs (R, X, Y);				\
Packit 6c4009
									\
Packit 6c4009
	      if (_FP_FRAC_OVERP_##wc (fs, R))				\
Packit 6c4009
		_FP_FRAC_SRS_##wc (R, 1, _FP_WFRACBITS_##fs);		\
Packit 6c4009
	      else							\
Packit 6c4009
		R##_e--;						\
Packit 6c4009
	      break;							\
Packit 6c4009
									\
Packit 6c4009
	    case FP_CLS_NORMAL:;					\
Packit 6c4009
	      _FP_FRAC_DECL_##dwc (_FP_FMA_TD);				\
Packit 6c4009
	      _FP_FRAC_DECL_##dwc (_FP_FMA_ZD);				\
Packit 6c4009
	      _FP_FRAC_DECL_##dwc (_FP_FMA_RD);				\
Packit 6c4009
	      _FP_MUL_MEAT_DW_##fs (_FP_FMA_TD, X, Y);			\
Packit 6c4009
	      R##_e = _FP_FMA_T##_e;					\
Packit 6c4009
	      int _FP_FMA_tsh						\
Packit 6c4009
		= _FP_FRAC_HIGHBIT_DW_##dwc (fs, _FP_FMA_TD) == 0;	\
Packit 6c4009
	      _FP_FMA_T##_e -= _FP_FMA_tsh;				\
Packit 6c4009
	      int _FP_FMA_ediff = _FP_FMA_T##_e - Z##_e;		\
Packit 6c4009
	      if (_FP_FMA_ediff >= 0)					\
Packit 6c4009
		{							\
Packit 6c4009
		  int _FP_FMA_shift					\
Packit 6c4009
		    = _FP_WFRACBITS_##fs - _FP_FMA_tsh - _FP_FMA_ediff;	\
Packit 6c4009
		  if (_FP_FMA_shift <= -_FP_WFRACBITS_##fs)		\
Packit 6c4009
		    _FP_FRAC_SET_##dwc (_FP_FMA_ZD, _FP_MINFRAC_##dwc);	\
Packit 6c4009
		  else							\
Packit 6c4009
		    {							\
Packit 6c4009
		      _FP_FRAC_COPY_##dwc##_##wc (_FP_FMA_ZD, Z);	\
Packit 6c4009
		      if (_FP_FMA_shift < 0)				\
Packit 6c4009
			_FP_FRAC_SRS_##dwc (_FP_FMA_ZD, -_FP_FMA_shift,	\
Packit 6c4009
					    _FP_WFRACBITS_DW_##fs);	\
Packit 6c4009
		      else if (_FP_FMA_shift > 0)			\
Packit 6c4009
			_FP_FRAC_SLL_##dwc (_FP_FMA_ZD, _FP_FMA_shift);	\
Packit 6c4009
		    }							\
Packit 6c4009
		  R##_s = _FP_FMA_T##_s;				\
Packit 6c4009
		  if (_FP_FMA_T##_s == Z##_s)				\
Packit 6c4009
		    _FP_FRAC_ADD_##dwc (_FP_FMA_RD, _FP_FMA_TD,		\
Packit 6c4009
					_FP_FMA_ZD);			\
Packit 6c4009
		  else							\
Packit 6c4009
		    {							\
Packit 6c4009
		      _FP_FRAC_SUB_##dwc (_FP_FMA_RD, _FP_FMA_TD,	\
Packit 6c4009
					  _FP_FMA_ZD);			\
Packit 6c4009
		      if (_FP_FRAC_NEGP_##dwc (_FP_FMA_RD))		\
Packit 6c4009
			{						\
Packit 6c4009
			  R##_s = Z##_s;				\
Packit 6c4009
			  _FP_FRAC_SUB_##dwc (_FP_FMA_RD, _FP_FMA_ZD,	\
Packit 6c4009
					      _FP_FMA_TD);		\
Packit 6c4009
			}						\
Packit 6c4009
		    }							\
Packit 6c4009
		}							\
Packit 6c4009
	      else							\
Packit 6c4009
		{							\
Packit 6c4009
		  R##_e = Z##_e;					\
Packit 6c4009
		  R##_s = Z##_s;					\
Packit 6c4009
		  _FP_FRAC_COPY_##dwc##_##wc (_FP_FMA_ZD, Z);		\
Packit 6c4009
		  _FP_FRAC_SLL_##dwc (_FP_FMA_ZD, _FP_WFRACBITS_##fs);	\
Packit 6c4009
		  int _FP_FMA_shift = -_FP_FMA_ediff - _FP_FMA_tsh;	\
Packit 6c4009
		  if (_FP_FMA_shift >= _FP_WFRACBITS_DW_##fs)		\
Packit 6c4009
		    _FP_FRAC_SET_##dwc (_FP_FMA_TD, _FP_MINFRAC_##dwc);	\
Packit 6c4009
		  else if (_FP_FMA_shift > 0)				\
Packit 6c4009
		    _FP_FRAC_SRS_##dwc (_FP_FMA_TD, _FP_FMA_shift,	\
Packit 6c4009
					_FP_WFRACBITS_DW_##fs);		\
Packit 6c4009
		  if (Z##_s == _FP_FMA_T##_s)				\
Packit 6c4009
		    _FP_FRAC_ADD_##dwc (_FP_FMA_RD, _FP_FMA_ZD,		\
Packit 6c4009
					_FP_FMA_TD);			\
Packit 6c4009
		  else							\
Packit 6c4009
		    _FP_FRAC_SUB_##dwc (_FP_FMA_RD, _FP_FMA_ZD,		\
Packit 6c4009
					_FP_FMA_TD);			\
Packit 6c4009
		}							\
Packit 6c4009
	      if (_FP_FRAC_ZEROP_##dwc (_FP_FMA_RD))			\
Packit 6c4009
		{							\
Packit 6c4009
		  if (_FP_FMA_T##_s == Z##_s)				\
Packit 6c4009
		    R##_s = Z##_s;					\
Packit 6c4009
		  else							\
Packit 6c4009
		    R##_s = (FP_ROUNDMODE == FP_RND_MINF);		\
Packit 6c4009
		  _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc);		\
Packit 6c4009
		  R##_c = FP_CLS_ZERO;					\
Packit 6c4009
		}							\
Packit 6c4009
	      else							\
Packit 6c4009
		{							\
Packit 6c4009
		  int _FP_FMA_rlz;					\
Packit 6c4009
		  _FP_FRAC_CLZ_##dwc (_FP_FMA_rlz, _FP_FMA_RD);		\
Packit 6c4009
		  _FP_FMA_rlz -= _FP_WFRACXBITS_DW_##fs;		\
Packit 6c4009
		  R##_e -= _FP_FMA_rlz;					\
Packit 6c4009
		  int _FP_FMA_shift = _FP_WFRACBITS_##fs - _FP_FMA_rlz;	\
Packit 6c4009
		  if (_FP_FMA_shift > 0)				\
Packit 6c4009
		    _FP_FRAC_SRS_##dwc (_FP_FMA_RD, _FP_FMA_shift,	\
Packit 6c4009
					_FP_WFRACBITS_DW_##fs);		\
Packit 6c4009
		  else if (_FP_FMA_shift < 0)				\
Packit 6c4009
		    _FP_FRAC_SLL_##dwc (_FP_FMA_RD, -_FP_FMA_shift);	\
Packit 6c4009
		  _FP_FRAC_COPY_##wc##_##dwc (R, _FP_FMA_RD);		\
Packit 6c4009
		  R##_c = FP_CLS_NORMAL;				\
Packit 6c4009
		}							\
Packit 6c4009
	      break;							\
Packit 6c4009
	    }								\
Packit 6c4009
	  goto done_fma;						\
Packit 6c4009
									\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN):			\
Packit 6c4009
	  _FP_CHOOSENAN (fs, wc, _FP_FMA_T, X, Y, '*');			\
Packit 6c4009
	  break;							\
Packit 6c4009
									\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF):			\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO):			\
Packit 6c4009
	  _FP_FMA_T##_s = X##_s;					\
Packit 6c4009
	  /* FALLTHRU */						\
Packit 6c4009
									\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF):			\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO):		\
Packit 6c4009
	  _FP_FRAC_COPY_##wc (_FP_FMA_T, X);				\
Packit 6c4009
	  _FP_FMA_T##_c = X##_c;					\
Packit 6c4009
	  break;							\
Packit 6c4009
									\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN):			\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN):			\
Packit 6c4009
	  _FP_FMA_T##_s = Y##_s;					\
Packit 6c4009
	  /* FALLTHRU */						\
Packit 6c4009
									\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO):		\
Packit 6c4009
	  _FP_FRAC_COPY_##wc (_FP_FMA_T, Y);				\
Packit 6c4009
	  _FP_FMA_T##_c = Y##_c;					\
Packit 6c4009
	  break;							\
Packit 6c4009
									\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO):			\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF):			\
Packit 6c4009
	  _FP_FMA_T##_s = _FP_NANSIGN_##fs;				\
Packit 6c4009
	  _FP_FMA_T##_c = FP_CLS_NAN;					\
Packit 6c4009
	  _FP_FRAC_SET_##wc (_FP_FMA_T, _FP_NANFRAC_##fs);		\
Packit 6c4009
	  FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_IMZ_FMA);	\
Packit 6c4009
	  break;							\
Packit 6c4009
									\
Packit 6c4009
	default:							\
Packit 6c4009
	  _FP_UNREACHABLE;						\
Packit 6c4009
	}								\
Packit 6c4009
									\
Packit 6c4009
      /* T = X * Y is zero, infinity or NaN.  */			\
Packit 6c4009
      switch (_FP_CLS_COMBINE (_FP_FMA_T##_c, Z##_c))			\
Packit 6c4009
	{								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN):			\
Packit 6c4009
	  _FP_CHOOSENAN (fs, wc, R, _FP_FMA_T, Z, '+');			\
Packit 6c4009
	  break;							\
Packit 6c4009
									\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF):			\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO):			\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO):			\
Packit 6c4009
	  R##_s = _FP_FMA_T##_s;					\
Packit 6c4009
	  _FP_FRAC_COPY_##wc (R, _FP_FMA_T);				\
Packit 6c4009
	  R##_c = _FP_FMA_T##_c;					\
Packit 6c4009
	  break;							\
Packit 6c4009
									\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN):			\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN):			\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF):			\
Packit 6c4009
	  R##_s = Z##_s;						\
Packit 6c4009
	  _FP_FRAC_COPY_##wc (R, Z);					\
Packit 6c4009
	  R##_c = Z##_c;						\
Packit 6c4009
	  R##_e = Z##_e;						\
Packit 6c4009
	  break;							\
Packit 6c4009
									\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF):			\
Packit 6c4009
	  if (_FP_FMA_T##_s == Z##_s)					\
Packit 6c4009
	    {								\
Packit 6c4009
	      R##_s = Z##_s;						\
Packit 6c4009
	      _FP_FRAC_COPY_##wc (R, Z);				\
Packit 6c4009
	      R##_c = Z##_c;						\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      R##_s = _FP_NANSIGN_##fs;					\
Packit 6c4009
	      R##_c = FP_CLS_NAN;					\
Packit 6c4009
	      _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs);			\
Packit 6c4009
	      FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_ISI);	\
Packit 6c4009
	    }								\
Packit 6c4009
	  break;							\
Packit 6c4009
									\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO):		\
Packit 6c4009
	  if (_FP_FMA_T##_s == Z##_s)					\
Packit 6c4009
	    R##_s = Z##_s;						\
Packit 6c4009
	  else								\
Packit 6c4009
	    R##_s = (FP_ROUNDMODE == FP_RND_MINF);			\
Packit 6c4009
	  _FP_FRAC_COPY_##wc (R, Z);					\
Packit 6c4009
	  R##_c = Z##_c;						\
Packit 6c4009
	  break;							\
Packit 6c4009
									\
Packit 6c4009
	default:							\
Packit 6c4009
	  _FP_UNREACHABLE;						\
Packit 6c4009
	}								\
Packit 6c4009
    done_fma: ;								\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Main division routine.  The input values should be cooked.  */
Packit 6c4009
Packit 6c4009
#define _FP_DIV(fs, wc, R, X, Y)				\
Packit 6c4009
  do								\
Packit 6c4009
    {								\
Packit 6c4009
      R##_s = X##_s ^ Y##_s;					\
Packit 6c4009
      R##_e = X##_e - Y##_e;					\
Packit 6c4009
      switch (_FP_CLS_COMBINE (X##_c, Y##_c))			\
Packit 6c4009
	{							\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NORMAL):	\
Packit 6c4009
	  R##_c = FP_CLS_NORMAL;				\
Packit 6c4009
								\
Packit 6c4009
	  _FP_DIV_MEAT_##fs (R, X, Y);				\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NAN):		\
Packit 6c4009
	  _FP_CHOOSENAN (fs, wc, R, X, Y, '/');			\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_NORMAL):	\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_INF):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NAN, FP_CLS_ZERO):		\
Packit 6c4009
	  R##_s = X##_s;					\
Packit 6c4009
	  _FP_FRAC_COPY_##wc (R, X);				\
Packit 6c4009
	  R##_c = X##_c;					\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_NAN):	\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NAN):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NAN):		\
Packit 6c4009
	  R##_s = Y##_s;					\
Packit 6c4009
	  _FP_FRAC_COPY_##wc (R, Y);				\
Packit 6c4009
	  R##_c = Y##_c;					\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_INF):	\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_INF):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_NORMAL):	\
Packit 6c4009
	  R##_c = FP_CLS_ZERO;					\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_NORMAL, FP_CLS_ZERO):	\
Packit 6c4009
	  FP_SET_EXCEPTION (FP_EX_DIVZERO);			\
Packit 6c4009
	  /* FALLTHRU */					\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_ZERO):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_NORMAL):	\
Packit 6c4009
	  R##_c = FP_CLS_INF;					\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_INF, FP_CLS_INF):		\
Packit 6c4009
	case _FP_CLS_COMBINE (FP_CLS_ZERO, FP_CLS_ZERO):	\
Packit 6c4009
	  R##_s = _FP_NANSIGN_##fs;				\
Packit 6c4009
	  R##_c = FP_CLS_NAN;					\
Packit 6c4009
	  _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs);		\
Packit 6c4009
	  FP_SET_EXCEPTION (FP_EX_INVALID			\
Packit 6c4009
			    | (X##_c == FP_CLS_INF		\
Packit 6c4009
			       ? FP_EX_INVALID_IDI		\
Packit 6c4009
			       : FP_EX_INVALID_ZDZ));		\
Packit 6c4009
	  break;						\
Packit 6c4009
								\
Packit 6c4009
	default:						\
Packit 6c4009
	  _FP_UNREACHABLE;					\
Packit 6c4009
	}							\
Packit 6c4009
    }								\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Helper for comparisons.  EX is 0 not to raise exceptions, 1 to
Packit 6c4009
   raise exceptions for signaling NaN operands, 2 to raise exceptions
Packit 6c4009
   for all NaN operands.  Conditionals are organized to allow the
Packit 6c4009
   compiler to optimize away code based on the value of EX.  */
Packit 6c4009
Packit 6c4009
#define _FP_CMP_CHECK_NAN(fs, wc, X, Y, ex)				\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      /* The arguments are unordered, which may or may not result in	\
Packit 6c4009
	 an exception.  */						\
Packit 6c4009
      if (ex)								\
Packit 6c4009
	{								\
Packit 6c4009
	  /* At least some cases of unordered arguments result in	\
Packit 6c4009
	     exceptions; check whether this is one.  */			\
Packit 6c4009
	  if (FP_EX_INVALID_SNAN || FP_EX_INVALID_VC)			\
Packit 6c4009
	    {								\
Packit 6c4009
	      /* Check separately for each case of "invalid"		\
Packit 6c4009
		 exceptions.  */					\
Packit 6c4009
	      if ((ex) == 2)						\
Packit 6c4009
		FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_VC);	\
Packit 6c4009
	      if (_FP_ISSIGNAN (fs, wc, X)				\
Packit 6c4009
		  || _FP_ISSIGNAN (fs, wc, Y))				\
Packit 6c4009
		FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_SNAN);	\
Packit 6c4009
	    }								\
Packit 6c4009
	  /* Otherwise, we only need to check whether to raise an	\
Packit 6c4009
	     exception, not which case or cases it is.  */		\
Packit 6c4009
	  else if ((ex) == 2						\
Packit 6c4009
		   || _FP_ISSIGNAN (fs, wc, X)				\
Packit 6c4009
		   || _FP_ISSIGNAN (fs, wc, Y))				\
Packit 6c4009
	    FP_SET_EXCEPTION (FP_EX_INVALID);				\
Packit 6c4009
	}								\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Helper for comparisons.  If denormal operands would raise an
Packit 6c4009
   exception, check for them, and flush to zero as appropriate
Packit 6c4009
   (otherwise, we need only check and flush to zero if it might affect
Packit 6c4009
   the result, which is done later with _FP_CMP_CHECK_FLUSH_ZERO).  */
Packit 6c4009
#define _FP_CMP_CHECK_DENORM(fs, wc, X, Y)				\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      if (FP_EX_DENORM != 0)						\
Packit 6c4009
	{								\
Packit 6c4009
	  /* We must ensure the correct exceptions are raised for	\
Packit 6c4009
	     denormal operands, even though this may not affect the	\
Packit 6c4009
	     result of the comparison.  */				\
Packit 6c4009
	  if (FP_DENORM_ZERO)						\
Packit 6c4009
	    {								\
Packit 6c4009
	      _FP_CHECK_FLUSH_ZERO (fs, wc, X);				\
Packit 6c4009
	      _FP_CHECK_FLUSH_ZERO (fs, wc, Y);				\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      if ((X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X))		\
Packit 6c4009
		  || (Y##_e == 0 && !_FP_FRAC_ZEROP_##wc (Y)))		\
Packit 6c4009
		FP_SET_EXCEPTION (FP_EX_DENORM);			\
Packit 6c4009
	    }								\
Packit 6c4009
	}								\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Helper for comparisons.  Check for flushing denormals for zero if
Packit 6c4009
   we didn't need to check earlier for any denormal operands.  */
Packit 6c4009
#define _FP_CMP_CHECK_FLUSH_ZERO(fs, wc, X, Y)	\
Packit 6c4009
  do						\
Packit 6c4009
    {						\
Packit 6c4009
      if (FP_EX_DENORM == 0)			\
Packit 6c4009
	{					\
Packit 6c4009
	  _FP_CHECK_FLUSH_ZERO (fs, wc, X);	\
Packit 6c4009
	  _FP_CHECK_FLUSH_ZERO (fs, wc, Y);	\
Packit 6c4009
	}					\
Packit 6c4009
    }						\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Main differential comparison routine.  The inputs should be raw not
Packit 6c4009
   cooked.  The return is -1, 0, 1 for normal values, UN
Packit 6c4009
   otherwise.  */
Packit 6c4009
Packit 6c4009
#define _FP_CMP(fs, wc, ret, X, Y, un, ex)				\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      _FP_CMP_CHECK_DENORM (fs, wc, X, Y);				\
Packit 6c4009
      /* NANs are unordered.  */					\
Packit 6c4009
      if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X))	\
Packit 6c4009
	  || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y)))	\
Packit 6c4009
	{								\
Packit 6c4009
	  (ret) = (un);							\
Packit 6c4009
	  _FP_CMP_CHECK_NAN (fs, wc, X, Y, (ex));			\
Packit 6c4009
	}								\
Packit 6c4009
      else								\
Packit 6c4009
	{								\
Packit 6c4009
	  int _FP_CMP_is_zero_x;					\
Packit 6c4009
	  int _FP_CMP_is_zero_y;					\
Packit 6c4009
									\
Packit 6c4009
	  _FP_CMP_CHECK_FLUSH_ZERO (fs, wc, X, Y);			\
Packit 6c4009
									\
Packit 6c4009
	  _FP_CMP_is_zero_x						\
Packit 6c4009
	    = (!X##_e && _FP_FRAC_ZEROP_##wc (X)) ? 1 : 0;		\
Packit 6c4009
	  _FP_CMP_is_zero_y						\
Packit 6c4009
	    = (!Y##_e && _FP_FRAC_ZEROP_##wc (Y)) ? 1 : 0;		\
Packit 6c4009
									\
Packit 6c4009
	  if (_FP_CMP_is_zero_x && _FP_CMP_is_zero_y)			\
Packit 6c4009
	    (ret) = 0;							\
Packit 6c4009
	  else if (_FP_CMP_is_zero_x)					\
Packit 6c4009
	    (ret) = Y##_s ? 1 : -1;					\
Packit 6c4009
	  else if (_FP_CMP_is_zero_y)					\
Packit 6c4009
	    (ret) = X##_s ? -1 : 1;					\
Packit 6c4009
	  else if (X##_s != Y##_s)					\
Packit 6c4009
	    (ret) = X##_s ? -1 : 1;					\
Packit 6c4009
	  else if (X##_e > Y##_e)					\
Packit 6c4009
	    (ret) = X##_s ? -1 : 1;					\
Packit 6c4009
	  else if (X##_e < Y##_e)					\
Packit 6c4009
	    (ret) = X##_s ? 1 : -1;					\
Packit 6c4009
	  else if (_FP_FRAC_GT_##wc (X, Y))				\
Packit 6c4009
	    (ret) = X##_s ? -1 : 1;					\
Packit 6c4009
	  else if (_FP_FRAC_GT_##wc (Y, X))				\
Packit 6c4009
	    (ret) = X##_s ? 1 : -1;					\
Packit 6c4009
	  else								\
Packit 6c4009
	    (ret) = 0;							\
Packit 6c4009
	}								\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Simplification for strict equality.  */
Packit 6c4009
Packit 6c4009
#define _FP_CMP_EQ(fs, wc, ret, X, Y, ex)				\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      _FP_CMP_CHECK_DENORM (fs, wc, X, Y);				\
Packit 6c4009
      /* NANs are unordered.  */					\
Packit 6c4009
      if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X))	\
Packit 6c4009
	  || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y)))	\
Packit 6c4009
	{								\
Packit 6c4009
	  (ret) = 1;							\
Packit 6c4009
	  _FP_CMP_CHECK_NAN (fs, wc, X, Y, (ex));			\
Packit 6c4009
	}								\
Packit 6c4009
      else								\
Packit 6c4009
	{								\
Packit 6c4009
	  _FP_CMP_CHECK_FLUSH_ZERO (fs, wc, X, Y);			\
Packit 6c4009
									\
Packit 6c4009
	  (ret) = !(X##_e == Y##_e					\
Packit 6c4009
		    && _FP_FRAC_EQ_##wc (X, Y)				\
Packit 6c4009
		    && (X##_s == Y##_s					\
Packit 6c4009
			|| (!X##_e && _FP_FRAC_ZEROP_##wc (X))));	\
Packit 6c4009
	}								\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Version to test unordered.  */
Packit 6c4009
Packit 6c4009
#define _FP_CMP_UNORD(fs, wc, ret, X, Y, ex)				\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      _FP_CMP_CHECK_DENORM (fs, wc, X, Y);				\
Packit 6c4009
      (ret) = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (X))	\
Packit 6c4009
	       || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc (Y))); \
Packit 6c4009
      if (ret)								\
Packit 6c4009
	_FP_CMP_CHECK_NAN (fs, wc, X, Y, (ex));				\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Main square root routine.  The input value should be cooked.  */
Packit 6c4009
Packit 6c4009
#define _FP_SQRT(fs, wc, R, X)						\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      _FP_FRAC_DECL_##wc (_FP_SQRT_T);					\
Packit 6c4009
      _FP_FRAC_DECL_##wc (_FP_SQRT_S);					\
Packit 6c4009
      _FP_W_TYPE _FP_SQRT_q;						\
Packit 6c4009
      switch (X##_c)							\
Packit 6c4009
	{								\
Packit 6c4009
	case FP_CLS_NAN:						\
Packit 6c4009
	  _FP_FRAC_COPY_##wc (R, X);					\
Packit 6c4009
	  R##_s = X##_s;						\
Packit 6c4009
	  R##_c = FP_CLS_NAN;						\
Packit 6c4009
	  break;							\
Packit 6c4009
	case FP_CLS_INF:						\
Packit 6c4009
	  if (X##_s)							\
Packit 6c4009
	    {								\
Packit 6c4009
	      R##_s = _FP_NANSIGN_##fs;					\
Packit 6c4009
	      R##_c = FP_CLS_NAN; /* NAN */				\
Packit 6c4009
	      _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs);			\
Packit 6c4009
	      FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_SQRT);	\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      R##_s = 0;						\
Packit 6c4009
	      R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */		\
Packit 6c4009
	    }								\
Packit 6c4009
	  break;							\
Packit 6c4009
	case FP_CLS_ZERO:						\
Packit 6c4009
	  R##_s = X##_s;						\
Packit 6c4009
	  R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */			\
Packit 6c4009
	  break;							\
Packit 6c4009
	case FP_CLS_NORMAL:						\
Packit 6c4009
	  R##_s = 0;							\
Packit 6c4009
	  if (X##_s)							\
Packit 6c4009
	    {								\
Packit 6c4009
	      R##_c = FP_CLS_NAN; /* NAN */				\
Packit 6c4009
	      R##_s = _FP_NANSIGN_##fs;					\
Packit 6c4009
	      _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs);			\
Packit 6c4009
	      FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_SQRT);	\
Packit 6c4009
	      break;							\
Packit 6c4009
	    }								\
Packit 6c4009
	  R##_c = FP_CLS_NORMAL;					\
Packit 6c4009
	  if (X##_e & 1)						\
Packit 6c4009
	    _FP_FRAC_SLL_##wc (X, 1);					\
Packit 6c4009
	  R##_e = X##_e >> 1;						\
Packit 6c4009
	  _FP_FRAC_SET_##wc (_FP_SQRT_S, _FP_ZEROFRAC_##wc);		\
Packit 6c4009
	  _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc);			\
Packit 6c4009
	  _FP_SQRT_q = _FP_OVERFLOW_##fs >> 1;				\
Packit 6c4009
	  _FP_SQRT_MEAT_##wc (R, _FP_SQRT_S, _FP_SQRT_T, X,		\
Packit 6c4009
			      _FP_SQRT_q);				\
Packit 6c4009
	}								\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Convert from FP to integer.  Input is raw.  */
Packit 6c4009
Packit 6c4009
/* RSIGNED can have following values:
Packit 6c4009
   0:  the number is required to be 0..(2^rsize)-1, if not, NV is set plus
Packit 6c4009
       the result is either 0 or (2^rsize)-1 depending on the sign in such
Packit 6c4009
       case.
Packit 6c4009
   1:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
Packit 6c4009
       NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
Packit 6c4009
       depending on the sign in such case.
Packit 6c4009
   2:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
Packit 6c4009
       NV is set plus the result is reduced modulo 2^rsize.
Packit 6c4009
   -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
Packit 6c4009
       set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
Packit 6c4009
       depending on the sign in such case.  */
Packit 6c4009
#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)			\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      if (X##_e < _FP_EXPBIAS_##fs)					\
Packit 6c4009
	{								\
Packit 6c4009
	  (r) = 0;							\
Packit 6c4009
	  if (X##_e == 0)						\
Packit 6c4009
	    {								\
Packit 6c4009
	      if (!_FP_FRAC_ZEROP_##wc (X))				\
Packit 6c4009
		{							\
Packit 6c4009
		  if (!FP_DENORM_ZERO)					\
Packit 6c4009
		    FP_SET_EXCEPTION (FP_EX_INEXACT);			\
Packit 6c4009
		  FP_SET_EXCEPTION (FP_EX_DENORM);			\
Packit 6c4009
		}							\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    FP_SET_EXCEPTION (FP_EX_INEXACT);				\
Packit 6c4009
	}								\
Packit 6c4009
      else if ((rsigned) == 2						\
Packit 6c4009
	       && (X##_e						\
Packit 6c4009
		   >= ((_FP_EXPMAX_##fs					\
Packit 6c4009
			< _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + (rsize) - 1) \
Packit 6c4009
		       ? _FP_EXPMAX_##fs				\
Packit 6c4009
		       : _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + (rsize) - 1))) \
Packit 6c4009
	{								\
Packit 6c4009
	  /* Overflow resulting in 0.  */				\
Packit 6c4009
	  (r) = 0;							\
Packit 6c4009
	  FP_SET_EXCEPTION (FP_EX_INVALID				\
Packit 6c4009
			    | FP_EX_INVALID_CVI				\
Packit 6c4009
			    | ((FP_EX_INVALID_SNAN			\
Packit 6c4009
				&& _FP_ISSIGNAN (fs, wc, X))		\
Packit 6c4009
			       ? FP_EX_INVALID_SNAN			\
Packit 6c4009
			       : 0));					\
Packit 6c4009
	}								\
Packit 6c4009
      else if ((rsigned) != 2						\
Packit 6c4009
	       && (X##_e >= (_FP_EXPMAX_##fs < _FP_EXPBIAS_##fs + (rsize) \
Packit 6c4009
			     ? _FP_EXPMAX_##fs				\
Packit 6c4009
			     : (_FP_EXPBIAS_##fs + (rsize)		\
Packit 6c4009
				- ((rsigned) > 0 || X##_s)))		\
Packit 6c4009
		   || (!(rsigned) && X##_s)))				\
Packit 6c4009
	{								\
Packit 6c4009
	  /* Overflow or converting to the most negative integer.  */	\
Packit 6c4009
	  if (rsigned)							\
Packit 6c4009
	    {								\
Packit 6c4009
	      (r) = 1;							\
Packit 6c4009
	      (r) <<= (rsize) - 1;					\
Packit 6c4009
	      (r) -= 1 - X##_s;						\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      (r) = 0;							\
Packit 6c4009
	      if (!X##_s)						\
Packit 6c4009
		(r) = ~(r);						\
Packit 6c4009
	    }								\
Packit 6c4009
									\
Packit 6c4009
	  if (_FP_EXPBIAS_##fs + (rsize) - 1 < _FP_EXPMAX_##fs		\
Packit 6c4009
	      && (rsigned)						\
Packit 6c4009
	      && X##_s							\
Packit 6c4009
	      && X##_e == _FP_EXPBIAS_##fs + (rsize) - 1)		\
Packit 6c4009
	    {								\
Packit 6c4009
	      /* Possibly converting to most negative integer; check the \
Packit 6c4009
		 mantissa.  */						\
Packit 6c4009
	      int _FP_TO_INT_inexact = 0;				\
Packit 6c4009
	      (void) ((_FP_FRACBITS_##fs > (rsize))			\
Packit 6c4009
		      ? ({						\
Packit 6c4009
			  _FP_FRAC_SRST_##wc (X, _FP_TO_INT_inexact,	\
Packit 6c4009
					      _FP_FRACBITS_##fs - (rsize), \
Packit 6c4009
					      _FP_FRACBITS_##fs);	\
Packit 6c4009
			  0;						\
Packit 6c4009
			})						\
Packit 6c4009
		      : 0);						\
Packit 6c4009
	      if (!_FP_FRAC_ZEROP_##wc (X))				\
Packit 6c4009
		FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI);	\
Packit 6c4009
	      else if (_FP_TO_INT_inexact)				\
Packit 6c4009
		FP_SET_EXCEPTION (FP_EX_INEXACT);			\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    FP_SET_EXCEPTION (FP_EX_INVALID				\
Packit 6c4009
			      | FP_EX_INVALID_CVI			\
Packit 6c4009
			      | ((FP_EX_INVALID_SNAN			\
Packit 6c4009
				  && _FP_ISSIGNAN (fs, wc, X))		\
Packit 6c4009
				 ? FP_EX_INVALID_SNAN			\
Packit 6c4009
				 : 0));					\
Packit 6c4009
	}								\
Packit 6c4009
      else								\
Packit 6c4009
	{								\
Packit 6c4009
	  int _FP_TO_INT_inexact = 0;					\
Packit 6c4009
	  _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs;		\
Packit 6c4009
	  if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1)	\
Packit 6c4009
	    {								\
Packit 6c4009
	      _FP_FRAC_ASSEMBLE_##wc ((r), X, (rsize));			\
Packit 6c4009
	      (r) <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      _FP_FRAC_SRST_##wc (X, _FP_TO_INT_inexact,		\
Packit 6c4009
				  (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1 \
Packit 6c4009
				   - X##_e),				\
Packit 6c4009
				  _FP_FRACBITS_##fs);			\
Packit 6c4009
	      _FP_FRAC_ASSEMBLE_##wc ((r), X, (rsize));			\
Packit 6c4009
	    }								\
Packit 6c4009
	  if ((rsigned) && X##_s)					\
Packit 6c4009
	    (r) = -(r);							\
Packit 6c4009
	  if ((rsigned) == 2 && X##_e >= _FP_EXPBIAS_##fs + (rsize) - 1) \
Packit 6c4009
	    {								\
Packit 6c4009
	      /* Overflow or converting to the most negative integer.  */ \
Packit 6c4009
	      if (X##_e > _FP_EXPBIAS_##fs + (rsize) - 1		\
Packit 6c4009
		  || !X##_s						\
Packit 6c4009
		  || (r) != (((typeof (r)) 1) << ((rsize) - 1)))	\
Packit 6c4009
		{							\
Packit 6c4009
		  _FP_TO_INT_inexact = 0;				\
Packit 6c4009
		  FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI);	\
Packit 6c4009
		}							\
Packit 6c4009
	    }								\
Packit 6c4009
	  if (_FP_TO_INT_inexact)					\
Packit 6c4009
	    FP_SET_EXCEPTION (FP_EX_INEXACT);				\
Packit 6c4009
	}								\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Convert from floating point to integer, rounding according to the
Packit 6c4009
   current rounding direction.  Input is raw.  RSIGNED is as for
Packit 6c4009
   _FP_TO_INT.  */
Packit 6c4009
#define _FP_TO_INT_ROUND(fs, wc, r, X, rsize, rsigned)			\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      __label__ _FP_TO_INT_ROUND_done;					\
Packit 6c4009
      if (X##_e < _FP_EXPBIAS_##fs)					\
Packit 6c4009
	{								\
Packit 6c4009
	  int _FP_TO_INT_ROUND_rounds_away = 0;				\
Packit 6c4009
	  if (X##_e == 0)						\
Packit 6c4009
	    {								\
Packit 6c4009
	      if (_FP_FRAC_ZEROP_##wc (X))				\
Packit 6c4009
		{							\
Packit 6c4009
		  (r) = 0;						\
Packit 6c4009
		  goto _FP_TO_INT_ROUND_done;				\
Packit 6c4009
		}							\
Packit 6c4009
	      else							\
Packit 6c4009
		{							\
Packit 6c4009
		  FP_SET_EXCEPTION (FP_EX_DENORM);			\
Packit 6c4009
		  if (FP_DENORM_ZERO)					\
Packit 6c4009
		    {							\
Packit 6c4009
		      (r) = 0;						\
Packit 6c4009
		      goto _FP_TO_INT_ROUND_done;			\
Packit 6c4009
		    }							\
Packit 6c4009
		}							\
Packit 6c4009
	    }								\
Packit 6c4009
	  /* The result is 0, 1 or -1 depending on the rounding mode;	\
Packit 6c4009
	     -1 may cause overflow in the unsigned case.  */		\
Packit 6c4009
	  switch (FP_ROUNDMODE)						\
Packit 6c4009
	    {								\
Packit 6c4009
	    case FP_RND_NEAREST:					\
Packit 6c4009
	      _FP_TO_INT_ROUND_rounds_away				\
Packit 6c4009
		= (X##_e == _FP_EXPBIAS_##fs - 1			\
Packit 6c4009
		   && !_FP_FRAC_ZEROP_##wc (X));			\
Packit 6c4009
	      break;							\
Packit 6c4009
	    case FP_RND_ZERO:						\
Packit 6c4009
	      /* _FP_TO_INT_ROUND_rounds_away is already 0.  */		\
Packit 6c4009
	      break;							\
Packit 6c4009
	    case FP_RND_PINF:						\
Packit 6c4009
	      _FP_TO_INT_ROUND_rounds_away = !X##_s;			\
Packit 6c4009
	      break;							\
Packit 6c4009
	    case FP_RND_MINF:						\
Packit 6c4009
	      _FP_TO_INT_ROUND_rounds_away = X##_s;			\
Packit 6c4009
	      break;							\
Packit 6c4009
	    }								\
Packit 6c4009
	  if ((rsigned) == 0 && _FP_TO_INT_ROUND_rounds_away && X##_s)	\
Packit 6c4009
	    {								\
Packit 6c4009
	      /* Result of -1 for an unsigned conversion.  */		\
Packit 6c4009
	      (r) = 0;							\
Packit 6c4009
	      FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI);	\
Packit 6c4009
	    }								\
Packit 6c4009
	  else if ((rsize) == 1 && (rsigned) > 0			\
Packit 6c4009
		   && _FP_TO_INT_ROUND_rounds_away && !X##_s)		\
Packit 6c4009
	    {								\
Packit 6c4009
	      /* Converting to a 1-bit signed bit-field, which cannot	\
Packit 6c4009
		 represent +1.  */					\
Packit 6c4009
	      (r) = ((rsigned) == 2 ? -1 : 0);				\
Packit 6c4009
	      FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI);	\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      (r) = (_FP_TO_INT_ROUND_rounds_away			\
Packit 6c4009
		     ? (X##_s ? -1 : 1)					\
Packit 6c4009
		     : 0);						\
Packit 6c4009
	      FP_SET_EXCEPTION (FP_EX_INEXACT);				\
Packit 6c4009
	    }								\
Packit 6c4009
	}								\
Packit 6c4009
      else if ((rsigned) == 2						\
Packit 6c4009
	       && (X##_e						\
Packit 6c4009
		   >= ((_FP_EXPMAX_##fs					\
Packit 6c4009
			< _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + (rsize) - 1) \
Packit 6c4009
		       ? _FP_EXPMAX_##fs				\
Packit 6c4009
		       : _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + (rsize) - 1))) \
Packit 6c4009
	{								\
Packit 6c4009
	  /* Overflow resulting in 0.  */				\
Packit 6c4009
	  (r) = 0;							\
Packit 6c4009
	  FP_SET_EXCEPTION (FP_EX_INVALID				\
Packit 6c4009
			    | FP_EX_INVALID_CVI				\
Packit 6c4009
			    | ((FP_EX_INVALID_SNAN			\
Packit 6c4009
				&& _FP_ISSIGNAN (fs, wc, X))		\
Packit 6c4009
			       ? FP_EX_INVALID_SNAN			\
Packit 6c4009
			       : 0));					\
Packit 6c4009
	}								\
Packit 6c4009
      else if ((rsigned) != 2						\
Packit 6c4009
	       && (X##_e >= (_FP_EXPMAX_##fs < _FP_EXPBIAS_##fs + (rsize) \
Packit 6c4009
			     ? _FP_EXPMAX_##fs				\
Packit 6c4009
			     : (_FP_EXPBIAS_##fs + (rsize)		\
Packit 6c4009
				- ((rsigned) > 0 && !X##_s)))		\
Packit 6c4009
		   || ((rsigned) == 0 && X##_s)))			\
Packit 6c4009
	{								\
Packit 6c4009
	  /* Definite overflow (does not require rounding to tell).  */	\
Packit 6c4009
	  if ((rsigned) != 0)						\
Packit 6c4009
	    {								\
Packit 6c4009
	      (r) = 1;							\
Packit 6c4009
	      (r) <<= (rsize) - 1;					\
Packit 6c4009
	      (r) -= 1 - X##_s;						\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      (r) = 0;							\
Packit 6c4009
	      if (!X##_s)						\
Packit 6c4009
		(r) = ~(r);						\
Packit 6c4009
	    }								\
Packit 6c4009
									\
Packit 6c4009
	  FP_SET_EXCEPTION (FP_EX_INVALID				\
Packit 6c4009
			    | FP_EX_INVALID_CVI				\
Packit 6c4009
			    | ((FP_EX_INVALID_SNAN			\
Packit 6c4009
				&& _FP_ISSIGNAN (fs, wc, X))		\
Packit 6c4009
			       ? FP_EX_INVALID_SNAN			\
Packit 6c4009
			       : 0));					\
Packit 6c4009
	}								\
Packit 6c4009
      else								\
Packit 6c4009
	{								\
Packit 6c4009
	  /* The value is finite, with magnitude at least 1.  If	\
Packit 6c4009
	     the conversion is unsigned, the value is positive.		\
Packit 6c4009
	     If RSIGNED is not 2, the value does not definitely		\
Packit 6c4009
	     overflow by virtue of its exponent, but may still turn	\
Packit 6c4009
	     out to overflow after rounding; if RSIGNED is 2, the	\
Packit 6c4009
	     exponent may be such that the value definitely overflows,	\
Packit 6c4009
	     but at least one mantissa bit will not be shifted out.  */ \
Packit 6c4009
	  int _FP_TO_INT_ROUND_inexact = 0;				\
Packit 6c4009
	  _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs;		\
Packit 6c4009
	  if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1)	\
Packit 6c4009
	    {								\
Packit 6c4009
	      /* The value is an integer, no rounding needed.  */	\
Packit 6c4009
	      _FP_FRAC_ASSEMBLE_##wc ((r), X, (rsize));			\
Packit 6c4009
	      (r) <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      /* May need to shift in order to round (unless there	\
Packit 6c4009
		 are exactly _FP_WORKBITS fractional bits already).  */	\
Packit 6c4009
	      int _FP_TO_INT_ROUND_rshift				\
Packit 6c4009
		= (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs			\
Packit 6c4009
		   - 1 - _FP_WORKBITS - X##_e);				\
Packit 6c4009
	      if (_FP_TO_INT_ROUND_rshift > 0)				\
Packit 6c4009
		_FP_FRAC_SRS_##wc (X, _FP_TO_INT_ROUND_rshift,		\
Packit 6c4009
				   _FP_WFRACBITS_##fs);			\
Packit 6c4009
	      else if (_FP_TO_INT_ROUND_rshift < 0)			\
Packit 6c4009
		_FP_FRAC_SLL_##wc (X, -_FP_TO_INT_ROUND_rshift);	\
Packit 6c4009
	      /* Round like _FP_ROUND, but setting			\
Packit 6c4009
		 _FP_TO_INT_ROUND_inexact instead of directly setting	\
Packit 6c4009
		 the "inexact" exception, since it may turn out we	\
Packit 6c4009
		 should set "invalid" instead.  */			\
Packit 6c4009
	      if (_FP_FRAC_LOW_##wc (X) & 7)				\
Packit 6c4009
		{							\
Packit 6c4009
		  _FP_TO_INT_ROUND_inexact = 1;				\
Packit 6c4009
		  switch (FP_ROUNDMODE)					\
Packit 6c4009
		    {							\
Packit 6c4009
		    case FP_RND_NEAREST:				\
Packit 6c4009
		      _FP_ROUND_NEAREST (wc, X);			\
Packit 6c4009
		      break;						\
Packit 6c4009
		    case FP_RND_ZERO:					\
Packit 6c4009
		      _FP_ROUND_ZERO (wc, X);				\
Packit 6c4009
		      break;						\
Packit 6c4009
		    case FP_RND_PINF:					\
Packit 6c4009
		      _FP_ROUND_PINF (wc, X);				\
Packit 6c4009
		      break;						\
Packit 6c4009
		    case FP_RND_MINF:					\
Packit 6c4009
		      _FP_ROUND_MINF (wc, X);				\
Packit 6c4009
		      break;						\
Packit 6c4009
		    }							\
Packit 6c4009
		}							\
Packit 6c4009
	      _FP_FRAC_SRL_##wc (X, _FP_WORKBITS);			\
Packit 6c4009
	      _FP_FRAC_ASSEMBLE_##wc ((r), X, (rsize));			\
Packit 6c4009
	    }								\
Packit 6c4009
	  if ((rsigned) != 0 && X##_s)					\
Packit 6c4009
	    (r) = -(r);							\
Packit 6c4009
	  /* An exponent of RSIZE - 1 always needs testing for		\
Packit 6c4009
	     overflow (either directly overflowing, or overflowing	\
Packit 6c4009
	     when rounding up results in 2^RSIZE).  An exponent of	\
Packit 6c4009
	     RSIZE - 2 can overflow for positive values when rounding	\
Packit 6c4009
	     up to 2^(RSIZE-1), but cannot overflow for negative	\
Packit 6c4009
	     values.  Smaller exponents cannot overflow.  */		\
Packit 6c4009
	  if (X##_e >= (_FP_EXPBIAS_##fs + (rsize) - 1			\
Packit 6c4009
			- ((rsigned) > 0 && !X##_s)))			\
Packit 6c4009
	    {								\
Packit 6c4009
	      if (X##_e > _FP_EXPBIAS_##fs + (rsize) - 1		\
Packit 6c4009
		  || (X##_e == _FP_EXPBIAS_##fs + (rsize) - 1		\
Packit 6c4009
		      && (X##_s						\
Packit 6c4009
			  ? (r) != (((typeof (r)) 1) << ((rsize) - 1))	\
Packit 6c4009
			  : ((rsigned) > 0 || (r) == 0)))		\
Packit 6c4009
		  || ((rsigned) > 0					\
Packit 6c4009
		      && !X##_s						\
Packit 6c4009
		      && X##_e == _FP_EXPBIAS_##fs + (rsize) - 2	\
Packit 6c4009
		      && (r) == (((typeof (r)) 1) << ((rsize) - 1))))	\
Packit 6c4009
		{							\
Packit 6c4009
		  if ((rsigned) != 2)					\
Packit 6c4009
		    {							\
Packit 6c4009
		      if ((rsigned) != 0)				\
Packit 6c4009
			{						\
Packit 6c4009
			  (r) = 1;					\
Packit 6c4009
			  (r) <<= (rsize) - 1;				\
Packit 6c4009
			  (r) -= 1 - X##_s;				\
Packit 6c4009
			}						\
Packit 6c4009
		      else						\
Packit 6c4009
			{						\
Packit 6c4009
			  (r) = 0;					\
Packit 6c4009
			  (r) = ~(r);					\
Packit 6c4009
			}						\
Packit 6c4009
		    }							\
Packit 6c4009
		  _FP_TO_INT_ROUND_inexact = 0;				\
Packit 6c4009
		  FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI);	\
Packit 6c4009
		}							\
Packit 6c4009
	    }								\
Packit 6c4009
	  if (_FP_TO_INT_ROUND_inexact)					\
Packit 6c4009
	    FP_SET_EXCEPTION (FP_EX_INEXACT);				\
Packit 6c4009
	}								\
Packit 6c4009
    _FP_TO_INT_ROUND_done: ;						\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Convert integer to fp.  Output is raw.  RTYPE is unsigned even if
Packit 6c4009
   input is signed.  */
Packit 6c4009
#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)			\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      __label__ pack_semiraw;						\
Packit 6c4009
      if (r)								\
Packit 6c4009
	{								\
Packit 6c4009
	  rtype _FP_FROM_INT_ur = (r);					\
Packit 6c4009
									\
Packit 6c4009
	  if ((X##_s = ((r) < 0)))					\
Packit 6c4009
	    _FP_FROM_INT_ur = -_FP_FROM_INT_ur;				\
Packit 6c4009
									\
Packit 6c4009
	  _FP_STATIC_ASSERT ((rsize) <= 2 * _FP_W_TYPE_SIZE,		\
Packit 6c4009
			     "rsize too large");			\
Packit 6c4009
	  (void) (((rsize) <= _FP_W_TYPE_SIZE)				\
Packit 6c4009
		  ? ({							\
Packit 6c4009
		      int _FP_FROM_INT_lz;				\
Packit 6c4009
		      __FP_CLZ (_FP_FROM_INT_lz,			\
Packit 6c4009
				(_FP_W_TYPE) _FP_FROM_INT_ur);		\
Packit 6c4009
		      X##_e = (_FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1	\
Packit 6c4009
			       - _FP_FROM_INT_lz);			\
Packit 6c4009
		    })							\
Packit 6c4009
		  : ({						\
Packit 6c4009
		      int _FP_FROM_INT_lz;				\
Packit 6c4009
		      __FP_CLZ_2 (_FP_FROM_INT_lz,			\
Packit 6c4009
				  (_FP_W_TYPE) (_FP_FROM_INT_ur		\
Packit 6c4009
						>> _FP_W_TYPE_SIZE),	\
Packit 6c4009
				  (_FP_W_TYPE) _FP_FROM_INT_ur);	\
Packit 6c4009
		      X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \
Packit 6c4009
			       - _FP_FROM_INT_lz);			\
Packit 6c4009
		    }));						\
Packit 6c4009
									\
Packit 6c4009
	  if ((rsize) - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs		\
Packit 6c4009
	      && X##_e >= _FP_EXPMAX_##fs)				\
Packit 6c4009
	    {								\
Packit 6c4009
	      /* Exponent too big; overflow to infinity.  (May also	\
Packit 6c4009
		 happen after rounding below.)  */			\
Packit 6c4009
	      _FP_OVERFLOW_SEMIRAW (fs, wc, X);				\
Packit 6c4009
	      goto pack_semiraw;					\
Packit 6c4009
	    }								\
Packit 6c4009
									\
Packit 6c4009
	  if ((rsize) <= _FP_FRACBITS_##fs				\
Packit 6c4009
	      || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs)		\
Packit 6c4009
	    {								\
Packit 6c4009
	      /* Exactly representable; shift left.  */			\
Packit 6c4009
	      _FP_FRAC_DISASSEMBLE_##wc (X, _FP_FROM_INT_ur, (rsize));	\
Packit 6c4009
	      if (_FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1 - X##_e > 0)	\
Packit 6c4009
		_FP_FRAC_SLL_##wc (X, (_FP_EXPBIAS_##fs			\
Packit 6c4009
				       + _FP_FRACBITS_##fs - 1 - X##_e)); \
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      /* More bits in integer than in floating type; need to	\
Packit 6c4009
		 round.  */						\
Packit 6c4009
	      if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e)	\
Packit 6c4009
		_FP_FROM_INT_ur						\
Packit 6c4009
		  = ((_FP_FROM_INT_ur >> (X##_e - _FP_EXPBIAS_##fs	\
Packit 6c4009
					  - _FP_WFRACBITS_##fs + 1))	\
Packit 6c4009
		     | ((_FP_FROM_INT_ur				\
Packit 6c4009
			 << ((rsize) - (X##_e - _FP_EXPBIAS_##fs	\
Packit 6c4009
					- _FP_WFRACBITS_##fs + 1)))	\
Packit 6c4009
			!= 0));						\
Packit 6c4009
	      _FP_FRAC_DISASSEMBLE_##wc (X, _FP_FROM_INT_ur, (rsize));	\
Packit 6c4009
	      if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0) \
Packit 6c4009
		_FP_FRAC_SLL_##wc (X, (_FP_EXPBIAS_##fs			\
Packit 6c4009
				       + _FP_WFRACBITS_##fs - 1 - X##_e)); \
Packit 6c4009
	      _FP_FRAC_HIGH_##fs (X) &= ~(_FP_W_TYPE) _FP_IMPLBIT_SH_##fs; \
Packit 6c4009
	    pack_semiraw:						\
Packit 6c4009
	      _FP_PACK_SEMIRAW (fs, wc, X);				\
Packit 6c4009
	    }								\
Packit 6c4009
	}								\
Packit 6c4009
      else								\
Packit 6c4009
	{								\
Packit 6c4009
	  X##_s = 0;							\
Packit 6c4009
	  X##_e = 0;							\
Packit 6c4009
	  _FP_FRAC_SET_##wc (X, _FP_ZEROFRAC_##wc);			\
Packit 6c4009
	}								\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Extend from a narrower floating-point format to a wider one.  Input
Packit 6c4009
   and output are raw.  If CHECK_NAN, then signaling NaNs are
Packit 6c4009
   converted to quiet with the "invalid" exception raised; otherwise
Packit 6c4009
   signaling NaNs remain signaling with no exception.  */
Packit 6c4009
#define _FP_EXTEND_CNAN(dfs, sfs, dwc, swc, D, S, check_nan)		\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      _FP_STATIC_ASSERT (_FP_FRACBITS_##dfs >= _FP_FRACBITS_##sfs,	\
Packit 6c4009
			 "destination mantissa narrower than source");	\
Packit 6c4009
      _FP_STATIC_ASSERT ((_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs		\
Packit 6c4009
			  >= _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs),	\
Packit 6c4009
			 "destination max exponent smaller"		\
Packit 6c4009
			 " than source");				\
Packit 6c4009
      _FP_STATIC_ASSERT (((_FP_EXPBIAS_##dfs				\
Packit 6c4009
			   >= (_FP_EXPBIAS_##sfs			\
Packit 6c4009
			       + _FP_FRACBITS_##sfs - 1))		\
Packit 6c4009
			  || (_FP_EXPBIAS_##dfs == _FP_EXPBIAS_##sfs)), \
Packit 6c4009
			 "source subnormals do not all become normal,"	\
Packit 6c4009
			 " but bias not the same");			\
Packit 6c4009
      D##_s = S##_s;							\
Packit 6c4009
      _FP_FRAC_COPY_##dwc##_##swc (D, S);				\
Packit 6c4009
      if (_FP_EXP_NORMAL (sfs, swc, S))					\
Packit 6c4009
	{								\
Packit 6c4009
	  D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs;	\
Packit 6c4009
	  _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs)); \
Packit 6c4009
	}								\
Packit 6c4009
      else								\
Packit 6c4009
	{								\
Packit 6c4009
	  if (S##_e == 0)						\
Packit 6c4009
	    {								\
Packit 6c4009
	      _FP_CHECK_FLUSH_ZERO (sfs, swc, S);			\
Packit 6c4009
	      if (_FP_FRAC_ZEROP_##swc (S))				\
Packit 6c4009
		D##_e = 0;						\
Packit 6c4009
	      else if (_FP_EXPBIAS_##dfs				\
Packit 6c4009
		       < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1)	\
Packit 6c4009
		{							\
Packit 6c4009
		  FP_SET_EXCEPTION (FP_EX_DENORM);			\
Packit 6c4009
		  _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs		\
Packit 6c4009
					  - _FP_FRACBITS_##sfs));	\
Packit 6c4009
		  D##_e = 0;						\
Packit 6c4009
		  if (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)		\
Packit 6c4009
		    FP_SET_EXCEPTION (FP_EX_UNDERFLOW);			\
Packit 6c4009
		}							\
Packit 6c4009
	      else							\
Packit 6c4009
		{							\
Packit 6c4009
		  int FP_EXTEND_lz;					\
Packit 6c4009
		  FP_SET_EXCEPTION (FP_EX_DENORM);			\
Packit 6c4009
		  _FP_FRAC_CLZ_##swc (FP_EXTEND_lz, S);			\
Packit 6c4009
		  _FP_FRAC_SLL_##dwc (D,				\
Packit 6c4009
				      FP_EXTEND_lz + _FP_FRACBITS_##dfs	\
Packit 6c4009
				      - _FP_FRACTBITS_##sfs);		\
Packit 6c4009
		  D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1	\
Packit 6c4009
			   + _FP_FRACXBITS_##sfs - FP_EXTEND_lz);	\
Packit 6c4009
		}							\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      D##_e = _FP_EXPMAX_##dfs;					\
Packit 6c4009
	      if (!_FP_FRAC_ZEROP_##swc (S))				\
Packit 6c4009
		{							\
Packit 6c4009
		  if (check_nan && _FP_FRAC_SNANP (sfs, S))		\
Packit 6c4009
		    FP_SET_EXCEPTION (FP_EX_INVALID			\
Packit 6c4009
				      | FP_EX_INVALID_SNAN);		\
Packit 6c4009
		  _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs		\
Packit 6c4009
					  - _FP_FRACBITS_##sfs));	\
Packit 6c4009
		  if (check_nan)					\
Packit 6c4009
		    _FP_SETQNAN (dfs, dwc, D);				\
Packit 6c4009
		}							\
Packit 6c4009
	    }								\
Packit 6c4009
	}								\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
#define FP_EXTEND(dfs, sfs, dwc, swc, D, S)		\
Packit 6c4009
    _FP_EXTEND_CNAN (dfs, sfs, dwc, swc, D, S, 1)
Packit 6c4009
Packit 6c4009
/* Truncate from a wider floating-point format to a narrower one.
Packit 6c4009
   Input and output are semi-raw.  */
Packit 6c4009
#define FP_TRUNC(dfs, sfs, dwc, swc, D, S)				\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      _FP_STATIC_ASSERT (_FP_FRACBITS_##sfs >= _FP_FRACBITS_##dfs,	\
Packit 6c4009
			 "destination mantissa wider than source");	\
Packit 6c4009
      _FP_STATIC_ASSERT (((_FP_EXPBIAS_##sfs				\
Packit 6c4009
			   >= (_FP_EXPBIAS_##dfs			\
Packit 6c4009
			       + _FP_FRACBITS_##dfs - 1))		\
Packit 6c4009
			  || _FP_EXPBIAS_##sfs == _FP_EXPBIAS_##dfs),	\
Packit 6c4009
			 "source subnormals do not all become same,"	\
Packit 6c4009
			 " but bias not the same");			\
Packit 6c4009
      D##_s = S##_s;							\
Packit 6c4009
      if (_FP_EXP_NORMAL (sfs, swc, S))					\
Packit 6c4009
	{								\
Packit 6c4009
	  D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs;	\
Packit 6c4009
	  if (D##_e >= _FP_EXPMAX_##dfs)				\
Packit 6c4009
	    _FP_OVERFLOW_SEMIRAW (dfs, dwc, D);				\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      if (D##_e <= 0)						\
Packit 6c4009
		{							\
Packit 6c4009
		  if (D##_e < 1 - _FP_FRACBITS_##dfs)			\
Packit 6c4009
		    {							\
Packit 6c4009
		      _FP_FRAC_SET_##swc (S, _FP_ZEROFRAC_##swc);	\
Packit 6c4009
		      _FP_FRAC_LOW_##swc (S) |= 1;			\
Packit 6c4009
		    }							\
Packit 6c4009
		  else							\
Packit 6c4009
		    {							\
Packit 6c4009
		      _FP_FRAC_HIGH_##sfs (S) |= _FP_IMPLBIT_SH_##sfs;	\
Packit 6c4009
		      _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs	\
Packit 6c4009
					      - _FP_WFRACBITS_##dfs	\
Packit 6c4009
					      + 1 - D##_e),		\
Packit 6c4009
					  _FP_WFRACBITS_##sfs);		\
Packit 6c4009
		    }							\
Packit 6c4009
		  D##_e = 0;						\
Packit 6c4009
		}							\
Packit 6c4009
	      else							\
Packit 6c4009
		_FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs		\
Packit 6c4009
					- _FP_WFRACBITS_##dfs),		\
Packit 6c4009
				    _FP_WFRACBITS_##sfs);		\
Packit 6c4009
	      _FP_FRAC_COPY_##dwc##_##swc (D, S);			\
Packit 6c4009
	    }								\
Packit 6c4009
	}								\
Packit 6c4009
      else								\
Packit 6c4009
	{								\
Packit 6c4009
	  if (S##_e == 0)						\
Packit 6c4009
	    {								\
Packit 6c4009
	      _FP_CHECK_FLUSH_ZERO (sfs, swc, S);			\
Packit 6c4009
	      D##_e = 0;						\
Packit 6c4009
	      if (_FP_FRAC_ZEROP_##swc (S))				\
Packit 6c4009
		_FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc);		\
Packit 6c4009
	      else							\
Packit 6c4009
		{							\
Packit 6c4009
		  FP_SET_EXCEPTION (FP_EX_DENORM);			\
Packit 6c4009
		  if (_FP_EXPBIAS_##sfs					\
Packit 6c4009
		      < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1)	\
Packit 6c4009
		    {							\
Packit 6c4009
		      _FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs	\
Packit 6c4009
					      - _FP_WFRACBITS_##dfs),	\
Packit 6c4009
					  _FP_WFRACBITS_##sfs);		\
Packit 6c4009
		      _FP_FRAC_COPY_##dwc##_##swc (D, S);		\
Packit 6c4009
		    }							\
Packit 6c4009
		  else							\
Packit 6c4009
		    {							\
Packit 6c4009
		      _FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc);	\
Packit 6c4009
		      _FP_FRAC_LOW_##dwc (D) |= 1;			\
Packit 6c4009
		    }							\
Packit 6c4009
		}							\
Packit 6c4009
	    }								\
Packit 6c4009
	  else								\
Packit 6c4009
	    {								\
Packit 6c4009
	      D##_e = _FP_EXPMAX_##dfs;					\
Packit 6c4009
	      if (_FP_FRAC_ZEROP_##swc (S))				\
Packit 6c4009
		_FP_FRAC_SET_##dwc (D, _FP_ZEROFRAC_##dwc);		\
Packit 6c4009
	      else							\
Packit 6c4009
		{							\
Packit 6c4009
		  _FP_CHECK_SIGNAN_SEMIRAW (sfs, swc, S);		\
Packit 6c4009
		  _FP_FRAC_SRL_##swc (S, (_FP_WFRACBITS_##sfs		\
Packit 6c4009
					  - _FP_WFRACBITS_##dfs));	\
Packit 6c4009
		  _FP_FRAC_COPY_##dwc##_##swc (D, S);			\
Packit 6c4009
		  /* Semi-raw NaN must have all workbits cleared.  */	\
Packit 6c4009
		  _FP_FRAC_LOW_##dwc (D)				\
Packit 6c4009
		    &= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1);		\
Packit 6c4009
		  _FP_SETQNAN_SEMIRAW (dfs, dwc, D);			\
Packit 6c4009
		}							\
Packit 6c4009
	    }								\
Packit 6c4009
	}								\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Truncate from a wider floating-point format to a narrower one.
Packit 6c4009
   Input and output are cooked.  */
Packit 6c4009
#define FP_TRUNC_COOKED(dfs, sfs, dwc, swc, D, S)			\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      _FP_STATIC_ASSERT (_FP_FRACBITS_##sfs >= _FP_FRACBITS_##dfs,	\
Packit 6c4009
			 "destination mantissa wider than source");	\
Packit 6c4009
      if (S##_c == FP_CLS_NAN)						\
Packit 6c4009
	_FP_FRAC_SRL_##swc (S, (_FP_WFRACBITS_##sfs			\
Packit 6c4009
				- _FP_WFRACBITS_##dfs));		\
Packit 6c4009
      else								\
Packit 6c4009
	_FP_FRAC_SRS_##swc (S, (_FP_WFRACBITS_##sfs			\
Packit 6c4009
				- _FP_WFRACBITS_##dfs),			\
Packit 6c4009
			    _FP_WFRACBITS_##sfs);			\
Packit 6c4009
      _FP_FRAC_COPY_##dwc##_##swc (D, S);				\
Packit 6c4009
      D##_e = S##_e;							\
Packit 6c4009
      D##_c = S##_c;							\
Packit 6c4009
      D##_s = S##_s;							\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
/* Helper primitives.  */
Packit 6c4009
Packit 6c4009
/* Count leading zeros in a word.  */
Packit 6c4009
Packit 6c4009
#ifndef __FP_CLZ
Packit 6c4009
/* GCC 3.4 and later provide the builtins for us.  */
Packit 6c4009
# define __FP_CLZ(r, x)							\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      _FP_STATIC_ASSERT ((sizeof (_FP_W_TYPE) == sizeof (unsigned int)	\
Packit 6c4009
			  || (sizeof (_FP_W_TYPE)			\
Packit 6c4009
			      == sizeof (unsigned long))		\
Packit 6c4009
			  || (sizeof (_FP_W_TYPE)			\
Packit 6c4009
			      == sizeof (unsigned long long))),		\
Packit 6c4009
			 "_FP_W_TYPE size unsupported for clz");	\
Packit 6c4009
      if (sizeof (_FP_W_TYPE) == sizeof (unsigned int))			\
Packit 6c4009
	(r) = __builtin_clz (x);					\
Packit 6c4009
      else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long))		\
Packit 6c4009
	(r) = __builtin_clzl (x);					\
Packit 6c4009
      else /* sizeof (_FP_W_TYPE) == sizeof (unsigned long long).  */	\
Packit 6c4009
	(r) = __builtin_clzll (x);					\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
#endif /* ndef __FP_CLZ */
Packit 6c4009
Packit 6c4009
#define _FP_DIV_HELP_imm(q, r, n, d)		\
Packit 6c4009
  do						\
Packit 6c4009
    {						\
Packit 6c4009
      (q) = (n) / (d), (r) = (n) % (d);		\
Packit 6c4009
    }						\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* A restoring bit-by-bit division primitive.  */
Packit 6c4009
Packit 6c4009
#define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y)				\
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      int _FP_DIV_MEAT_N_loop_count = _FP_WFRACBITS_##fs;		\
Packit 6c4009
      _FP_FRAC_DECL_##wc (_FP_DIV_MEAT_N_loop_u);			\
Packit 6c4009
      _FP_FRAC_DECL_##wc (_FP_DIV_MEAT_N_loop_v);			\
Packit 6c4009
      _FP_FRAC_COPY_##wc (_FP_DIV_MEAT_N_loop_u, X);			\
Packit 6c4009
      _FP_FRAC_COPY_##wc (_FP_DIV_MEAT_N_loop_v, Y);			\
Packit 6c4009
      _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc);				\
Packit 6c4009
      /* Normalize _FP_DIV_MEAT_N_LOOP_U and _FP_DIV_MEAT_N_LOOP_V.  */	\
Packit 6c4009
      _FP_FRAC_SLL_##wc (_FP_DIV_MEAT_N_loop_u, _FP_WFRACXBITS_##fs);	\
Packit 6c4009
      _FP_FRAC_SLL_##wc (_FP_DIV_MEAT_N_loop_v, _FP_WFRACXBITS_##fs);	\
Packit 6c4009
      /* First round.  Since the operands are normalized, either the	\
Packit 6c4009
	 first or second bit will be set in the fraction.  Produce a	\
Packit 6c4009
	 normalized result by checking which and adjusting the loop	\
Packit 6c4009
	 count and exponent accordingly.  */				\
Packit 6c4009
      if (_FP_FRAC_GE_1 (_FP_DIV_MEAT_N_loop_u, _FP_DIV_MEAT_N_loop_v))	\
Packit 6c4009
	{								\
Packit 6c4009
	  _FP_FRAC_SUB_##wc (_FP_DIV_MEAT_N_loop_u,			\
Packit 6c4009
			     _FP_DIV_MEAT_N_loop_u,			\
Packit 6c4009
			     _FP_DIV_MEAT_N_loop_v);			\
Packit 6c4009
	  _FP_FRAC_LOW_##wc (R) |= 1;					\
Packit 6c4009
	  _FP_DIV_MEAT_N_loop_count--;					\
Packit 6c4009
	}								\
Packit 6c4009
      else								\
Packit 6c4009
	R##_e--;							\
Packit 6c4009
      /* Subsequent rounds.  */						\
Packit 6c4009
      do								\
Packit 6c4009
	{								\
Packit 6c4009
	  int _FP_DIV_MEAT_N_loop_msb					\
Packit 6c4009
	    = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (_FP_DIV_MEAT_N_loop_u) < 0; \
Packit 6c4009
	  _FP_FRAC_SLL_##wc (_FP_DIV_MEAT_N_loop_u, 1);			\
Packit 6c4009
	  _FP_FRAC_SLL_##wc (R, 1);					\
Packit 6c4009
	  if (_FP_DIV_MEAT_N_loop_msb					\
Packit 6c4009
	      || _FP_FRAC_GE_1 (_FP_DIV_MEAT_N_loop_u,			\
Packit 6c4009
				_FP_DIV_MEAT_N_loop_v))			\
Packit 6c4009
	    {								\
Packit 6c4009
	      _FP_FRAC_SUB_##wc (_FP_DIV_MEAT_N_loop_u,			\
Packit 6c4009
				 _FP_DIV_MEAT_N_loop_u,			\
Packit 6c4009
				 _FP_DIV_MEAT_N_loop_v);		\
Packit 6c4009
	      _FP_FRAC_LOW_##wc (R) |= 1;				\
Packit 6c4009
	    }								\
Packit 6c4009
	}								\
Packit 6c4009
      while (--_FP_DIV_MEAT_N_loop_count > 0);				\
Packit 6c4009
      /* If there's anything left in _FP_DIV_MEAT_N_LOOP_U, the result	\
Packit 6c4009
	 is inexact.  */						\
Packit 6c4009
      _FP_FRAC_LOW_##wc (R)						\
Packit 6c4009
	|= !_FP_FRAC_ZEROP_##wc (_FP_DIV_MEAT_N_loop_u);		\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
#define _FP_DIV_MEAT_1_loop(fs, R, X, Y)  _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y)
Packit 6c4009
#define _FP_DIV_MEAT_2_loop(fs, R, X, Y)  _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y)
Packit 6c4009
#define _FP_DIV_MEAT_4_loop(fs, R, X, Y)  _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y)
Packit 6c4009
Packit 6c4009
#endif /* !SOFT_FP_OP_COMMON_H */