18c2ecf20Sopenharmony_ci/* Software floating-point emulation. Common operations.
28c2ecf20Sopenharmony_ci   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
38c2ecf20Sopenharmony_ci   This file is part of the GNU C Library.
48c2ecf20Sopenharmony_ci   Contributed by Richard Henderson (rth@cygnus.com),
58c2ecf20Sopenharmony_ci		  Jakub Jelinek (jj@ultra.linux.cz),
68c2ecf20Sopenharmony_ci		  David S. Miller (davem@redhat.com) and
78c2ecf20Sopenharmony_ci		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci   The GNU C Library is free software; you can redistribute it and/or
108c2ecf20Sopenharmony_ci   modify it under the terms of the GNU Library General Public License as
118c2ecf20Sopenharmony_ci   published by the Free Software Foundation; either version 2 of the
128c2ecf20Sopenharmony_ci   License, or (at your option) any later version.
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci   The GNU C Library is distributed in the hope that it will be useful,
158c2ecf20Sopenharmony_ci   but WITHOUT ANY WARRANTY; without even the implied warranty of
168c2ecf20Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
178c2ecf20Sopenharmony_ci   Library General Public License for more details.
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci   You should have received a copy of the GNU Library General Public
208c2ecf20Sopenharmony_ci   License along with the GNU C Library; see the file COPYING.LIB.  If
218c2ecf20Sopenharmony_ci   not, write to the Free Software Foundation, Inc.,
228c2ecf20Sopenharmony_ci   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#ifndef __MATH_EMU_OP_COMMON_H__
258c2ecf20Sopenharmony_ci#define __MATH_EMU_OP_COMMON_H__
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#define _FP_DECL(wc, X)			\
288c2ecf20Sopenharmony_ci  _FP_I_TYPE X##_c=0, X##_s=0, X##_e=0;	\
298c2ecf20Sopenharmony_ci  _FP_FRAC_DECL_##wc(X)
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci/*
328c2ecf20Sopenharmony_ci * Finish truly unpacking a native fp value by classifying the kind
338c2ecf20Sopenharmony_ci * of fp value and normalizing both the exponent and the fraction.
348c2ecf20Sopenharmony_ci */
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci#define _FP_UNPACK_CANONICAL(fs, wc, X)					\
378c2ecf20Sopenharmony_cido {									\
388c2ecf20Sopenharmony_ci  switch (X##_e)							\
398c2ecf20Sopenharmony_ci  {									\
408c2ecf20Sopenharmony_ci  default:								\
418c2ecf20Sopenharmony_ci    _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs;			\
428c2ecf20Sopenharmony_ci    _FP_FRAC_SLL_##wc(X, _FP_WORKBITS);					\
438c2ecf20Sopenharmony_ci    X##_e -= _FP_EXPBIAS_##fs;						\
448c2ecf20Sopenharmony_ci    X##_c = FP_CLS_NORMAL;						\
458c2ecf20Sopenharmony_ci    break;								\
468c2ecf20Sopenharmony_ci									\
478c2ecf20Sopenharmony_ci  case 0:								\
488c2ecf20Sopenharmony_ci    if (_FP_FRAC_ZEROP_##wc(X))						\
498c2ecf20Sopenharmony_ci      X##_c = FP_CLS_ZERO;						\
508c2ecf20Sopenharmony_ci    else								\
518c2ecf20Sopenharmony_ci      {									\
528c2ecf20Sopenharmony_ci	/* a denormalized number */					\
538c2ecf20Sopenharmony_ci	_FP_I_TYPE _shift;						\
548c2ecf20Sopenharmony_ci	_FP_FRAC_CLZ_##wc(_shift, X);					\
558c2ecf20Sopenharmony_ci	_shift -= _FP_FRACXBITS_##fs;					\
568c2ecf20Sopenharmony_ci	_FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS));			\
578c2ecf20Sopenharmony_ci	X##_e -= _FP_EXPBIAS_##fs - 1 + _shift;				\
588c2ecf20Sopenharmony_ci	X##_c = FP_CLS_NORMAL;						\
598c2ecf20Sopenharmony_ci	FP_SET_EXCEPTION(FP_EX_DENORM);					\
608c2ecf20Sopenharmony_ci	if (FP_DENORM_ZERO)						\
618c2ecf20Sopenharmony_ci	  {								\
628c2ecf20Sopenharmony_ci	    FP_SET_EXCEPTION(FP_EX_INEXACT);				\
638c2ecf20Sopenharmony_ci	    X##_c = FP_CLS_ZERO;					\
648c2ecf20Sopenharmony_ci	  }								\
658c2ecf20Sopenharmony_ci      }									\
668c2ecf20Sopenharmony_ci    break;								\
678c2ecf20Sopenharmony_ci									\
688c2ecf20Sopenharmony_ci  case _FP_EXPMAX_##fs:							\
698c2ecf20Sopenharmony_ci    if (_FP_FRAC_ZEROP_##wc(X))						\
708c2ecf20Sopenharmony_ci      X##_c = FP_CLS_INF;						\
718c2ecf20Sopenharmony_ci    else								\
728c2ecf20Sopenharmony_ci      {									\
738c2ecf20Sopenharmony_ci	X##_c = FP_CLS_NAN;						\
748c2ecf20Sopenharmony_ci	/* Check for signaling NaN */					\
758c2ecf20Sopenharmony_ci	if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))		\
768c2ecf20Sopenharmony_ci	  FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_SNAN);		\
778c2ecf20Sopenharmony_ci      }									\
788c2ecf20Sopenharmony_ci    break;								\
798c2ecf20Sopenharmony_ci  }									\
808c2ecf20Sopenharmony_ci} while (0)
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci/*
838c2ecf20Sopenharmony_ci * Before packing the bits back into the native fp result, take care
848c2ecf20Sopenharmony_ci * of such mundane things as rounding and overflow.  Also, for some
858c2ecf20Sopenharmony_ci * kinds of fp values, the original parts may not have been fully
868c2ecf20Sopenharmony_ci * extracted -- but that is ok, we can regenerate them now.
878c2ecf20Sopenharmony_ci */
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci#define _FP_PACK_CANONICAL(fs, wc, X)				\
908c2ecf20Sopenharmony_cido {								\
918c2ecf20Sopenharmony_ci  switch (X##_c)						\
928c2ecf20Sopenharmony_ci  {								\
938c2ecf20Sopenharmony_ci  case FP_CLS_NORMAL:						\
948c2ecf20Sopenharmony_ci    X##_e += _FP_EXPBIAS_##fs;					\
958c2ecf20Sopenharmony_ci    if (X##_e > 0)						\
968c2ecf20Sopenharmony_ci      {								\
978c2ecf20Sopenharmony_ci	_FP_ROUND(wc, X);					\
988c2ecf20Sopenharmony_ci	if (_FP_FRAC_OVERP_##wc(fs, X))				\
998c2ecf20Sopenharmony_ci	  {							\
1008c2ecf20Sopenharmony_ci	    _FP_FRAC_CLEAR_OVERP_##wc(fs, X);			\
1018c2ecf20Sopenharmony_ci	    X##_e++;						\
1028c2ecf20Sopenharmony_ci	  }							\
1038c2ecf20Sopenharmony_ci	_FP_FRAC_SRL_##wc(X, _FP_WORKBITS);			\
1048c2ecf20Sopenharmony_ci	if (X##_e >= _FP_EXPMAX_##fs)				\
1058c2ecf20Sopenharmony_ci	  {							\
1068c2ecf20Sopenharmony_ci	    /* overflow */					\
1078c2ecf20Sopenharmony_ci	    switch (FP_ROUNDMODE)				\
1088c2ecf20Sopenharmony_ci	      {							\
1098c2ecf20Sopenharmony_ci	      case FP_RND_NEAREST:				\
1108c2ecf20Sopenharmony_ci		X##_c = FP_CLS_INF;				\
1118c2ecf20Sopenharmony_ci		break;						\
1128c2ecf20Sopenharmony_ci	      case FP_RND_PINF:					\
1138c2ecf20Sopenharmony_ci		if (!X##_s) X##_c = FP_CLS_INF;			\
1148c2ecf20Sopenharmony_ci		break;						\
1158c2ecf20Sopenharmony_ci	      case FP_RND_MINF:					\
1168c2ecf20Sopenharmony_ci		if (X##_s) X##_c = FP_CLS_INF;			\
1178c2ecf20Sopenharmony_ci		break;						\
1188c2ecf20Sopenharmony_ci	      }							\
1198c2ecf20Sopenharmony_ci	    if (X##_c == FP_CLS_INF)				\
1208c2ecf20Sopenharmony_ci	      {							\
1218c2ecf20Sopenharmony_ci		/* Overflow to infinity */			\
1228c2ecf20Sopenharmony_ci		X##_e = _FP_EXPMAX_##fs;			\
1238c2ecf20Sopenharmony_ci		_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);	\
1248c2ecf20Sopenharmony_ci	      }							\
1258c2ecf20Sopenharmony_ci	    else						\
1268c2ecf20Sopenharmony_ci	      {							\
1278c2ecf20Sopenharmony_ci		/* Overflow to maximum normal */		\
1288c2ecf20Sopenharmony_ci		X##_e = _FP_EXPMAX_##fs - 1;			\
1298c2ecf20Sopenharmony_ci		_FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc);		\
1308c2ecf20Sopenharmony_ci	      }							\
1318c2ecf20Sopenharmony_ci	    FP_SET_EXCEPTION(FP_EX_OVERFLOW);			\
1328c2ecf20Sopenharmony_ci            FP_SET_EXCEPTION(FP_EX_INEXACT);			\
1338c2ecf20Sopenharmony_ci	  }							\
1348c2ecf20Sopenharmony_ci      }								\
1358c2ecf20Sopenharmony_ci    else							\
1368c2ecf20Sopenharmony_ci      {								\
1378c2ecf20Sopenharmony_ci	/* we've got a denormalized number */			\
1388c2ecf20Sopenharmony_ci	X##_e = -X##_e + 1;					\
1398c2ecf20Sopenharmony_ci	if (X##_e <= _FP_WFRACBITS_##fs)			\
1408c2ecf20Sopenharmony_ci	  {							\
1418c2ecf20Sopenharmony_ci	    _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs);	\
1428c2ecf20Sopenharmony_ci	    if (_FP_FRAC_HIGH_##fs(X)				\
1438c2ecf20Sopenharmony_ci		& (_FP_OVERFLOW_##fs >> 1))			\
1448c2ecf20Sopenharmony_ci	      {							\
1458c2ecf20Sopenharmony_ci	        X##_e = 1;					\
1468c2ecf20Sopenharmony_ci	        _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);	\
1478c2ecf20Sopenharmony_ci	      }							\
1488c2ecf20Sopenharmony_ci	    else						\
1498c2ecf20Sopenharmony_ci	      {							\
1508c2ecf20Sopenharmony_ci		_FP_ROUND(wc, X);				\
1518c2ecf20Sopenharmony_ci		if (_FP_FRAC_HIGH_##fs(X)			\
1528c2ecf20Sopenharmony_ci		   & (_FP_OVERFLOW_##fs >> 1))			\
1538c2ecf20Sopenharmony_ci		  {						\
1548c2ecf20Sopenharmony_ci		    X##_e = 1;					\
1558c2ecf20Sopenharmony_ci		    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);	\
1568c2ecf20Sopenharmony_ci		    FP_SET_EXCEPTION(FP_EX_INEXACT);		\
1578c2ecf20Sopenharmony_ci		  }						\
1588c2ecf20Sopenharmony_ci		else						\
1598c2ecf20Sopenharmony_ci		  {						\
1608c2ecf20Sopenharmony_ci		    X##_e = 0;					\
1618c2ecf20Sopenharmony_ci		    _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);		\
1628c2ecf20Sopenharmony_ci		  }						\
1638c2ecf20Sopenharmony_ci	      }							\
1648c2ecf20Sopenharmony_ci	    if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) ||		\
1658c2ecf20Sopenharmony_ci		(FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))	\
1668c2ecf20Sopenharmony_ci		FP_SET_EXCEPTION(FP_EX_UNDERFLOW);		\
1678c2ecf20Sopenharmony_ci	  }							\
1688c2ecf20Sopenharmony_ci	else							\
1698c2ecf20Sopenharmony_ci	  {							\
1708c2ecf20Sopenharmony_ci	    /* underflow to zero */				\
1718c2ecf20Sopenharmony_ci	    X##_e = 0;						\
1728c2ecf20Sopenharmony_ci	    if (!_FP_FRAC_ZEROP_##wc(X))			\
1738c2ecf20Sopenharmony_ci	      {							\
1748c2ecf20Sopenharmony_ci	        _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);		\
1758c2ecf20Sopenharmony_ci	        _FP_ROUND(wc, X);				\
1768c2ecf20Sopenharmony_ci	        _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS);	\
1778c2ecf20Sopenharmony_ci	      }							\
1788c2ecf20Sopenharmony_ci	    FP_SET_EXCEPTION(FP_EX_UNDERFLOW);			\
1798c2ecf20Sopenharmony_ci	  }							\
1808c2ecf20Sopenharmony_ci      }								\
1818c2ecf20Sopenharmony_ci    break;							\
1828c2ecf20Sopenharmony_ci								\
1838c2ecf20Sopenharmony_ci  case FP_CLS_ZERO:						\
1848c2ecf20Sopenharmony_ci    X##_e = 0;							\
1858c2ecf20Sopenharmony_ci    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			\
1868c2ecf20Sopenharmony_ci    break;							\
1878c2ecf20Sopenharmony_ci								\
1888c2ecf20Sopenharmony_ci  case FP_CLS_INF:						\
1898c2ecf20Sopenharmony_ci    X##_e = _FP_EXPMAX_##fs;					\
1908c2ecf20Sopenharmony_ci    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			\
1918c2ecf20Sopenharmony_ci    break;							\
1928c2ecf20Sopenharmony_ci								\
1938c2ecf20Sopenharmony_ci  case FP_CLS_NAN:						\
1948c2ecf20Sopenharmony_ci    X##_e = _FP_EXPMAX_##fs;					\
1958c2ecf20Sopenharmony_ci    if (!_FP_KEEPNANFRACP)					\
1968c2ecf20Sopenharmony_ci      {								\
1978c2ecf20Sopenharmony_ci	_FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);			\
1988c2ecf20Sopenharmony_ci	X##_s = _FP_NANSIGN_##fs;				\
1998c2ecf20Sopenharmony_ci      }								\
2008c2ecf20Sopenharmony_ci    else							\
2018c2ecf20Sopenharmony_ci      _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs;		\
2028c2ecf20Sopenharmony_ci    break;							\
2038c2ecf20Sopenharmony_ci  }								\
2048c2ecf20Sopenharmony_ci} while (0)
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci/* This one accepts raw argument and not cooked,  returns
2078c2ecf20Sopenharmony_ci * 1 if X is a signaling NaN.
2088c2ecf20Sopenharmony_ci */
2098c2ecf20Sopenharmony_ci#define _FP_ISSIGNAN(fs, wc, X)					\
2108c2ecf20Sopenharmony_ci({								\
2118c2ecf20Sopenharmony_ci  int __ret = 0;						\
2128c2ecf20Sopenharmony_ci  if (X##_e == _FP_EXPMAX_##fs)					\
2138c2ecf20Sopenharmony_ci    {								\
2148c2ecf20Sopenharmony_ci      if (!_FP_FRAC_ZEROP_##wc(X)				\
2158c2ecf20Sopenharmony_ci	  && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))	\
2168c2ecf20Sopenharmony_ci	__ret = 1;						\
2178c2ecf20Sopenharmony_ci    }								\
2188c2ecf20Sopenharmony_ci  __ret;							\
2198c2ecf20Sopenharmony_ci})
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci/*
2268c2ecf20Sopenharmony_ci * Main addition routine.  The input values should be cooked.
2278c2ecf20Sopenharmony_ci */
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP)				     \
2308c2ecf20Sopenharmony_cido {									     \
2318c2ecf20Sopenharmony_ci  switch (_FP_CLS_COMBINE(X##_c, Y##_c))				     \
2328c2ecf20Sopenharmony_ci  {									     \
2338c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):			     \
2348c2ecf20Sopenharmony_ci    {									     \
2358c2ecf20Sopenharmony_ci      /* shift the smaller number so that its exponent matches the larger */ \
2368c2ecf20Sopenharmony_ci      _FP_I_TYPE diff = X##_e - Y##_e;					     \
2378c2ecf20Sopenharmony_ci									     \
2388c2ecf20Sopenharmony_ci      if (diff < 0)							     \
2398c2ecf20Sopenharmony_ci	{								     \
2408c2ecf20Sopenharmony_ci	  diff = -diff;							     \
2418c2ecf20Sopenharmony_ci	  if (diff <= _FP_WFRACBITS_##fs)				     \
2428c2ecf20Sopenharmony_ci	    _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs);		     \
2438c2ecf20Sopenharmony_ci	  else if (!_FP_FRAC_ZEROP_##wc(X))				     \
2448c2ecf20Sopenharmony_ci	    _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);			     \
2458c2ecf20Sopenharmony_ci	  R##_e = Y##_e;						     \
2468c2ecf20Sopenharmony_ci	}								     \
2478c2ecf20Sopenharmony_ci      else								     \
2488c2ecf20Sopenharmony_ci	{								     \
2498c2ecf20Sopenharmony_ci	  if (diff > 0)							     \
2508c2ecf20Sopenharmony_ci	    {								     \
2518c2ecf20Sopenharmony_ci	      if (diff <= _FP_WFRACBITS_##fs)				     \
2528c2ecf20Sopenharmony_ci	        _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs);		     \
2538c2ecf20Sopenharmony_ci	      else if (!_FP_FRAC_ZEROP_##wc(Y))				     \
2548c2ecf20Sopenharmony_ci	        _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc);			     \
2558c2ecf20Sopenharmony_ci	    }								     \
2568c2ecf20Sopenharmony_ci	  R##_e = X##_e;						     \
2578c2ecf20Sopenharmony_ci	}								     \
2588c2ecf20Sopenharmony_ci									     \
2598c2ecf20Sopenharmony_ci      R##_c = FP_CLS_NORMAL;						     \
2608c2ecf20Sopenharmony_ci									     \
2618c2ecf20Sopenharmony_ci      if (X##_s == Y##_s)						     \
2628c2ecf20Sopenharmony_ci	{								     \
2638c2ecf20Sopenharmony_ci	  R##_s = X##_s;						     \
2648c2ecf20Sopenharmony_ci	  _FP_FRAC_ADD_##wc(R, X, Y);					     \
2658c2ecf20Sopenharmony_ci	  if (_FP_FRAC_OVERP_##wc(fs, R))				     \
2668c2ecf20Sopenharmony_ci	    {								     \
2678c2ecf20Sopenharmony_ci	      _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);		     \
2688c2ecf20Sopenharmony_ci	      R##_e++;							     \
2698c2ecf20Sopenharmony_ci	    }								     \
2708c2ecf20Sopenharmony_ci	}								     \
2718c2ecf20Sopenharmony_ci      else								     \
2728c2ecf20Sopenharmony_ci	{								     \
2738c2ecf20Sopenharmony_ci	  R##_s = X##_s;						     \
2748c2ecf20Sopenharmony_ci	  _FP_FRAC_SUB_##wc(R, X, Y);					     \
2758c2ecf20Sopenharmony_ci	  if (_FP_FRAC_ZEROP_##wc(R))					     \
2768c2ecf20Sopenharmony_ci	    {								     \
2778c2ecf20Sopenharmony_ci	      /* return an exact zero */				     \
2788c2ecf20Sopenharmony_ci	      if (FP_ROUNDMODE == FP_RND_MINF)				     \
2798c2ecf20Sopenharmony_ci		R##_s |= Y##_s;						     \
2808c2ecf20Sopenharmony_ci	      else							     \
2818c2ecf20Sopenharmony_ci		R##_s &= Y##_s;						     \
2828c2ecf20Sopenharmony_ci	      R##_c = FP_CLS_ZERO;					     \
2838c2ecf20Sopenharmony_ci	    }								     \
2848c2ecf20Sopenharmony_ci	  else								     \
2858c2ecf20Sopenharmony_ci	    {								     \
2868c2ecf20Sopenharmony_ci	      if (_FP_FRAC_NEGP_##wc(R))				     \
2878c2ecf20Sopenharmony_ci		{							     \
2888c2ecf20Sopenharmony_ci		  _FP_FRAC_SUB_##wc(R, Y, X);				     \
2898c2ecf20Sopenharmony_ci		  R##_s = Y##_s;					     \
2908c2ecf20Sopenharmony_ci		}							     \
2918c2ecf20Sopenharmony_ci									     \
2928c2ecf20Sopenharmony_ci	      /* renormalize after subtraction */			     \
2938c2ecf20Sopenharmony_ci	      _FP_FRAC_CLZ_##wc(diff, R);				     \
2948c2ecf20Sopenharmony_ci	      diff -= _FP_WFRACXBITS_##fs;				     \
2958c2ecf20Sopenharmony_ci	      if (diff)							     \
2968c2ecf20Sopenharmony_ci		{							     \
2978c2ecf20Sopenharmony_ci		  R##_e -= diff;					     \
2988c2ecf20Sopenharmony_ci		  _FP_FRAC_SLL_##wc(R, diff);				     \
2998c2ecf20Sopenharmony_ci		}							     \
3008c2ecf20Sopenharmony_ci	    }								     \
3018c2ecf20Sopenharmony_ci	}								     \
3028c2ecf20Sopenharmony_ci      break;								     \
3038c2ecf20Sopenharmony_ci    }									     \
3048c2ecf20Sopenharmony_ci									     \
3058c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):				     \
3068c2ecf20Sopenharmony_ci    _FP_CHOOSENAN(fs, wc, R, X, Y, OP);					     \
3078c2ecf20Sopenharmony_ci    break;								     \
3088c2ecf20Sopenharmony_ci									     \
3098c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):			     \
3108c2ecf20Sopenharmony_ci    R##_e = X##_e;							     \
3118c2ecf20Sopenharmony_ci	fallthrough;							     \
3128c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):			     \
3138c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):				     \
3148c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):				     \
3158c2ecf20Sopenharmony_ci    _FP_FRAC_COPY_##wc(R, X);						     \
3168c2ecf20Sopenharmony_ci    R##_s = X##_s;							     \
3178c2ecf20Sopenharmony_ci    R##_c = X##_c;							     \
3188c2ecf20Sopenharmony_ci    break;								     \
3198c2ecf20Sopenharmony_ci									     \
3208c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):			     \
3218c2ecf20Sopenharmony_ci    R##_e = Y##_e;							     \
3228c2ecf20Sopenharmony_ci	fallthrough;							     \
3238c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):			     \
3248c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):				     \
3258c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):				     \
3268c2ecf20Sopenharmony_ci    _FP_FRAC_COPY_##wc(R, Y);						     \
3278c2ecf20Sopenharmony_ci    R##_s = Y##_s;							     \
3288c2ecf20Sopenharmony_ci    R##_c = Y##_c;							     \
3298c2ecf20Sopenharmony_ci    break;								     \
3308c2ecf20Sopenharmony_ci									     \
3318c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):				     \
3328c2ecf20Sopenharmony_ci    if (X##_s != Y##_s)							     \
3338c2ecf20Sopenharmony_ci      {									     \
3348c2ecf20Sopenharmony_ci	/* +INF + -INF => NAN */					     \
3358c2ecf20Sopenharmony_ci	_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);				     \
3368c2ecf20Sopenharmony_ci	R##_s = _FP_NANSIGN_##fs;					     \
3378c2ecf20Sopenharmony_ci	R##_c = FP_CLS_NAN;						     \
3388c2ecf20Sopenharmony_ci	FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_ISI);		     \
3398c2ecf20Sopenharmony_ci	break;								     \
3408c2ecf20Sopenharmony_ci      }									     \
3418c2ecf20Sopenharmony_ci    /* FALLTHRU */							     \
3428c2ecf20Sopenharmony_ci									     \
3438c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):			     \
3448c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):				     \
3458c2ecf20Sopenharmony_ci    R##_s = X##_s;							     \
3468c2ecf20Sopenharmony_ci    R##_c = FP_CLS_INF;							     \
3478c2ecf20Sopenharmony_ci    break;								     \
3488c2ecf20Sopenharmony_ci									     \
3498c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):			     \
3508c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):				     \
3518c2ecf20Sopenharmony_ci    R##_s = Y##_s;							     \
3528c2ecf20Sopenharmony_ci    R##_c = FP_CLS_INF;							     \
3538c2ecf20Sopenharmony_ci    break;								     \
3548c2ecf20Sopenharmony_ci									     \
3558c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):			     \
3568c2ecf20Sopenharmony_ci    /* make sure the sign is correct */					     \
3578c2ecf20Sopenharmony_ci    if (FP_ROUNDMODE == FP_RND_MINF)					     \
3588c2ecf20Sopenharmony_ci      R##_s = X##_s | Y##_s;						     \
3598c2ecf20Sopenharmony_ci    else								     \
3608c2ecf20Sopenharmony_ci      R##_s = X##_s & Y##_s;						     \
3618c2ecf20Sopenharmony_ci    R##_c = FP_CLS_ZERO;						     \
3628c2ecf20Sopenharmony_ci    break;								     \
3638c2ecf20Sopenharmony_ci									     \
3648c2ecf20Sopenharmony_ci  default:								     \
3658c2ecf20Sopenharmony_ci    abort();								     \
3668c2ecf20Sopenharmony_ci  }									     \
3678c2ecf20Sopenharmony_ci} while (0)
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_ci#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+')
3708c2ecf20Sopenharmony_ci#define _FP_SUB(fs, wc, R, X, Y)					     \
3718c2ecf20Sopenharmony_ci  do {									     \
3728c2ecf20Sopenharmony_ci    if (Y##_c != FP_CLS_NAN) Y##_s ^= 1;				     \
3738c2ecf20Sopenharmony_ci    _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-');				     \
3748c2ecf20Sopenharmony_ci  } while (0)
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci/*
3788c2ecf20Sopenharmony_ci * Main negation routine.  FIXME -- when we care about setting exception
3798c2ecf20Sopenharmony_ci * bits reliably, this will not do.  We should examine all of the fp classes.
3808c2ecf20Sopenharmony_ci */
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_ci#define _FP_NEG(fs, wc, R, X)		\
3838c2ecf20Sopenharmony_ci  do {					\
3848c2ecf20Sopenharmony_ci    _FP_FRAC_COPY_##wc(R, X);		\
3858c2ecf20Sopenharmony_ci    R##_c = X##_c;			\
3868c2ecf20Sopenharmony_ci    R##_e = X##_e;			\
3878c2ecf20Sopenharmony_ci    R##_s = 1 ^ X##_s;			\
3888c2ecf20Sopenharmony_ci  } while (0)
3898c2ecf20Sopenharmony_ci
3908c2ecf20Sopenharmony_ci
3918c2ecf20Sopenharmony_ci/*
3928c2ecf20Sopenharmony_ci * Main multiplication routine.  The input values should be cooked.
3938c2ecf20Sopenharmony_ci */
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ci#define _FP_MUL(fs, wc, R, X, Y)			\
3968c2ecf20Sopenharmony_cido {							\
3978c2ecf20Sopenharmony_ci  R##_s = X##_s ^ Y##_s;				\
3988c2ecf20Sopenharmony_ci  switch (_FP_CLS_COMBINE(X##_c, Y##_c))		\
3998c2ecf20Sopenharmony_ci  {							\
4008c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):	\
4018c2ecf20Sopenharmony_ci    R##_c = FP_CLS_NORMAL;				\
4028c2ecf20Sopenharmony_ci    R##_e = X##_e + Y##_e + 1;				\
4038c2ecf20Sopenharmony_ci							\
4048c2ecf20Sopenharmony_ci    _FP_MUL_MEAT_##fs(R,X,Y);				\
4058c2ecf20Sopenharmony_ci							\
4068c2ecf20Sopenharmony_ci    if (_FP_FRAC_OVERP_##wc(fs, R))			\
4078c2ecf20Sopenharmony_ci      _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);	\
4088c2ecf20Sopenharmony_ci    else						\
4098c2ecf20Sopenharmony_ci      R##_e--;						\
4108c2ecf20Sopenharmony_ci    break;						\
4118c2ecf20Sopenharmony_ci							\
4128c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):		\
4138c2ecf20Sopenharmony_ci    _FP_CHOOSENAN(fs, wc, R, X, Y, '*');		\
4148c2ecf20Sopenharmony_ci    break;						\
4158c2ecf20Sopenharmony_ci							\
4168c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):	\
4178c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):		\
4188c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):		\
4198c2ecf20Sopenharmony_ci    R##_s = X##_s;					\
4208c2ecf20Sopenharmony_ci	  fallthrough;					\
4218c2ecf20Sopenharmony_ci							\
4228c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):		\
4238c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):	\
4248c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):	\
4258c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):	\
4268c2ecf20Sopenharmony_ci    _FP_FRAC_COPY_##wc(R, X);				\
4278c2ecf20Sopenharmony_ci    R##_c = X##_c;					\
4288c2ecf20Sopenharmony_ci    break;						\
4298c2ecf20Sopenharmony_ci							\
4308c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):	\
4318c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):		\
4328c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):		\
4338c2ecf20Sopenharmony_ci    R##_s = Y##_s;					\
4348c2ecf20Sopenharmony_ci	  fallthrough;					\
4358c2ecf20Sopenharmony_ci							\
4368c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):	\
4378c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):	\
4388c2ecf20Sopenharmony_ci    _FP_FRAC_COPY_##wc(R, Y);				\
4398c2ecf20Sopenharmony_ci    R##_c = Y##_c;					\
4408c2ecf20Sopenharmony_ci    break;						\
4418c2ecf20Sopenharmony_ci							\
4428c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):		\
4438c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):		\
4448c2ecf20Sopenharmony_ci    R##_s = _FP_NANSIGN_##fs;				\
4458c2ecf20Sopenharmony_ci    R##_c = FP_CLS_NAN;					\
4468c2ecf20Sopenharmony_ci    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
4478c2ecf20Sopenharmony_ci    FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_IMZ);\
4488c2ecf20Sopenharmony_ci    break;						\
4498c2ecf20Sopenharmony_ci							\
4508c2ecf20Sopenharmony_ci  default:						\
4518c2ecf20Sopenharmony_ci    abort();						\
4528c2ecf20Sopenharmony_ci  }							\
4538c2ecf20Sopenharmony_ci} while (0)
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_ci
4568c2ecf20Sopenharmony_ci/*
4578c2ecf20Sopenharmony_ci * Main division routine.  The input values should be cooked.
4588c2ecf20Sopenharmony_ci */
4598c2ecf20Sopenharmony_ci
4608c2ecf20Sopenharmony_ci#define _FP_DIV(fs, wc, R, X, Y)			\
4618c2ecf20Sopenharmony_cido {							\
4628c2ecf20Sopenharmony_ci  R##_s = X##_s ^ Y##_s;				\
4638c2ecf20Sopenharmony_ci  switch (_FP_CLS_COMBINE(X##_c, Y##_c))		\
4648c2ecf20Sopenharmony_ci  {							\
4658c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):	\
4668c2ecf20Sopenharmony_ci    R##_c = FP_CLS_NORMAL;				\
4678c2ecf20Sopenharmony_ci    R##_e = X##_e - Y##_e;				\
4688c2ecf20Sopenharmony_ci							\
4698c2ecf20Sopenharmony_ci    _FP_DIV_MEAT_##fs(R,X,Y);				\
4708c2ecf20Sopenharmony_ci    break;						\
4718c2ecf20Sopenharmony_ci							\
4728c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):		\
4738c2ecf20Sopenharmony_ci    _FP_CHOOSENAN(fs, wc, R, X, Y, '/');		\
4748c2ecf20Sopenharmony_ci    break;						\
4758c2ecf20Sopenharmony_ci							\
4768c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):	\
4778c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):		\
4788c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):		\
4798c2ecf20Sopenharmony_ci    R##_s = X##_s;					\
4808c2ecf20Sopenharmony_ci    _FP_FRAC_COPY_##wc(R, X);				\
4818c2ecf20Sopenharmony_ci    R##_c = X##_c;					\
4828c2ecf20Sopenharmony_ci    break;						\
4838c2ecf20Sopenharmony_ci							\
4848c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):	\
4858c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):		\
4868c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):		\
4878c2ecf20Sopenharmony_ci    R##_s = Y##_s;					\
4888c2ecf20Sopenharmony_ci    _FP_FRAC_COPY_##wc(R, Y);				\
4898c2ecf20Sopenharmony_ci    R##_c = Y##_c;					\
4908c2ecf20Sopenharmony_ci    break;						\
4918c2ecf20Sopenharmony_ci							\
4928c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):	\
4938c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):		\
4948c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):	\
4958c2ecf20Sopenharmony_ci    R##_c = FP_CLS_ZERO;				\
4968c2ecf20Sopenharmony_ci    break;						\
4978c2ecf20Sopenharmony_ci							\
4988c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):	\
4998c2ecf20Sopenharmony_ci    FP_SET_EXCEPTION(FP_EX_DIVZERO);			\
5008c2ecf20Sopenharmony_ci	fallthrough;					\
5018c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):		\
5028c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):	\
5038c2ecf20Sopenharmony_ci    R##_c = FP_CLS_INF;					\
5048c2ecf20Sopenharmony_ci    break;						\
5058c2ecf20Sopenharmony_ci							\
5068c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):		\
5078c2ecf20Sopenharmony_ci    R##_s = _FP_NANSIGN_##fs;				\
5088c2ecf20Sopenharmony_ci    R##_c = FP_CLS_NAN;					\
5098c2ecf20Sopenharmony_ci    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
5108c2ecf20Sopenharmony_ci    FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_IDI);\
5118c2ecf20Sopenharmony_ci    break;						\
5128c2ecf20Sopenharmony_ci							\
5138c2ecf20Sopenharmony_ci  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):	\
5148c2ecf20Sopenharmony_ci    R##_s = _FP_NANSIGN_##fs;				\
5158c2ecf20Sopenharmony_ci    R##_c = FP_CLS_NAN;					\
5168c2ecf20Sopenharmony_ci    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
5178c2ecf20Sopenharmony_ci    FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_ZDZ);\
5188c2ecf20Sopenharmony_ci    break;						\
5198c2ecf20Sopenharmony_ci							\
5208c2ecf20Sopenharmony_ci  default:						\
5218c2ecf20Sopenharmony_ci    abort();						\
5228c2ecf20Sopenharmony_ci  }							\
5238c2ecf20Sopenharmony_ci} while (0)
5248c2ecf20Sopenharmony_ci
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_ci/*
5278c2ecf20Sopenharmony_ci * Main differential comparison routine.  The inputs should be raw not
5288c2ecf20Sopenharmony_ci * cooked.  The return is -1,0,1 for normal values, 2 otherwise.
5298c2ecf20Sopenharmony_ci */
5308c2ecf20Sopenharmony_ci
5318c2ecf20Sopenharmony_ci#define _FP_CMP(fs, wc, ret, X, Y, un)					\
5328c2ecf20Sopenharmony_ci  do {									\
5338c2ecf20Sopenharmony_ci    /* NANs are unordered */						\
5348c2ecf20Sopenharmony_ci    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))		\
5358c2ecf20Sopenharmony_ci	|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))	\
5368c2ecf20Sopenharmony_ci      {									\
5378c2ecf20Sopenharmony_ci	ret = un;							\
5388c2ecf20Sopenharmony_ci      }									\
5398c2ecf20Sopenharmony_ci    else								\
5408c2ecf20Sopenharmony_ci      {									\
5418c2ecf20Sopenharmony_ci	int __is_zero_x;						\
5428c2ecf20Sopenharmony_ci	int __is_zero_y;						\
5438c2ecf20Sopenharmony_ci									\
5448c2ecf20Sopenharmony_ci	__is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0;	\
5458c2ecf20Sopenharmony_ci	__is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0;	\
5468c2ecf20Sopenharmony_ci									\
5478c2ecf20Sopenharmony_ci	if (__is_zero_x && __is_zero_y)					\
5488c2ecf20Sopenharmony_ci		ret = 0;						\
5498c2ecf20Sopenharmony_ci	else if (__is_zero_x)						\
5508c2ecf20Sopenharmony_ci		ret = Y##_s ? 1 : -1;					\
5518c2ecf20Sopenharmony_ci	else if (__is_zero_y)						\
5528c2ecf20Sopenharmony_ci		ret = X##_s ? -1 : 1;					\
5538c2ecf20Sopenharmony_ci	else if (X##_s != Y##_s)					\
5548c2ecf20Sopenharmony_ci	  ret = X##_s ? -1 : 1;						\
5558c2ecf20Sopenharmony_ci	else if (X##_e > Y##_e)						\
5568c2ecf20Sopenharmony_ci	  ret = X##_s ? -1 : 1;						\
5578c2ecf20Sopenharmony_ci	else if (X##_e < Y##_e)						\
5588c2ecf20Sopenharmony_ci	  ret = X##_s ? 1 : -1;						\
5598c2ecf20Sopenharmony_ci	else if (_FP_FRAC_GT_##wc(X, Y))				\
5608c2ecf20Sopenharmony_ci	  ret = X##_s ? -1 : 1;						\
5618c2ecf20Sopenharmony_ci	else if (_FP_FRAC_GT_##wc(Y, X))				\
5628c2ecf20Sopenharmony_ci	  ret = X##_s ? 1 : -1;						\
5638c2ecf20Sopenharmony_ci	else								\
5648c2ecf20Sopenharmony_ci	  ret = 0;							\
5658c2ecf20Sopenharmony_ci      }									\
5668c2ecf20Sopenharmony_ci  } while (0)
5678c2ecf20Sopenharmony_ci
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci/* Simplification for strict equality.  */
5708c2ecf20Sopenharmony_ci
5718c2ecf20Sopenharmony_ci#define _FP_CMP_EQ(fs, wc, ret, X, Y)					  \
5728c2ecf20Sopenharmony_ci  do {									  \
5738c2ecf20Sopenharmony_ci    /* NANs are unordered */						  \
5748c2ecf20Sopenharmony_ci    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))		  \
5758c2ecf20Sopenharmony_ci	|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))	  \
5768c2ecf20Sopenharmony_ci      {									  \
5778c2ecf20Sopenharmony_ci	ret = 1;							  \
5788c2ecf20Sopenharmony_ci      }									  \
5798c2ecf20Sopenharmony_ci    else								  \
5808c2ecf20Sopenharmony_ci      {									  \
5818c2ecf20Sopenharmony_ci	ret = !(X##_e == Y##_e						  \
5828c2ecf20Sopenharmony_ci		&& _FP_FRAC_EQ_##wc(X, Y)				  \
5838c2ecf20Sopenharmony_ci		&& (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
5848c2ecf20Sopenharmony_ci      }									  \
5858c2ecf20Sopenharmony_ci  } while (0)
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_ci/*
5888c2ecf20Sopenharmony_ci * Main square root routine.  The input value should be cooked.
5898c2ecf20Sopenharmony_ci */
5908c2ecf20Sopenharmony_ci
5918c2ecf20Sopenharmony_ci#define _FP_SQRT(fs, wc, R, X)						\
5928c2ecf20Sopenharmony_cido {									\
5938c2ecf20Sopenharmony_ci    _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S);			\
5948c2ecf20Sopenharmony_ci    _FP_W_TYPE q;							\
5958c2ecf20Sopenharmony_ci    switch (X##_c)							\
5968c2ecf20Sopenharmony_ci    {									\
5978c2ecf20Sopenharmony_ci    case FP_CLS_NAN:							\
5988c2ecf20Sopenharmony_ci	_FP_FRAC_COPY_##wc(R, X);					\
5998c2ecf20Sopenharmony_ci	R##_s = X##_s;							\
6008c2ecf20Sopenharmony_ci    	R##_c = FP_CLS_NAN;						\
6018c2ecf20Sopenharmony_ci    	break;								\
6028c2ecf20Sopenharmony_ci    case FP_CLS_INF:							\
6038c2ecf20Sopenharmony_ci    	if (X##_s)							\
6048c2ecf20Sopenharmony_ci    	  {								\
6058c2ecf20Sopenharmony_ci    	    R##_s = _FP_NANSIGN_##fs;					\
6068c2ecf20Sopenharmony_ci	    R##_c = FP_CLS_NAN; /* NAN */				\
6078c2ecf20Sopenharmony_ci	    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);			\
6088c2ecf20Sopenharmony_ci	    FP_SET_EXCEPTION(FP_EX_INVALID);				\
6098c2ecf20Sopenharmony_ci    	  }								\
6108c2ecf20Sopenharmony_ci    	else								\
6118c2ecf20Sopenharmony_ci    	  {								\
6128c2ecf20Sopenharmony_ci    	    R##_s = 0;							\
6138c2ecf20Sopenharmony_ci    	    R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */			\
6148c2ecf20Sopenharmony_ci    	  }								\
6158c2ecf20Sopenharmony_ci    	break;								\
6168c2ecf20Sopenharmony_ci    case FP_CLS_ZERO:							\
6178c2ecf20Sopenharmony_ci	R##_s = X##_s;							\
6188c2ecf20Sopenharmony_ci	R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */			\
6198c2ecf20Sopenharmony_ci	break;								\
6208c2ecf20Sopenharmony_ci    case FP_CLS_NORMAL:							\
6218c2ecf20Sopenharmony_ci    	R##_s = 0;							\
6228c2ecf20Sopenharmony_ci        if (X##_s)							\
6238c2ecf20Sopenharmony_ci          {								\
6248c2ecf20Sopenharmony_ci	    R##_c = FP_CLS_NAN; /* sNAN */				\
6258c2ecf20Sopenharmony_ci	    R##_s = _FP_NANSIGN_##fs;					\
6268c2ecf20Sopenharmony_ci	    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);			\
6278c2ecf20Sopenharmony_ci	    FP_SET_EXCEPTION(FP_EX_INVALID);				\
6288c2ecf20Sopenharmony_ci	    break;							\
6298c2ecf20Sopenharmony_ci          }								\
6308c2ecf20Sopenharmony_ci    	R##_c = FP_CLS_NORMAL;						\
6318c2ecf20Sopenharmony_ci        if (X##_e & 1)							\
6328c2ecf20Sopenharmony_ci          _FP_FRAC_SLL_##wc(X, 1);					\
6338c2ecf20Sopenharmony_ci        R##_e = X##_e >> 1;						\
6348c2ecf20Sopenharmony_ci        _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc);			\
6358c2ecf20Sopenharmony_ci        _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc);			\
6368c2ecf20Sopenharmony_ci        q = _FP_OVERFLOW_##fs >> 1;					\
6378c2ecf20Sopenharmony_ci        _FP_SQRT_MEAT_##wc(R, S, T, X, q);				\
6388c2ecf20Sopenharmony_ci    }									\
6398c2ecf20Sopenharmony_ci  } while (0)
6408c2ecf20Sopenharmony_ci
6418c2ecf20Sopenharmony_ci/*
6428c2ecf20Sopenharmony_ci * Convert from FP to integer
6438c2ecf20Sopenharmony_ci */
6448c2ecf20Sopenharmony_ci
6458c2ecf20Sopenharmony_ci/* RSIGNED can have following values:
6468c2ecf20Sopenharmony_ci * 0:  the number is required to be 0..(2^rsize)-1, if not, NV is set plus
6478c2ecf20Sopenharmony_ci *     the result is either 0 or (2^rsize)-1 depending on the sign in such case.
6488c2ecf20Sopenharmony_ci * 1:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
6498c2ecf20Sopenharmony_ci *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
6508c2ecf20Sopenharmony_ci *     on the sign in such case.
6518c2ecf20Sopenharmony_ci * 2:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
6528c2ecf20Sopenharmony_ci *     set plus the result is truncated to fit into destination.
6538c2ecf20Sopenharmony_ci * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
6548c2ecf20Sopenharmony_ci *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
6558c2ecf20Sopenharmony_ci *     on the sign in such case.
6568c2ecf20Sopenharmony_ci */
6578c2ecf20Sopenharmony_ci#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)				\
6588c2ecf20Sopenharmony_ci  do {										\
6598c2ecf20Sopenharmony_ci    switch (X##_c)								\
6608c2ecf20Sopenharmony_ci      {										\
6618c2ecf20Sopenharmony_ci      case FP_CLS_NORMAL:							\
6628c2ecf20Sopenharmony_ci	if (X##_e < 0)								\
6638c2ecf20Sopenharmony_ci	  {									\
6648c2ecf20Sopenharmony_ci	    FP_SET_EXCEPTION(FP_EX_INEXACT);					\
6658c2ecf20Sopenharmony_ci	  case FP_CLS_ZERO:							\
6668c2ecf20Sopenharmony_ci	    r = 0;								\
6678c2ecf20Sopenharmony_ci	  }									\
6688c2ecf20Sopenharmony_ci	else if (X##_e >= rsize - (rsigned > 0 || X##_s)			\
6698c2ecf20Sopenharmony_ci		 || (!rsigned && X##_s))					\
6708c2ecf20Sopenharmony_ci	  {	/* overflow */							\
6718c2ecf20Sopenharmony_ci	  case FP_CLS_NAN:                                                      \
6728c2ecf20Sopenharmony_ci	  case FP_CLS_INF:							\
6738c2ecf20Sopenharmony_ci	    if (rsigned == 2)							\
6748c2ecf20Sopenharmony_ci	      {									\
6758c2ecf20Sopenharmony_ci		if (X##_c != FP_CLS_NORMAL					\
6768c2ecf20Sopenharmony_ci		    || X##_e >= rsize - 1 + _FP_WFRACBITS_##fs)			\
6778c2ecf20Sopenharmony_ci		  r = 0;							\
6788c2ecf20Sopenharmony_ci		else								\
6798c2ecf20Sopenharmony_ci		  {								\
6808c2ecf20Sopenharmony_ci		    _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));	\
6818c2ecf20Sopenharmony_ci		    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);			\
6828c2ecf20Sopenharmony_ci		  }								\
6838c2ecf20Sopenharmony_ci	      }									\
6848c2ecf20Sopenharmony_ci	    else if (rsigned)							\
6858c2ecf20Sopenharmony_ci	      {									\
6868c2ecf20Sopenharmony_ci		r = 1;								\
6878c2ecf20Sopenharmony_ci		r <<= rsize - 1;						\
6888c2ecf20Sopenharmony_ci		r -= 1 - X##_s;							\
6898c2ecf20Sopenharmony_ci	      }									\
6908c2ecf20Sopenharmony_ci	    else								\
6918c2ecf20Sopenharmony_ci	      {									\
6928c2ecf20Sopenharmony_ci		r = 0;								\
6938c2ecf20Sopenharmony_ci		if (!X##_s)							\
6948c2ecf20Sopenharmony_ci		  r = ~r;							\
6958c2ecf20Sopenharmony_ci	      }									\
6968c2ecf20Sopenharmony_ci	    FP_SET_EXCEPTION(FP_EX_INVALID);					\
6978c2ecf20Sopenharmony_ci	  }									\
6988c2ecf20Sopenharmony_ci	else									\
6998c2ecf20Sopenharmony_ci	  {									\
7008c2ecf20Sopenharmony_ci	    if (_FP_W_TYPE_SIZE*wc < rsize)					\
7018c2ecf20Sopenharmony_ci	      {									\
7028c2ecf20Sopenharmony_ci		_FP_FRAC_ASSEMBLE_##wc(r, X, rsize);				\
7038c2ecf20Sopenharmony_ci		r <<= X##_e - _FP_WFRACBITS_##fs;				\
7048c2ecf20Sopenharmony_ci	      }									\
7058c2ecf20Sopenharmony_ci	    else								\
7068c2ecf20Sopenharmony_ci	      {									\
7078c2ecf20Sopenharmony_ci		if (X##_e >= _FP_WFRACBITS_##fs)				\
7088c2ecf20Sopenharmony_ci		  _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));	\
7098c2ecf20Sopenharmony_ci		else if (X##_e < _FP_WFRACBITS_##fs - 1)			\
7108c2ecf20Sopenharmony_ci		  {								\
7118c2ecf20Sopenharmony_ci		    _FP_FRAC_SRS_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 2),	\
7128c2ecf20Sopenharmony_ci				      _FP_WFRACBITS_##fs);			\
7138c2ecf20Sopenharmony_ci		    if (_FP_FRAC_LOW_##wc(X) & 1)				\
7148c2ecf20Sopenharmony_ci		      FP_SET_EXCEPTION(FP_EX_INEXACT);				\
7158c2ecf20Sopenharmony_ci		    _FP_FRAC_SRL_##wc(X, 1);					\
7168c2ecf20Sopenharmony_ci		  }								\
7178c2ecf20Sopenharmony_ci		_FP_FRAC_ASSEMBLE_##wc(r, X, rsize);				\
7188c2ecf20Sopenharmony_ci	      }									\
7198c2ecf20Sopenharmony_ci	    if (rsigned && X##_s)						\
7208c2ecf20Sopenharmony_ci	      r = -r;								\
7218c2ecf20Sopenharmony_ci	  }									\
7228c2ecf20Sopenharmony_ci	break;									\
7238c2ecf20Sopenharmony_ci      }										\
7248c2ecf20Sopenharmony_ci  } while (0)
7258c2ecf20Sopenharmony_ci
7268c2ecf20Sopenharmony_ci#define _FP_TO_INT_ROUND(fs, wc, r, X, rsize, rsigned)				\
7278c2ecf20Sopenharmony_ci  do {										\
7288c2ecf20Sopenharmony_ci    r = 0;									\
7298c2ecf20Sopenharmony_ci    switch (X##_c)								\
7308c2ecf20Sopenharmony_ci      {										\
7318c2ecf20Sopenharmony_ci      case FP_CLS_NORMAL:							\
7328c2ecf20Sopenharmony_ci	if (X##_e >= _FP_FRACBITS_##fs - 1)					\
7338c2ecf20Sopenharmony_ci	  {									\
7348c2ecf20Sopenharmony_ci	    if (X##_e < rsize - 1 + _FP_WFRACBITS_##fs)				\
7358c2ecf20Sopenharmony_ci	      {									\
7368c2ecf20Sopenharmony_ci		if (X##_e >= _FP_WFRACBITS_##fs - 1)				\
7378c2ecf20Sopenharmony_ci		  {								\
7388c2ecf20Sopenharmony_ci		    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);			\
7398c2ecf20Sopenharmony_ci		    r <<= X##_e - _FP_WFRACBITS_##fs + 1;			\
7408c2ecf20Sopenharmony_ci		  }								\
7418c2ecf20Sopenharmony_ci		else								\
7428c2ecf20Sopenharmony_ci		  {								\
7438c2ecf20Sopenharmony_ci		    _FP_FRAC_SRL_##wc(X, _FP_WORKBITS - X##_e			\
7448c2ecf20Sopenharmony_ci				      + _FP_FRACBITS_##fs - 1);			\
7458c2ecf20Sopenharmony_ci		    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);			\
7468c2ecf20Sopenharmony_ci		  }								\
7478c2ecf20Sopenharmony_ci	      }									\
7488c2ecf20Sopenharmony_ci	  }									\
7498c2ecf20Sopenharmony_ci	else									\
7508c2ecf20Sopenharmony_ci	  {									\
7518c2ecf20Sopenharmony_ci	    int _lz0, _lz1;							\
7528c2ecf20Sopenharmony_ci	    if (X##_e <= -_FP_WORKBITS - 1)					\
7538c2ecf20Sopenharmony_ci	      _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);				\
7548c2ecf20Sopenharmony_ci	    else								\
7558c2ecf20Sopenharmony_ci	      _FP_FRAC_SRS_##wc(X, _FP_FRACBITS_##fs - 1 - X##_e,		\
7568c2ecf20Sopenharmony_ci				_FP_WFRACBITS_##fs);				\
7578c2ecf20Sopenharmony_ci	    _FP_FRAC_CLZ_##wc(_lz0, X);						\
7588c2ecf20Sopenharmony_ci	    _FP_ROUND(wc, X);							\
7598c2ecf20Sopenharmony_ci	    _FP_FRAC_CLZ_##wc(_lz1, X);						\
7608c2ecf20Sopenharmony_ci	    if (_lz1 < _lz0)							\
7618c2ecf20Sopenharmony_ci	      X##_e++; /* For overflow detection.  */				\
7628c2ecf20Sopenharmony_ci	    _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);					\
7638c2ecf20Sopenharmony_ci	    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);				\
7648c2ecf20Sopenharmony_ci	  }									\
7658c2ecf20Sopenharmony_ci	if (rsigned && X##_s)							\
7668c2ecf20Sopenharmony_ci	  r = -r;								\
7678c2ecf20Sopenharmony_ci	if (X##_e >= rsize - (rsigned > 0 || X##_s)				\
7688c2ecf20Sopenharmony_ci	    || (!rsigned && X##_s))						\
7698c2ecf20Sopenharmony_ci	  {	/* overflow */							\
7708c2ecf20Sopenharmony_ci	  case FP_CLS_NAN:                                                      \
7718c2ecf20Sopenharmony_ci	  case FP_CLS_INF:							\
7728c2ecf20Sopenharmony_ci	    if (!rsigned)							\
7738c2ecf20Sopenharmony_ci	      {									\
7748c2ecf20Sopenharmony_ci		r = 0;								\
7758c2ecf20Sopenharmony_ci		if (!X##_s)							\
7768c2ecf20Sopenharmony_ci		  r = ~r;							\
7778c2ecf20Sopenharmony_ci	      }									\
7788c2ecf20Sopenharmony_ci	    else if (rsigned != 2)						\
7798c2ecf20Sopenharmony_ci	      {									\
7808c2ecf20Sopenharmony_ci		r = 1;								\
7818c2ecf20Sopenharmony_ci		r <<= rsize - 1;						\
7828c2ecf20Sopenharmony_ci		r -= 1 - X##_s;							\
7838c2ecf20Sopenharmony_ci	      }									\
7848c2ecf20Sopenharmony_ci	    FP_SET_EXCEPTION(FP_EX_INVALID);					\
7858c2ecf20Sopenharmony_ci	  }									\
7868c2ecf20Sopenharmony_ci	break;									\
7878c2ecf20Sopenharmony_ci      case FP_CLS_ZERO:								\
7888c2ecf20Sopenharmony_ci        break;									\
7898c2ecf20Sopenharmony_ci      }										\
7908c2ecf20Sopenharmony_ci  } while (0)
7918c2ecf20Sopenharmony_ci
7928c2ecf20Sopenharmony_ci#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)			\
7938c2ecf20Sopenharmony_ci  do {									\
7948c2ecf20Sopenharmony_ci    if (r)								\
7958c2ecf20Sopenharmony_ci      {									\
7968c2ecf20Sopenharmony_ci        unsigned rtype ur_;						\
7978c2ecf20Sopenharmony_ci	X##_c = FP_CLS_NORMAL;						\
7988c2ecf20Sopenharmony_ci									\
7998c2ecf20Sopenharmony_ci	if ((X##_s = (r < 0)))						\
8008c2ecf20Sopenharmony_ci	  ur_ = (unsigned rtype) -r;					\
8018c2ecf20Sopenharmony_ci	else								\
8028c2ecf20Sopenharmony_ci	  ur_ = (unsigned rtype) r;					\
8038c2ecf20Sopenharmony_ci	(void) (((rsize) <= _FP_W_TYPE_SIZE)				\
8048c2ecf20Sopenharmony_ci		? ({ __FP_CLZ(X##_e, ur_); })				\
8058c2ecf20Sopenharmony_ci		: ({							\
8068c2ecf20Sopenharmony_ci		     __FP_CLZ_2(X##_e, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE),  \
8078c2ecf20Sopenharmony_ci							    (_FP_W_TYPE)ur_); \
8088c2ecf20Sopenharmony_ci		  }));							\
8098c2ecf20Sopenharmony_ci	if (rsize < _FP_W_TYPE_SIZE)					\
8108c2ecf20Sopenharmony_ci		X##_e -= (_FP_W_TYPE_SIZE - rsize);			\
8118c2ecf20Sopenharmony_ci	X##_e = rsize - X##_e - 1;					\
8128c2ecf20Sopenharmony_ci									\
8138c2ecf20Sopenharmony_ci	if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs <= X##_e)	\
8148c2ecf20Sopenharmony_ci	  __FP_FRAC_SRS_1(ur_, (X##_e - _FP_WFRACBITS_##fs + 1), rsize);\
8158c2ecf20Sopenharmony_ci	_FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize);			\
8168c2ecf20Sopenharmony_ci	if ((_FP_WFRACBITS_##fs - X##_e - 1) > 0)			\
8178c2ecf20Sopenharmony_ci	  _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));	\
8188c2ecf20Sopenharmony_ci      }									\
8198c2ecf20Sopenharmony_ci    else								\
8208c2ecf20Sopenharmony_ci      {									\
8218c2ecf20Sopenharmony_ci	X##_c = FP_CLS_ZERO, X##_s = 0;					\
8228c2ecf20Sopenharmony_ci      }									\
8238c2ecf20Sopenharmony_ci  } while (0)
8248c2ecf20Sopenharmony_ci
8258c2ecf20Sopenharmony_ci
8268c2ecf20Sopenharmony_ci#define FP_CONV(dfs,sfs,dwc,swc,D,S)			\
8278c2ecf20Sopenharmony_ci  do {							\
8288c2ecf20Sopenharmony_ci    _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S);	\
8298c2ecf20Sopenharmony_ci    D##_e = S##_e;					\
8308c2ecf20Sopenharmony_ci    D##_c = S##_c;					\
8318c2ecf20Sopenharmony_ci    D##_s = S##_s;					\
8328c2ecf20Sopenharmony_ci  } while (0)
8338c2ecf20Sopenharmony_ci
8348c2ecf20Sopenharmony_ci/*
8358c2ecf20Sopenharmony_ci * Helper primitives.
8368c2ecf20Sopenharmony_ci */
8378c2ecf20Sopenharmony_ci
8388c2ecf20Sopenharmony_ci/* Count leading zeros in a word.  */
8398c2ecf20Sopenharmony_ci
8408c2ecf20Sopenharmony_ci#ifndef __FP_CLZ
8418c2ecf20Sopenharmony_ci#if _FP_W_TYPE_SIZE < 64
8428c2ecf20Sopenharmony_ci/* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
8438c2ecf20Sopenharmony_ci#define __FP_CLZ(r, x)				\
8448c2ecf20Sopenharmony_ci  do {						\
8458c2ecf20Sopenharmony_ci    _FP_W_TYPE _t = (x);			\
8468c2ecf20Sopenharmony_ci    r = _FP_W_TYPE_SIZE - 1;			\
8478c2ecf20Sopenharmony_ci    if (_t > 0xffff) r -= 16;			\
8488c2ecf20Sopenharmony_ci    if (_t > 0xffff) _t >>= 16;			\
8498c2ecf20Sopenharmony_ci    if (_t > 0xff) r -= 8;			\
8508c2ecf20Sopenharmony_ci    if (_t > 0xff) _t >>= 8;			\
8518c2ecf20Sopenharmony_ci    if (_t & 0xf0) r -= 4;			\
8528c2ecf20Sopenharmony_ci    if (_t & 0xf0) _t >>= 4;			\
8538c2ecf20Sopenharmony_ci    if (_t & 0xc) r -= 2;			\
8548c2ecf20Sopenharmony_ci    if (_t & 0xc) _t >>= 2;			\
8558c2ecf20Sopenharmony_ci    if (_t & 0x2) r -= 1;			\
8568c2ecf20Sopenharmony_ci  } while (0)
8578c2ecf20Sopenharmony_ci#else /* not _FP_W_TYPE_SIZE < 64 */
8588c2ecf20Sopenharmony_ci#define __FP_CLZ(r, x)				\
8598c2ecf20Sopenharmony_ci  do {						\
8608c2ecf20Sopenharmony_ci    _FP_W_TYPE _t = (x);			\
8618c2ecf20Sopenharmony_ci    r = _FP_W_TYPE_SIZE - 1;			\
8628c2ecf20Sopenharmony_ci    if (_t > 0xffffffff) r -= 32;		\
8638c2ecf20Sopenharmony_ci    if (_t > 0xffffffff) _t >>= 32;		\
8648c2ecf20Sopenharmony_ci    if (_t > 0xffff) r -= 16;			\
8658c2ecf20Sopenharmony_ci    if (_t > 0xffff) _t >>= 16;			\
8668c2ecf20Sopenharmony_ci    if (_t > 0xff) r -= 8;			\
8678c2ecf20Sopenharmony_ci    if (_t > 0xff) _t >>= 8;			\
8688c2ecf20Sopenharmony_ci    if (_t & 0xf0) r -= 4;			\
8698c2ecf20Sopenharmony_ci    if (_t & 0xf0) _t >>= 4;			\
8708c2ecf20Sopenharmony_ci    if (_t & 0xc) r -= 2;			\
8718c2ecf20Sopenharmony_ci    if (_t & 0xc) _t >>= 2;			\
8728c2ecf20Sopenharmony_ci    if (_t & 0x2) r -= 1;			\
8738c2ecf20Sopenharmony_ci  } while (0)
8748c2ecf20Sopenharmony_ci#endif /* not _FP_W_TYPE_SIZE < 64 */
8758c2ecf20Sopenharmony_ci#endif /* ndef __FP_CLZ */
8768c2ecf20Sopenharmony_ci
8778c2ecf20Sopenharmony_ci#define _FP_DIV_HELP_imm(q, r, n, d)		\
8788c2ecf20Sopenharmony_ci  do {						\
8798c2ecf20Sopenharmony_ci    q = n / d, r = n % d;			\
8808c2ecf20Sopenharmony_ci  } while (0)
8818c2ecf20Sopenharmony_ci
8828c2ecf20Sopenharmony_ci#endif /* __MATH_EMU_OP_COMMON_H__ */
883