VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   1) /* Software floating-point emulation. Common operations.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   2)    Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   3)    This file is part of the GNU C Library.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   4)    Contributed by Richard Henderson (rth@cygnus.com),
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   5) 		  Jakub Jelinek (jj@ultra.linux.cz),
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   6) 		  David S. Miller (davem@redhat.com) and
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   7) 		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   8) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700   9)    The GNU C Library is free software; you can redistribute it and/or
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  10)    modify it under the terms of the GNU Library General Public License as
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  11)    published by the Free Software Foundation; either version 2 of the
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  12)    License, or (at your option) any later version.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  13) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  14)    The GNU C Library is distributed in the hope that it will be useful,
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  15)    but WITHOUT ANY WARRANTY; without even the implied warranty of
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  16)    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  17)    Library General Public License for more details.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  18) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  19)    You should have received a copy of the GNU Library General Public
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  20)    License along with the GNU C Library; see the file COPYING.LIB.  If
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  21)    not, write to the Free Software Foundation, Inc.,
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  22)    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  23) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  24) #ifndef __MATH_EMU_OP_COMMON_H__
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  25) #define __MATH_EMU_OP_COMMON_H__
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  26) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  27) #define _FP_DECL(wc, X)			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  28)   _FP_I_TYPE X##_c=0, X##_s=0, X##_e=0;	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  29)   _FP_FRAC_DECL_##wc(X)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  30) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  31) /*
c41b20e721ea4 (Adam Buchbinder     2009-12-11 16:35:39 -0500  32)  * Finish truly unpacking a native fp value by classifying the kind
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  33)  * of fp value and normalizing both the exponent and the fraction.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  34)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  35) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  36) #define _FP_UNPACK_CANONICAL(fs, wc, X)					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  37) do {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  38)   switch (X##_e)							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  39)   {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  40)   default:								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  41)     _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  42)     _FP_FRAC_SLL_##wc(X, _FP_WORKBITS);					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  43)     X##_e -= _FP_EXPBIAS_##fs;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  44)     X##_c = FP_CLS_NORMAL;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  45)     break;								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  46) 									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  47)   case 0:								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  48)     if (_FP_FRAC_ZEROP_##wc(X))						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  49)       X##_c = FP_CLS_ZERO;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  50)     else								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  51)       {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  52) 	/* a denormalized number */					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  53) 	_FP_I_TYPE _shift;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  54) 	_FP_FRAC_CLZ_##wc(_shift, X);					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  55) 	_shift -= _FP_FRACXBITS_##fs;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  56) 	_FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS));			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  57) 	X##_e -= _FP_EXPBIAS_##fs - 1 + _shift;				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  58) 	X##_c = FP_CLS_NORMAL;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  59) 	FP_SET_EXCEPTION(FP_EX_DENORM);					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  60) 	if (FP_DENORM_ZERO)						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  61) 	  {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  62) 	    FP_SET_EXCEPTION(FP_EX_INEXACT);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  63) 	    X##_c = FP_CLS_ZERO;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  64) 	  }								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  65)       }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  66)     break;								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  67) 									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  68)   case _FP_EXPMAX_##fs:							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  69)     if (_FP_FRAC_ZEROP_##wc(X))						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  70)       X##_c = FP_CLS_INF;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  71)     else								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  72)       {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  73) 	X##_c = FP_CLS_NAN;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  74) 	/* Check for signaling NaN */					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  75) 	if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))		\
48d6c64311ddb (Kumar Gala          2008-06-27 09:39:00 -0500  76) 	  FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_SNAN);		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  77)       }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  78)     break;								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  79)   }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  80) } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  81) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  82) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  83)  * Before packing the bits back into the native fp result, take care
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  84)  * of such mundane things as rounding and overflow.  Also, for some
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  85)  * kinds of fp values, the original parts may not have been fully
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  86)  * extracted -- but that is ok, we can regenerate them now.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  87)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  88) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  89) #define _FP_PACK_CANONICAL(fs, wc, X)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  90) do {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  91)   switch (X##_c)						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  92)   {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  93)   case FP_CLS_NORMAL:						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  94)     X##_e += _FP_EXPBIAS_##fs;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  95)     if (X##_e > 0)						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  96)       {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  97) 	_FP_ROUND(wc, X);					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  98) 	if (_FP_FRAC_OVERP_##wc(fs, X))				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700  99) 	  {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 100) 	    _FP_FRAC_CLEAR_OVERP_##wc(fs, X);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 101) 	    X##_e++;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 102) 	  }							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 103) 	_FP_FRAC_SRL_##wc(X, _FP_WORKBITS);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 104) 	if (X##_e >= _FP_EXPMAX_##fs)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 105) 	  {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 106) 	    /* overflow */					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 107) 	    switch (FP_ROUNDMODE)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 108) 	      {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 109) 	      case FP_RND_NEAREST:				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 110) 		X##_c = FP_CLS_INF;				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 111) 		break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 112) 	      case FP_RND_PINF:					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 113) 		if (!X##_s) X##_c = FP_CLS_INF;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 114) 		break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 115) 	      case FP_RND_MINF:					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 116) 		if (X##_s) X##_c = FP_CLS_INF;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 117) 		break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 118) 	      }							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 119) 	    if (X##_c == FP_CLS_INF)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 120) 	      {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 121) 		/* Overflow to infinity */			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 122) 		X##_e = _FP_EXPMAX_##fs;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 123) 		_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 124) 	      }							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 125) 	    else						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 126) 	      {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 127) 		/* Overflow to maximum normal */		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 128) 		X##_e = _FP_EXPMAX_##fs - 1;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 129) 		_FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc);		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 130) 	      }							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 131) 	    FP_SET_EXCEPTION(FP_EX_OVERFLOW);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 132)             FP_SET_EXCEPTION(FP_EX_INEXACT);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 133) 	  }							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 134)       }								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 135)     else							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 136)       {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 137) 	/* we've got a denormalized number */			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 138) 	X##_e = -X##_e + 1;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 139) 	if (X##_e <= _FP_WFRACBITS_##fs)			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 140) 	  {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 141) 	    _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs);	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 142) 	    if (_FP_FRAC_HIGH_##fs(X)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 143) 		& (_FP_OVERFLOW_##fs >> 1))			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 144) 	      {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 145) 	        X##_e = 1;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 146) 	        _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 147) 	      }							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 148) 	    else						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 149) 	      {							\
930cc144a043f (Kumar Gala          2008-10-21 22:19:00 -0700 150) 		_FP_ROUND(wc, X);				\
930cc144a043f (Kumar Gala          2008-10-21 22:19:00 -0700 151) 		if (_FP_FRAC_HIGH_##fs(X)			\
930cc144a043f (Kumar Gala          2008-10-21 22:19:00 -0700 152) 		   & (_FP_OVERFLOW_##fs >> 1))			\
930cc144a043f (Kumar Gala          2008-10-21 22:19:00 -0700 153) 		  {						\
930cc144a043f (Kumar Gala          2008-10-21 22:19:00 -0700 154) 		    X##_e = 1;					\
930cc144a043f (Kumar Gala          2008-10-21 22:19:00 -0700 155) 		    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);	\
930cc144a043f (Kumar Gala          2008-10-21 22:19:00 -0700 156) 		    FP_SET_EXCEPTION(FP_EX_INEXACT);		\
930cc144a043f (Kumar Gala          2008-10-21 22:19:00 -0700 157) 		  }						\
930cc144a043f (Kumar Gala          2008-10-21 22:19:00 -0700 158) 		else						\
930cc144a043f (Kumar Gala          2008-10-21 22:19:00 -0700 159) 		  {						\
930cc144a043f (Kumar Gala          2008-10-21 22:19:00 -0700 160) 		    X##_e = 0;					\
930cc144a043f (Kumar Gala          2008-10-21 22:19:00 -0700 161) 		    _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);		\
930cc144a043f (Kumar Gala          2008-10-21 22:19:00 -0700 162) 		  }						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 163) 	      }							\
405849610fd96 (David S. Miller     2007-08-16 22:59:49 -0700 164) 	    if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) ||		\
405849610fd96 (David S. Miller     2007-08-16 22:59:49 -0700 165) 		(FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))	\
405849610fd96 (David S. Miller     2007-08-16 22:59:49 -0700 166) 		FP_SET_EXCEPTION(FP_EX_UNDERFLOW);		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 167) 	  }							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 168) 	else							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 169) 	  {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 170) 	    /* underflow to zero */				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 171) 	    X##_e = 0;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 172) 	    if (!_FP_FRAC_ZEROP_##wc(X))			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 173) 	      {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 174) 	        _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 175) 	        _FP_ROUND(wc, X);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 176) 	        _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS);	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 177) 	      }							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 178) 	    FP_SET_EXCEPTION(FP_EX_UNDERFLOW);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 179) 	  }							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 180)       }								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 181)     break;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 182) 								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 183)   case FP_CLS_ZERO:						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 184)     X##_e = 0;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 185)     _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 186)     break;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 187) 								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 188)   case FP_CLS_INF:						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 189)     X##_e = _FP_EXPMAX_##fs;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 190)     _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 191)     break;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 192) 								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 193)   case FP_CLS_NAN:						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 194)     X##_e = _FP_EXPMAX_##fs;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 195)     if (!_FP_KEEPNANFRACP)					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 196)       {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 197) 	_FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 198) 	X##_s = _FP_NANSIGN_##fs;				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 199)       }								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 200)     else							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 201)       _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs;		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 202)     break;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 203)   }								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 204) } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 205) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 206) /* This one accepts raw argument and not cooked,  returns
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 207)  * 1 if X is a signaling NaN.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 208)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 209) #define _FP_ISSIGNAN(fs, wc, X)					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 210) ({								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 211)   int __ret = 0;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 212)   if (X##_e == _FP_EXPMAX_##fs)					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 213)     {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 214)       if (!_FP_FRAC_ZEROP_##wc(X)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 215) 	  && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 216) 	__ret = 1;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 217)     }								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 218)   __ret;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 219) })
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 220) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 221) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 222) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 223) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 224) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 225) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 226)  * Main addition routine.  The input values should be cooked.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 227)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 228) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 229) #define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP)				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 230) do {									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 231)   switch (_FP_CLS_COMBINE(X##_c, Y##_c))				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 232)   {									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 233)   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):			     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 234)     {									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 235)       /* shift the smaller number so that its exponent matches the larger */ \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 236)       _FP_I_TYPE diff = X##_e - Y##_e;					     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 237) 									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 238)       if (diff < 0)							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 239) 	{								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 240) 	  diff = -diff;							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 241) 	  if (diff <= _FP_WFRACBITS_##fs)				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 242) 	    _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs);		     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 243) 	  else if (!_FP_FRAC_ZEROP_##wc(X))				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 244) 	    _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);			     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 245) 	  R##_e = Y##_e;						     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 246) 	}								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 247)       else								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 248) 	{								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 249) 	  if (diff > 0)							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 250) 	    {								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 251) 	      if (diff <= _FP_WFRACBITS_##fs)				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 252) 	        _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs);		     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 253) 	      else if (!_FP_FRAC_ZEROP_##wc(Y))				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 254) 	        _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc);			     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 255) 	    }								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 256) 	  R##_e = X##_e;						     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 257) 	}								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 258) 									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 259)       R##_c = FP_CLS_NORMAL;						     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 260) 									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 261)       if (X##_s == Y##_s)						     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 262) 	{								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 263) 	  R##_s = X##_s;						     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 264) 	  _FP_FRAC_ADD_##wc(R, X, Y);					     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 265) 	  if (_FP_FRAC_OVERP_##wc(fs, R))				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 266) 	    {								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 267) 	      _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);		     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 268) 	      R##_e++;							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 269) 	    }								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 270) 	}								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 271)       else								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 272) 	{								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 273) 	  R##_s = X##_s;						     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 274) 	  _FP_FRAC_SUB_##wc(R, X, Y);					     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 275) 	  if (_FP_FRAC_ZEROP_##wc(R))					     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 276) 	    {								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 277) 	      /* return an exact zero */				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 278) 	      if (FP_ROUNDMODE == FP_RND_MINF)				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 279) 		R##_s |= Y##_s;						     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 280) 	      else							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 281) 		R##_s &= Y##_s;						     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 282) 	      R##_c = FP_CLS_ZERO;					     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 283) 	    }								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 284) 	  else								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 285) 	    {								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 286) 	      if (_FP_FRAC_NEGP_##wc(R))				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 287) 		{							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 288) 		  _FP_FRAC_SUB_##wc(R, Y, X);				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 289) 		  R##_s = Y##_s;					     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 290) 		}							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 291) 									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 292) 	      /* renormalize after subtraction */			     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 293) 	      _FP_FRAC_CLZ_##wc(diff, R);				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 294) 	      diff -= _FP_WFRACXBITS_##fs;				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 295) 	      if (diff)							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 296) 		{							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 297) 		  R##_e -= diff;					     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 298) 		  _FP_FRAC_SLL_##wc(R, diff);				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 299) 		}							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 300) 	    }								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 301) 	}								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 302)       break;								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 303)     }									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 304) 									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 305)   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 306)     _FP_CHOOSENAN(fs, wc, R, X, Y, OP);					     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 307)     break;								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 308) 									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 309)   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):			     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 310)     R##_e = X##_e;							     \
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 311) 	fallthrough;							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 312)   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):			     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 313)   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 314)   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 315)     _FP_FRAC_COPY_##wc(R, X);						     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 316)     R##_s = X##_s;							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 317)     R##_c = X##_c;							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 318)     break;								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 319) 									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 320)   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):			     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 321)     R##_e = Y##_e;							     \
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 322) 	fallthrough;							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 323)   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):			     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 324)   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 325)   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 326)     _FP_FRAC_COPY_##wc(R, Y);						     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 327)     R##_s = Y##_s;							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 328)     R##_c = Y##_c;							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 329)     break;								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 330) 									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 331)   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 332)     if (X##_s != Y##_s)							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 333)       {									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 334) 	/* +INF + -INF => NAN */					     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 335) 	_FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 336) 	R##_s = _FP_NANSIGN_##fs;					     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 337) 	R##_c = FP_CLS_NAN;						     \
48d6c64311ddb (Kumar Gala          2008-06-27 09:39:00 -0500 338) 	FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_ISI);		     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 339) 	break;								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 340)       }									     \
f336a009f8e3d (Gustavo A. R. Silva 2021-07-13 13:09:06 -0500 341)     fallthrough;							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 342) 									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 343)   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):			     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 344)   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 345)     R##_s = X##_s;							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 346)     R##_c = FP_CLS_INF;							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 347)     break;								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 348) 									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 349)   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):			     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 350)   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 351)     R##_s = Y##_s;							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 352)     R##_c = FP_CLS_INF;							     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 353)     break;								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 354) 									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 355)   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):			     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 356)     /* make sure the sign is correct */					     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 357)     if (FP_ROUNDMODE == FP_RND_MINF)					     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 358)       R##_s = X##_s | Y##_s;						     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 359)     else								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 360)       R##_s = X##_s & Y##_s;						     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 361)     R##_c = FP_CLS_ZERO;						     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 362)     break;								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 363) 									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 364)   default:								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 365)     abort();								     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 366)   }									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 367) } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 368) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 369) #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+')
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 370) #define _FP_SUB(fs, wc, R, X, Y)					     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 371)   do {									     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 372)     if (Y##_c != FP_CLS_NAN) Y##_s ^= 1;				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 373)     _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-');				     \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 374)   } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 375) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 376) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 377) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 378)  * Main negation routine.  FIXME -- when we care about setting exception
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 379)  * bits reliably, this will not do.  We should examine all of the fp classes.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 380)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 381) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 382) #define _FP_NEG(fs, wc, R, X)		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 383)   do {					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 384)     _FP_FRAC_COPY_##wc(R, X);		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 385)     R##_c = X##_c;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 386)     R##_e = X##_e;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 387)     R##_s = 1 ^ X##_s;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 388)   } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 389) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 390) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 391) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 392)  * Main multiplication routine.  The input values should be cooked.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 393)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 394) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 395) #define _FP_MUL(fs, wc, R, X, Y)			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 396) do {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 397)   R##_s = X##_s ^ Y##_s;				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 398)   switch (_FP_CLS_COMBINE(X##_c, Y##_c))		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 399)   {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 400)   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 401)     R##_c = FP_CLS_NORMAL;				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 402)     R##_e = X##_e + Y##_e + 1;				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 403) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 404)     _FP_MUL_MEAT_##fs(R,X,Y);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 405) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 406)     if (_FP_FRAC_OVERP_##wc(fs, R))			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 407)       _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 408)     else						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 409)       R##_e--;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 410)     break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 411) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 412)   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 413)     _FP_CHOOSENAN(fs, wc, R, X, Y, '*');		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 414)     break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 415) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 416)   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 417)   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 418)   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 419)     R##_s = X##_s;					\
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 420) 	  fallthrough;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 421) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 422)   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 423)   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 424)   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 425)   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 426)     _FP_FRAC_COPY_##wc(R, X);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 427)     R##_c = X##_c;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 428)     break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 429) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 430)   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 431)   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 432)   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 433)     R##_s = Y##_s;					\
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 434) 	  fallthrough;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 435) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 436)   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 437)   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 438)     _FP_FRAC_COPY_##wc(R, Y);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 439)     R##_c = Y##_c;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 440)     break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 441) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 442)   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 443)   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 444)     R##_s = _FP_NANSIGN_##fs;				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 445)     R##_c = FP_CLS_NAN;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 446)     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
48d6c64311ddb (Kumar Gala          2008-06-27 09:39:00 -0500 447)     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_IMZ);\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 448)     break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 449) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 450)   default:						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 451)     abort();						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 452)   }							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 453) } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 454) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 455) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 456) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 457)  * Main division routine.  The input values should be cooked.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 458)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 459) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 460) #define _FP_DIV(fs, wc, R, X, Y)			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 461) do {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 462)   R##_s = X##_s ^ Y##_s;				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 463)   switch (_FP_CLS_COMBINE(X##_c, Y##_c))		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 464)   {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 465)   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 466)     R##_c = FP_CLS_NORMAL;				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 467)     R##_e = X##_e - Y##_e;				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 468) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 469)     _FP_DIV_MEAT_##fs(R,X,Y);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 470)     break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 471) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 472)   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 473)     _FP_CHOOSENAN(fs, wc, R, X, Y, '/');		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 474)     break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 475) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 476)   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 477)   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 478)   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 479)     R##_s = X##_s;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 480)     _FP_FRAC_COPY_##wc(R, X);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 481)     R##_c = X##_c;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 482)     break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 483) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 484)   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 485)   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 486)   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 487)     R##_s = Y##_s;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 488)     _FP_FRAC_COPY_##wc(R, Y);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 489)     R##_c = Y##_c;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 490)     break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 491) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 492)   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 493)   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 494)   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 495)     R##_c = FP_CLS_ZERO;				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 496)     break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 497) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 498)   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 499)     FP_SET_EXCEPTION(FP_EX_DIVZERO);			\
df561f6688fef (Gustavo A. R. Silva 2020-08-23 17:36:59 -0500 500) 	fallthrough;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 501)   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 502)   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 503)     R##_c = FP_CLS_INF;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 504)     break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 505) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 506)   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):		\
48d6c64311ddb (Kumar Gala          2008-06-27 09:39:00 -0500 507)     R##_s = _FP_NANSIGN_##fs;				\
48d6c64311ddb (Kumar Gala          2008-06-27 09:39:00 -0500 508)     R##_c = FP_CLS_NAN;					\
48d6c64311ddb (Kumar Gala          2008-06-27 09:39:00 -0500 509)     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
48d6c64311ddb (Kumar Gala          2008-06-27 09:39:00 -0500 510)     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_IDI);\
60b8267338aaf (David S. Miller     2008-10-22 22:09:59 -0700 511)     break;						\
60b8267338aaf (David S. Miller     2008-10-22 22:09:59 -0700 512) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 513)   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 514)     R##_s = _FP_NANSIGN_##fs;				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 515)     R##_c = FP_CLS_NAN;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 516)     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
48d6c64311ddb (Kumar Gala          2008-06-27 09:39:00 -0500 517)     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_ZDZ);\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 518)     break;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 519) 							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 520)   default:						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 521)     abort();						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 522)   }							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 523) } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 524) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 525) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 526) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 527)  * Main differential comparison routine.  The inputs should be raw not
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 528)  * cooked.  The return is -1,0,1 for normal values, 2 otherwise.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 529)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 530) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 531) #define _FP_CMP(fs, wc, ret, X, Y, un)					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 532)   do {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 533)     /* NANs are unordered */						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 534)     if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 535) 	|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 536)       {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 537) 	ret = un;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 538)       }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 539)     else								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 540)       {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 541) 	int __is_zero_x;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 542) 	int __is_zero_y;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 543) 									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 544) 	__is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0;	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 545) 	__is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0;	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 546) 									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 547) 	if (__is_zero_x && __is_zero_y)					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 548) 		ret = 0;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 549) 	else if (__is_zero_x)						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 550) 		ret = Y##_s ? 1 : -1;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 551) 	else if (__is_zero_y)						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 552) 		ret = X##_s ? -1 : 1;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 553) 	else if (X##_s != Y##_s)					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 554) 	  ret = X##_s ? -1 : 1;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 555) 	else if (X##_e > Y##_e)						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 556) 	  ret = X##_s ? -1 : 1;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 557) 	else if (X##_e < Y##_e)						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 558) 	  ret = X##_s ? 1 : -1;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 559) 	else if (_FP_FRAC_GT_##wc(X, Y))				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 560) 	  ret = X##_s ? -1 : 1;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 561) 	else if (_FP_FRAC_GT_##wc(Y, X))				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 562) 	  ret = X##_s ? 1 : -1;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 563) 	else								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 564) 	  ret = 0;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 565)       }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 566)   } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 567) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 568) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 569) /* Simplification for strict equality.  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 570) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 571) #define _FP_CMP_EQ(fs, wc, ret, X, Y)					  \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 572)   do {									  \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 573)     /* NANs are unordered */						  \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 574)     if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))		  \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 575) 	|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))	  \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 576)       {									  \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 577) 	ret = 1;							  \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 578)       }									  \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 579)     else								  \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 580)       {									  \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 581) 	ret = !(X##_e == Y##_e						  \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 582) 		&& _FP_FRAC_EQ_##wc(X, Y)				  \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 583) 		&& (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 584)       }									  \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 585)   } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 586) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 587) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 588)  * Main square root routine.  The input value should be cooked.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 589)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 590) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 591) #define _FP_SQRT(fs, wc, R, X)						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 592) do {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 593)     _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 594)     _FP_W_TYPE q;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 595)     switch (X##_c)							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 596)     {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 597)     case FP_CLS_NAN:							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 598) 	_FP_FRAC_COPY_##wc(R, X);					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 599) 	R##_s = X##_s;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 600)     	R##_c = FP_CLS_NAN;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 601)     	break;								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 602)     case FP_CLS_INF:							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 603)     	if (X##_s)							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 604)     	  {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 605)     	    R##_s = _FP_NANSIGN_##fs;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 606) 	    R##_c = FP_CLS_NAN; /* NAN */				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 607) 	    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 608) 	    FP_SET_EXCEPTION(FP_EX_INVALID);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 609)     	  }								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 610)     	else								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 611)     	  {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 612)     	    R##_s = 0;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 613)     	    R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 614)     	  }								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 615)     	break;								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 616)     case FP_CLS_ZERO:							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 617) 	R##_s = X##_s;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 618) 	R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 619) 	break;								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 620)     case FP_CLS_NORMAL:							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 621)     	R##_s = 0;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 622)         if (X##_s)							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 623)           {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 624) 	    R##_c = FP_CLS_NAN; /* sNAN */				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 625) 	    R##_s = _FP_NANSIGN_##fs;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 626) 	    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 627) 	    FP_SET_EXCEPTION(FP_EX_INVALID);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 628) 	    break;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 629)           }								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 630)     	R##_c = FP_CLS_NORMAL;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 631)         if (X##_e & 1)							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 632)           _FP_FRAC_SLL_##wc(X, 1);					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 633)         R##_e = X##_e >> 1;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 634)         _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 635)         _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 636)         q = _FP_OVERFLOW_##fs >> 1;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 637)         _FP_SQRT_MEAT_##wc(R, S, T, X, q);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 638)     }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 639)   } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 640) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 641) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 642)  * Convert from FP to integer
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 643)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 644) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 645) /* RSIGNED can have following values:
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 646)  * 0:  the number is required to be 0..(2^rsize)-1, if not, NV is set plus
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 647)  *     the result is either 0 or (2^rsize)-1 depending on the sign in such case.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 648)  * 1:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 649)  *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 650)  *     on the sign in such case.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 651)  * 2:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 652)  *     set plus the result is truncated to fit into destination.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 653)  * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 654)  *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 655)  *     on the sign in such case.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 656)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 657) #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 658)   do {										\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 659)     switch (X##_c)								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 660)       {										\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 661)       case FP_CLS_NORMAL:							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 662) 	if (X##_e < 0)								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 663) 	  {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 664) 	    FP_SET_EXCEPTION(FP_EX_INEXACT);					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 665) 	  case FP_CLS_ZERO:							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 666) 	    r = 0;								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 667) 	  }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 668) 	else if (X##_e >= rsize - (rsigned > 0 || X##_s)			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 669) 		 || (!rsigned && X##_s))					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 670) 	  {	/* overflow */							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 671) 	  case FP_CLS_NAN:                                                      \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 672) 	  case FP_CLS_INF:							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 673) 	    if (rsigned == 2)							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 674) 	      {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 675) 		if (X##_c != FP_CLS_NORMAL					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 676) 		    || X##_e >= rsize - 1 + _FP_WFRACBITS_##fs)			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 677) 		  r = 0;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 678) 		else								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 679) 		  {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 680) 		    _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 681) 		    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 682) 		  }								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 683) 	      }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 684) 	    else if (rsigned)							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 685) 	      {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 686) 		r = 1;								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 687) 		r <<= rsize - 1;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 688) 		r -= 1 - X##_s;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 689) 	      }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 690) 	    else								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 691) 	      {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 692) 		r = 0;								\
4f6db5efff825 (Joseph Myers        2013-11-04 16:53:50 +0000 693) 		if (!X##_s)							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 694) 		  r = ~r;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 695) 	      }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 696) 	    FP_SET_EXCEPTION(FP_EX_INVALID);					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 697) 	  }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 698) 	else									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 699) 	  {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 700) 	    if (_FP_W_TYPE_SIZE*wc < rsize)					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 701) 	      {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 702) 		_FP_FRAC_ASSEMBLE_##wc(r, X, rsize);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 703) 		r <<= X##_e - _FP_WFRACBITS_##fs;				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 704) 	      }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 705) 	    else								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 706) 	      {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 707) 		if (X##_e >= _FP_WFRACBITS_##fs)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 708) 		  _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 709) 		else if (X##_e < _FP_WFRACBITS_##fs - 1)			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 710) 		  {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 711) 		    _FP_FRAC_SRS_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 2),	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 712) 				      _FP_WFRACBITS_##fs);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 713) 		    if (_FP_FRAC_LOW_##wc(X) & 1)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 714) 		      FP_SET_EXCEPTION(FP_EX_INEXACT);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 715) 		    _FP_FRAC_SRL_##wc(X, 1);					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 716) 		  }								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 717) 		_FP_FRAC_ASSEMBLE_##wc(r, X, rsize);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 718) 	      }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 719) 	    if (rsigned && X##_s)						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 720) 	      r = -r;								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 721) 	  }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 722) 	break;									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 723)       }										\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 724)   } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 725) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 726) #define _FP_TO_INT_ROUND(fs, wc, r, X, rsize, rsigned)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 727)   do {										\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 728)     r = 0;									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 729)     switch (X##_c)								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 730)       {										\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 731)       case FP_CLS_NORMAL:							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 732) 	if (X##_e >= _FP_FRACBITS_##fs - 1)					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 733) 	  {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 734) 	    if (X##_e < rsize - 1 + _FP_WFRACBITS_##fs)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 735) 	      {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 736) 		if (X##_e >= _FP_WFRACBITS_##fs - 1)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 737) 		  {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 738) 		    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 739) 		    r <<= X##_e - _FP_WFRACBITS_##fs + 1;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 740) 		  }								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 741) 		else								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 742) 		  {								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 743) 		    _FP_FRAC_SRL_##wc(X, _FP_WORKBITS - X##_e			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 744) 				      + _FP_FRACBITS_##fs - 1);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 745) 		    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 746) 		  }								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 747) 	      }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 748) 	  }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 749) 	else									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 750) 	  {									\
d06b3326dfd02 (Joseph Myers        2013-11-04 16:54:15 +0000 751) 	    int _lz0, _lz1;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 752) 	    if (X##_e <= -_FP_WORKBITS - 1)					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 753) 	      _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 754) 	    else								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 755) 	      _FP_FRAC_SRS_##wc(X, _FP_FRACBITS_##fs - 1 - X##_e,		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 756) 				_FP_WFRACBITS_##fs);				\
d06b3326dfd02 (Joseph Myers        2013-11-04 16:54:15 +0000 757) 	    _FP_FRAC_CLZ_##wc(_lz0, X);						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 758) 	    _FP_ROUND(wc, X);							\
d06b3326dfd02 (Joseph Myers        2013-11-04 16:54:15 +0000 759) 	    _FP_FRAC_CLZ_##wc(_lz1, X);						\
d06b3326dfd02 (Joseph Myers        2013-11-04 16:54:15 +0000 760) 	    if (_lz1 < _lz0)							\
d06b3326dfd02 (Joseph Myers        2013-11-04 16:54:15 +0000 761) 	      X##_e++; /* For overflow detection.  */				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 762) 	    _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 763) 	    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 764) 	  }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 765) 	if (rsigned && X##_s)							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 766) 	  r = -r;								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 767) 	if (X##_e >= rsize - (rsigned > 0 || X##_s)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 768) 	    || (!rsigned && X##_s))						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 769) 	  {	/* overflow */							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 770) 	  case FP_CLS_NAN:                                                      \
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 771) 	  case FP_CLS_INF:							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 772) 	    if (!rsigned)							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 773) 	      {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 774) 		r = 0;								\
4f6db5efff825 (Joseph Myers        2013-11-04 16:53:50 +0000 775) 		if (!X##_s)							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 776) 		  r = ~r;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 777) 	      }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 778) 	    else if (rsigned != 2)						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 779) 	      {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 780) 		r = 1;								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 781) 		r <<= rsize - 1;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 782) 		r -= 1 - X##_s;							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 783) 	      }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 784) 	    FP_SET_EXCEPTION(FP_EX_INVALID);					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 785) 	  }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 786) 	break;									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 787)       case FP_CLS_ZERO:								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 788)         break;									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 789)       }										\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 790)   } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 791) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 792) #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 793)   do {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 794)     if (r)								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 795)       {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 796)         unsigned rtype ur_;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 797) 	X##_c = FP_CLS_NORMAL;						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 798) 									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 799) 	if ((X##_s = (r < 0)))						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 800) 	  ur_ = (unsigned rtype) -r;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 801) 	else								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 802) 	  ur_ = (unsigned rtype) r;					\
8183db10db637 (Vincent Chen        2019-05-27 14:17:21 +0800 803) 	(void) (((rsize) <= _FP_W_TYPE_SIZE)				\
8183db10db637 (Vincent Chen        2019-05-27 14:17:21 +0800 804) 		? ({ __FP_CLZ(X##_e, ur_); })				\
8183db10db637 (Vincent Chen        2019-05-27 14:17:21 +0800 805) 		: ({							\
8183db10db637 (Vincent Chen        2019-05-27 14:17:21 +0800 806) 		     __FP_CLZ_2(X##_e, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE),  \
8183db10db637 (Vincent Chen        2019-05-27 14:17:21 +0800 807) 							    (_FP_W_TYPE)ur_); \
8183db10db637 (Vincent Chen        2019-05-27 14:17:21 +0800 808) 		  }));							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 809) 	if (rsize < _FP_W_TYPE_SIZE)					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 810) 		X##_e -= (_FP_W_TYPE_SIZE - rsize);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 811) 	X##_e = rsize - X##_e - 1;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 812) 									\
f8324e20f8289 (Mikael Pettersson   2010-07-20 18:45:14 -0700 813) 	if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs <= X##_e)	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 814) 	  __FP_FRAC_SRS_1(ur_, (X##_e - _FP_WFRACBITS_##fs + 1), rsize);\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 815) 	_FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 816) 	if ((_FP_WFRACBITS_##fs - X##_e - 1) > 0)			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 817) 	  _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 818)       }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 819)     else								\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 820)       {									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 821) 	X##_c = FP_CLS_ZERO, X##_s = 0;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 822)       }									\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 823)   } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 824) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 825) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 826) #define FP_CONV(dfs,sfs,dwc,swc,D,S)			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 827)   do {							\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 828)     _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S);	\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 829)     D##_e = S##_e;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 830)     D##_c = S##_c;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 831)     D##_s = S##_s;					\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 832)   } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 833) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 834) /*
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 835)  * Helper primitives.
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 836)  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 837) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 838) /* Count leading zeros in a word.  */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 839) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 840) #ifndef __FP_CLZ
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 841) #if _FP_W_TYPE_SIZE < 64
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 842) /* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 843) #define __FP_CLZ(r, x)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 844)   do {						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 845)     _FP_W_TYPE _t = (x);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 846)     r = _FP_W_TYPE_SIZE - 1;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 847)     if (_t > 0xffff) r -= 16;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 848)     if (_t > 0xffff) _t >>= 16;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 849)     if (_t > 0xff) r -= 8;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 850)     if (_t > 0xff) _t >>= 8;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 851)     if (_t & 0xf0) r -= 4;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 852)     if (_t & 0xf0) _t >>= 4;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 853)     if (_t & 0xc) r -= 2;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 854)     if (_t & 0xc) _t >>= 2;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 855)     if (_t & 0x2) r -= 1;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 856)   } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 857) #else /* not _FP_W_TYPE_SIZE < 64 */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 858) #define __FP_CLZ(r, x)				\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 859)   do {						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 860)     _FP_W_TYPE _t = (x);			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 861)     r = _FP_W_TYPE_SIZE - 1;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 862)     if (_t > 0xffffffff) r -= 32;		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 863)     if (_t > 0xffffffff) _t >>= 32;		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 864)     if (_t > 0xffff) r -= 16;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 865)     if (_t > 0xffff) _t >>= 16;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 866)     if (_t > 0xff) r -= 8;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 867)     if (_t > 0xff) _t >>= 8;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 868)     if (_t & 0xf0) r -= 4;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 869)     if (_t & 0xf0) _t >>= 4;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 870)     if (_t & 0xc) r -= 2;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 871)     if (_t & 0xc) _t >>= 2;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 872)     if (_t & 0x2) r -= 1;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 873)   } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 874) #endif /* not _FP_W_TYPE_SIZE < 64 */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 875) #endif /* ndef __FP_CLZ */
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 876) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 877) #define _FP_DIV_HELP_imm(q, r, n, d)		\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 878)   do {						\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 879)     q = n / d, r = n % d;			\
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 880)   } while (0)
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 881) 
^1da177e4c3f4 (Linus Torvalds      2005-04-16 15:20:36 -0700 882) #endif /* __MATH_EMU_OP_COMMON_H__ */