1169689Skan/* Software floating-point emulation. Common operations.
2169689Skan   Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc.
3169689Skan   This file is part of the GNU C Library.
4169689Skan   Contributed by Richard Henderson (rth@cygnus.com),
5169689Skan		  Jakub Jelinek (jj@ultra.linux.cz),
6169689Skan		  David S. Miller (davem@redhat.com) and
7169689Skan		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
8169689Skan
9169689Skan   The GNU C Library is free software; you can redistribute it and/or
10169689Skan   modify it under the terms of the GNU Lesser General Public
11169689Skan   License as published by the Free Software Foundation; either
12169689Skan   version 2.1 of the License, or (at your option) any later version.
13169689Skan
14169689Skan   In addition to the permissions in the GNU Lesser General Public
15169689Skan   License, the Free Software Foundation gives you unlimited
16169689Skan   permission to link the compiled version of this file into
17169689Skan   combinations with other programs, and to distribute those
18169689Skan   combinations without any restriction coming from the use of this
19169689Skan   file.  (The Lesser General Public License restrictions do apply in
20169689Skan   other respects; for example, they cover modification of the file,
21169689Skan   and distribution when not linked into a combine executable.)
22169689Skan
23169689Skan   The GNU C Library is distributed in the hope that it will be useful,
24169689Skan   but WITHOUT ANY WARRANTY; without even the implied warranty of
25169689Skan   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26169689Skan   Lesser General Public License for more details.
27169689Skan
28169689Skan   You should have received a copy of the GNU Lesser General Public
29169689Skan   License along with the GNU C Library; if not, write to the Free
30169689Skan   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
31169689Skan   MA 02110-1301, USA.  */
32169689Skan
33169689Skan#define _FP_DECL(wc, X)						\
34169689Skan  _FP_I_TYPE X##_c __attribute__((unused)), X##_s, X##_e;	\
35169689Skan  _FP_FRAC_DECL_##wc(X)
36169689Skan
37169689Skan/*
38169689Skan * Finish truely unpacking a native fp value by classifying the kind
39169689Skan * of fp value and normalizing both the exponent and the fraction.
40169689Skan */
41169689Skan
42169689Skan#define _FP_UNPACK_CANONICAL(fs, wc, X)					\
43169689Skando {									\
44169689Skan  switch (X##_e)							\
45169689Skan  {									\
46169689Skan  default:								\
47169689Skan    _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs;			\
48169689Skan    _FP_FRAC_SLL_##wc(X, _FP_WORKBITS);					\
49169689Skan    X##_e -= _FP_EXPBIAS_##fs;						\
50169689Skan    X##_c = FP_CLS_NORMAL;						\
51169689Skan    break;								\
52169689Skan									\
53169689Skan  case 0:								\
54169689Skan    if (_FP_FRAC_ZEROP_##wc(X))						\
55169689Skan      X##_c = FP_CLS_ZERO;						\
56169689Skan    else								\
57169689Skan      {									\
58169689Skan	/* a denormalized number */					\
59169689Skan	_FP_I_TYPE _shift;						\
60169689Skan	_FP_FRAC_CLZ_##wc(_shift, X);					\
61169689Skan	_shift -= _FP_FRACXBITS_##fs;					\
62169689Skan	_FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS));			\
63169689Skan	X##_e -= _FP_EXPBIAS_##fs - 1 + _shift;				\
64169689Skan	X##_c = FP_CLS_NORMAL;						\
65169689Skan	FP_SET_EXCEPTION(FP_EX_DENORM);					\
66169689Skan      }									\
67169689Skan    break;								\
68169689Skan									\
69169689Skan  case _FP_EXPMAX_##fs:							\
70169689Skan    if (_FP_FRAC_ZEROP_##wc(X))						\
71169689Skan      X##_c = FP_CLS_INF;						\
72169689Skan    else								\
73169689Skan      {									\
74169689Skan	X##_c = FP_CLS_NAN;						\
75169689Skan	/* Check for signaling NaN */					\
76169689Skan	if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))		\
77169689Skan	  FP_SET_EXCEPTION(FP_EX_INVALID);				\
78169689Skan      }									\
79169689Skan    break;								\
80169689Skan  }									\
81169689Skan} while (0)
82169689Skan
83169689Skan/* Finish unpacking an fp value in semi-raw mode: the mantissa is
84169689Skan   shifted by _FP_WORKBITS but the implicit MSB is not inserted and
85169689Skan   other classification is not done.  */
86169689Skan#define _FP_UNPACK_SEMIRAW(fs, wc, X)	_FP_FRAC_SLL_##wc(X, _FP_WORKBITS)
87169689Skan
88169689Skan/* A semi-raw value has overflowed to infinity.  Adjust the mantissa
89169689Skan   and exponent appropriately.  */
90169689Skan#define _FP_OVERFLOW_SEMIRAW(fs, wc, X)			\
91169689Skando {							\
92169689Skan  if (FP_ROUNDMODE == FP_RND_NEAREST			\
93169689Skan      || (FP_ROUNDMODE == FP_RND_PINF && !X##_s)	\
94169689Skan      || (FP_ROUNDMODE == FP_RND_MINF && X##_s))	\
95169689Skan    {							\
96169689Skan      X##_e = _FP_EXPMAX_##fs;				\
97169689Skan      _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);		\
98169689Skan    }							\
99169689Skan  else							\
100169689Skan    {							\
101169689Skan      X##_e = _FP_EXPMAX_##fs - 1;			\
102169689Skan      _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc);		\
103169689Skan    }							\
104169689Skan    FP_SET_EXCEPTION(FP_EX_INEXACT);			\
105169689Skan    FP_SET_EXCEPTION(FP_EX_OVERFLOW);			\
106169689Skan} while (0)
107169689Skan
108169689Skan/* Check for a semi-raw value being a signaling NaN and raise the
109169689Skan   invalid exception if so.  */
110169689Skan#define _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X)			\
111169689Skando {								\
112169689Skan  if (X##_e == _FP_EXPMAX_##fs					\
113169689Skan      && !_FP_FRAC_ZEROP_##wc(X)				\
114169689Skan      && !(_FP_FRAC_HIGH_##fs(X) & _FP_QNANBIT_SH_##fs))	\
115169689Skan    FP_SET_EXCEPTION(FP_EX_INVALID);				\
116169689Skan} while (0)
117169689Skan
118169689Skan/* Choose a NaN result from an operation on two semi-raw NaN
119169689Skan   values.  */
120169689Skan#define _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP)			\
121169689Skando {									\
122169689Skan  /* _FP_CHOOSENAN expects raw values, so shift as required.  */	\
123169689Skan  _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);					\
124169689Skan  _FP_FRAC_SRL_##wc(Y, _FP_WORKBITS);					\
125169689Skan  _FP_CHOOSENAN(fs, wc, R, X, Y, OP);					\
126169689Skan  _FP_FRAC_SLL_##wc(R, _FP_WORKBITS);					\
127169689Skan} while (0)
128169689Skan
129169689Skan/* Test whether a biased exponent is normal (not zero or maximum).  */
130169689Skan#define _FP_EXP_NORMAL(fs, wc, X)	(((X##_e + 1) & _FP_EXPMAX_##fs) > 1)
131169689Skan
132169689Skan/* Prepare to pack an fp value in semi-raw mode: the mantissa is
133169689Skan   rounded and shifted right, with the rounding possibly increasing
134169689Skan   the exponent (including changing a finite value to infinity).  */
135169689Skan#define _FP_PACK_SEMIRAW(fs, wc, X)				\
136169689Skando {								\
137169689Skan  _FP_ROUND(wc, X);						\
138169689Skan  if (_FP_FRAC_HIGH_##fs(X)					\
139169689Skan      & (_FP_OVERFLOW_##fs >> 1))				\
140169689Skan    {								\
141169689Skan      _FP_FRAC_HIGH_##fs(X) &= ~(_FP_OVERFLOW_##fs >> 1);	\
142169689Skan      X##_e++;							\
143169689Skan      if (X##_e == _FP_EXPMAX_##fs)				\
144169689Skan	_FP_OVERFLOW_SEMIRAW(fs, wc, X);			\
145169689Skan    }								\
146169689Skan  _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);				\
147169689Skan  if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X))	\
148169689Skan    {								\
149169689Skan      if (X##_e == 0)						\
150169689Skan	FP_SET_EXCEPTION(FP_EX_UNDERFLOW);			\
151169689Skan      else							\
152169689Skan	{							\
153169689Skan	  if (!_FP_KEEPNANFRACP)				\
154169689Skan	    {							\
155169689Skan	      _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);		\
156169689Skan	      X##_s = _FP_NANSIGN_##fs;				\
157169689Skan	    }							\
158169689Skan	  else							\
159169689Skan	    _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs;	\
160169689Skan	}							\
161169689Skan    }								\
162169689Skan} while (0)
163169689Skan
164169689Skan/*
165169689Skan * Before packing the bits back into the native fp result, take care
166169689Skan * of such mundane things as rounding and overflow.  Also, for some
167169689Skan * kinds of fp values, the original parts may not have been fully
168169689Skan * extracted -- but that is ok, we can regenerate them now.
169169689Skan */
170169689Skan
171169689Skan#define _FP_PACK_CANONICAL(fs, wc, X)				\
172169689Skando {								\
173169689Skan  switch (X##_c)						\
174169689Skan  {								\
175169689Skan  case FP_CLS_NORMAL:						\
176169689Skan    X##_e += _FP_EXPBIAS_##fs;					\
177169689Skan    if (X##_e > 0)						\
178169689Skan      {								\
179169689Skan	_FP_ROUND(wc, X);					\
180169689Skan	if (_FP_FRAC_OVERP_##wc(fs, X))				\
181169689Skan	  {							\
182169689Skan	    _FP_FRAC_CLEAR_OVERP_##wc(fs, X);			\
183169689Skan	    X##_e++;						\
184169689Skan	  }							\
185169689Skan	_FP_FRAC_SRL_##wc(X, _FP_WORKBITS);			\
186169689Skan	if (X##_e >= _FP_EXPMAX_##fs)				\
187169689Skan	  {							\
188169689Skan	    /* overflow */					\
189169689Skan	    switch (FP_ROUNDMODE)				\
190169689Skan	      {							\
191169689Skan	      case FP_RND_NEAREST:				\
192169689Skan		X##_c = FP_CLS_INF;				\
193169689Skan		break;						\
194169689Skan	      case FP_RND_PINF:					\
195169689Skan		if (!X##_s) X##_c = FP_CLS_INF;			\
196169689Skan		break;						\
197169689Skan	      case FP_RND_MINF:					\
198169689Skan		if (X##_s) X##_c = FP_CLS_INF;			\
199169689Skan		break;						\
200169689Skan	      }							\
201169689Skan	    if (X##_c == FP_CLS_INF)				\
202169689Skan	      {							\
203169689Skan		/* Overflow to infinity */			\
204169689Skan		X##_e = _FP_EXPMAX_##fs;			\
205169689Skan		_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);	\
206169689Skan	      }							\
207169689Skan	    else						\
208169689Skan	      {							\
209169689Skan		/* Overflow to maximum normal */		\
210169689Skan		X##_e = _FP_EXPMAX_##fs - 1;			\
211169689Skan		_FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc);		\
212169689Skan	      }							\
213169689Skan	    FP_SET_EXCEPTION(FP_EX_OVERFLOW);			\
214169689Skan            FP_SET_EXCEPTION(FP_EX_INEXACT);			\
215169689Skan	  }							\
216169689Skan      }								\
217169689Skan    else							\
218169689Skan      {								\
219169689Skan	/* we've got a denormalized number */			\
220169689Skan	X##_e = -X##_e + 1;					\
221169689Skan	if (X##_e <= _FP_WFRACBITS_##fs)			\
222169689Skan	  {							\
223169689Skan	    _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs);	\
224169689Skan	    _FP_ROUND(wc, X);					\
225169689Skan	    if (_FP_FRAC_HIGH_##fs(X)				\
226169689Skan		& (_FP_OVERFLOW_##fs >> 1))			\
227169689Skan	      {							\
228169689Skan	        X##_e = 1;					\
229169689Skan	        _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);	\
230169689Skan	      }							\
231169689Skan	    else						\
232169689Skan	      {							\
233169689Skan		X##_e = 0;					\
234169689Skan		_FP_FRAC_SRL_##wc(X, _FP_WORKBITS);		\
235169689Skan		FP_SET_EXCEPTION(FP_EX_UNDERFLOW);		\
236169689Skan	      }							\
237169689Skan	  }							\
238169689Skan	else							\
239169689Skan	  {							\
240169689Skan	    /* underflow to zero */				\
241169689Skan	    X##_e = 0;						\
242169689Skan	    if (!_FP_FRAC_ZEROP_##wc(X))			\
243169689Skan	      {							\
244169689Skan	        _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);		\
245169689Skan	        _FP_ROUND(wc, X);				\
246169689Skan	        _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS);	\
247169689Skan	      }							\
248169689Skan	    FP_SET_EXCEPTION(FP_EX_UNDERFLOW);			\
249169689Skan	  }							\
250169689Skan      }								\
251169689Skan    break;							\
252169689Skan								\
253169689Skan  case FP_CLS_ZERO:						\
254169689Skan    X##_e = 0;							\
255169689Skan    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			\
256169689Skan    break;							\
257169689Skan								\
258169689Skan  case FP_CLS_INF:						\
259169689Skan    X##_e = _FP_EXPMAX_##fs;					\
260169689Skan    _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			\
261169689Skan    break;							\
262169689Skan								\
263169689Skan  case FP_CLS_NAN:						\
264169689Skan    X##_e = _FP_EXPMAX_##fs;					\
265169689Skan    if (!_FP_KEEPNANFRACP)					\
266169689Skan      {								\
267169689Skan	_FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);			\
268169689Skan	X##_s = _FP_NANSIGN_##fs;				\
269169689Skan      }								\
270169689Skan    else							\
271169689Skan      _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs;		\
272169689Skan    break;							\
273169689Skan  }								\
274169689Skan} while (0)
275169689Skan
276169689Skan/* This one accepts raw argument and not cooked,  returns
277169689Skan * 1 if X is a signaling NaN.
278169689Skan */
279169689Skan#define _FP_ISSIGNAN(fs, wc, X)					\
280169689Skan({								\
281169689Skan  int __ret = 0;						\
282169689Skan  if (X##_e == _FP_EXPMAX_##fs)					\
283169689Skan    {								\
284169689Skan      if (!_FP_FRAC_ZEROP_##wc(X)				\
285169689Skan	  && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))	\
286169689Skan	__ret = 1;						\
287169689Skan    }								\
288169689Skan  __ret;							\
289169689Skan})
290169689Skan
291169689Skan
292169689Skan
293169689Skan
294169689Skan
295169689Skan/* Addition on semi-raw values.  */
296169689Skan#define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP)				 \
297169689Skando {									 \
298169689Skan  if (X##_s == Y##_s)							 \
299169689Skan    {									 \
300169689Skan      /* Addition.  */							 \
301169689Skan      R##_s = X##_s;							 \
302169689Skan      int ediff = X##_e - Y##_e;					 \
303169689Skan      if (ediff > 0)							 \
304169689Skan	{								 \
305169689Skan	  R##_e = X##_e;						 \
306169689Skan	  if (Y##_e == 0)						 \
307169689Skan	    {								 \
308169689Skan	      /* Y is zero or denormalized.  */				 \
309169689Skan	      if (_FP_FRAC_ZEROP_##wc(Y))				 \
310169689Skan		{							 \
311169689Skan		  _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);			 \
312169689Skan		  _FP_FRAC_COPY_##wc(R, X);				 \
313169689Skan		  goto add_done;					 \
314169689Skan		}							 \
315169689Skan	      else							 \
316169689Skan		{							 \
317169689Skan		  FP_SET_EXCEPTION(FP_EX_DENORM);			 \
318169689Skan		  ediff--;						 \
319169689Skan		  if (ediff == 0)					 \
320169689Skan		    {							 \
321169689Skan		      _FP_FRAC_ADD_##wc(R, X, Y);			 \
322169689Skan		      goto add3;					 \
323169689Skan		    }							 \
324169689Skan		  if (X##_e == _FP_EXPMAX_##fs)				 \
325169689Skan		    {							 \
326169689Skan		      _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);		 \
327169689Skan		      _FP_FRAC_COPY_##wc(R, X);				 \
328169689Skan		      goto add_done;					 \
329169689Skan		    }							 \
330169689Skan		  goto add1;						 \
331169689Skan		}							 \
332169689Skan	    }								 \
333169689Skan	  else if (X##_e == _FP_EXPMAX_##fs)				 \
334169689Skan	    {								 \
335169689Skan	      /* X is NaN or Inf, Y is normal.  */			 \
336169689Skan	      _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);			 \
337169689Skan	      _FP_FRAC_COPY_##wc(R, X);					 \
338169689Skan	      goto add_done;						 \
339169689Skan	    }								 \
340169689Skan									 \
341169689Skan	  /* Insert implicit MSB of Y.  */				 \
342169689Skan	  _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs;			 \
343169689Skan									 \
344169689Skan	add1:								 \
345169689Skan	  /* Shift the mantissa of Y to the right EDIFF steps;		 \
346169689Skan	     remember to account later for the implicit MSB of X.  */	 \
347169689Skan	  if (ediff <= _FP_WFRACBITS_##fs)				 \
348169689Skan	    _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs);		 \
349169689Skan	  else if (!_FP_FRAC_ZEROP_##wc(Y))				 \
350169689Skan	    _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc);			 \
351169689Skan	  _FP_FRAC_ADD_##wc(R, X, Y);					 \
352169689Skan	}								 \
353169689Skan      else if (ediff < 0)						 \
354169689Skan	{								 \
355169689Skan	  ediff = -ediff;						 \
356169689Skan	  R##_e = Y##_e;						 \
357169689Skan	  if (X##_e == 0)						 \
358169689Skan	    {								 \
359169689Skan	      /* X is zero or denormalized.  */				 \
360169689Skan	      if (_FP_FRAC_ZEROP_##wc(X))				 \
361169689Skan		{							 \
362169689Skan		  _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);			 \
363169689Skan		  _FP_FRAC_COPY_##wc(R, Y);				 \
364169689Skan		  goto add_done;					 \
365169689Skan		}							 \
366169689Skan	      else							 \
367169689Skan		{							 \
368169689Skan		  FP_SET_EXCEPTION(FP_EX_DENORM);			 \
369169689Skan		  ediff--;						 \
370169689Skan		  if (ediff == 0)					 \
371169689Skan		    {							 \
372169689Skan		      _FP_FRAC_ADD_##wc(R, Y, X);			 \
373169689Skan		      goto add3;					 \
374169689Skan		    }							 \
375169689Skan		  if (Y##_e == _FP_EXPMAX_##fs)				 \
376169689Skan		    {							 \
377169689Skan		      _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);		 \
378169689Skan		      _FP_FRAC_COPY_##wc(R, Y);				 \
379169689Skan		      goto add_done;					 \
380169689Skan		    }							 \
381169689Skan		  goto add2;						 \
382169689Skan		}							 \
383169689Skan	    }								 \
384169689Skan	  else if (Y##_e == _FP_EXPMAX_##fs)				 \
385169689Skan	    {								 \
386169689Skan	      /* Y is NaN or Inf, X is normal.  */			 \
387169689Skan	      _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);			 \
388169689Skan	      _FP_FRAC_COPY_##wc(R, Y);					 \
389169689Skan	      goto add_done;						 \
390169689Skan	    }								 \
391169689Skan									 \
392169689Skan	  /* Insert implicit MSB of X.  */				 \
393169689Skan	  _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs;			 \
394169689Skan									 \
395169689Skan	add2:								 \
396169689Skan	  /* Shift the mantissa of X to the right EDIFF steps;		 \
397169689Skan	     remember to account later for the implicit MSB of Y.  */	 \
398169689Skan	  if (ediff <= _FP_WFRACBITS_##fs)				 \
399169689Skan	    _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs);		 \
400169689Skan	  else if (!_FP_FRAC_ZEROP_##wc(X))				 \
401169689Skan	    _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);			 \
402169689Skan	  _FP_FRAC_ADD_##wc(R, Y, X);					 \
403169689Skan	}								 \
404169689Skan      else								 \
405169689Skan	{								 \
406169689Skan	  /* ediff == 0.  */						 \
407169689Skan	  if (!_FP_EXP_NORMAL(fs, wc, X))				 \
408169689Skan	    {								 \
409169689Skan	      if (X##_e == 0)						 \
410169689Skan		{							 \
411169689Skan		  /* X and Y are zero or denormalized.  */		 \
412169689Skan		  R##_e = 0;						 \
413169689Skan		  if (_FP_FRAC_ZEROP_##wc(X))				 \
414169689Skan		    {							 \
415169689Skan		      if (!_FP_FRAC_ZEROP_##wc(Y))			 \
416169689Skan			FP_SET_EXCEPTION(FP_EX_DENORM);			 \
417169689Skan		      _FP_FRAC_COPY_##wc(R, Y);				 \
418169689Skan		      goto add_done;					 \
419169689Skan		    }							 \
420169689Skan		  else if (_FP_FRAC_ZEROP_##wc(Y))			 \
421169689Skan		    {							 \
422169689Skan		      FP_SET_EXCEPTION(FP_EX_DENORM);			 \
423169689Skan		      _FP_FRAC_COPY_##wc(R, X);				 \
424169689Skan		      goto add_done;					 \
425169689Skan		    }							 \
426169689Skan		  else							 \
427169689Skan		    {							 \
428169689Skan		      FP_SET_EXCEPTION(FP_EX_DENORM);			 \
429169689Skan		      _FP_FRAC_ADD_##wc(R, X, Y);			 \
430169689Skan		      if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs)	 \
431169689Skan			{						 \
432169689Skan			  /* Normalized result.  */			 \
433169689Skan			  _FP_FRAC_HIGH_##fs(R)				 \
434169689Skan			    &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs;	 \
435169689Skan			  R##_e = 1;					 \
436169689Skan			}						 \
437169689Skan		      goto add_done;					 \
438169689Skan		    }							 \
439169689Skan		}							 \
440169689Skan	      else							 \
441169689Skan		{							 \
442169689Skan		  /* X and Y are NaN or Inf.  */			 \
443169689Skan		  _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);			 \
444169689Skan		  _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);			 \
445169689Skan		  R##_e = _FP_EXPMAX_##fs;				 \
446169689Skan		  if (_FP_FRAC_ZEROP_##wc(X))				 \
447169689Skan		    _FP_FRAC_COPY_##wc(R, Y);				 \
448169689Skan		  else if (_FP_FRAC_ZEROP_##wc(Y))			 \
449169689Skan		    _FP_FRAC_COPY_##wc(R, X);				 \
450169689Skan		  else							 \
451169689Skan		    _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP);		 \
452169689Skan		  goto add_done;					 \
453169689Skan		}							 \
454169689Skan	    }								 \
455169689Skan	  /* The exponents of X and Y, both normal, are equal.  The	 \
456169689Skan	     implicit MSBs will always add to increase the		 \
457169689Skan	     exponent.  */						 \
458169689Skan	  _FP_FRAC_ADD_##wc(R, X, Y);					 \
459169689Skan	  R##_e = X##_e + 1;						 \
460169689Skan	  _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);			 \
461169689Skan	  if (R##_e == _FP_EXPMAX_##fs)					 \
462169689Skan	    /* Overflow to infinity (depending on rounding mode).  */	 \
463169689Skan	    _FP_OVERFLOW_SEMIRAW(fs, wc, R);				 \
464169689Skan	  goto add_done;						 \
465169689Skan	}								 \
466169689Skan    add3:								 \
467169689Skan      if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs)			 \
468169689Skan	{								 \
469169689Skan	  /* Overflow.  */						 \
470169689Skan	  _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs;	 \
471169689Skan	  R##_e++;							 \
472169689Skan	  _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);			 \
473169689Skan	  if (R##_e == _FP_EXPMAX_##fs)					 \
474169689Skan	    /* Overflow to infinity (depending on rounding mode).  */	 \
475169689Skan	    _FP_OVERFLOW_SEMIRAW(fs, wc, R);				 \
476169689Skan	}								 \
477169689Skan    add_done: ;								 \
478169689Skan    }									 \
479169689Skan  else									 \
480169689Skan    {									 \
481169689Skan      /* Subtraction.  */						 \
482169689Skan      int ediff = X##_e - Y##_e;					 \
483169689Skan      if (ediff > 0)							 \
484169689Skan	{								 \
485169689Skan	  R##_e = X##_e;						 \
486169689Skan	  R##_s = X##_s;						 \
487169689Skan	  if (Y##_e == 0)						 \
488169689Skan	    {								 \
489169689Skan	      /* Y is zero or denormalized.  */				 \
490169689Skan	      if (_FP_FRAC_ZEROP_##wc(Y))				 \
491169689Skan		{							 \
492169689Skan		  _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);			 \
493169689Skan		  _FP_FRAC_COPY_##wc(R, X);				 \
494169689Skan		  goto sub_done;					 \
495169689Skan		}							 \
496169689Skan	      else							 \
497169689Skan		{							 \
498169689Skan		  FP_SET_EXCEPTION(FP_EX_DENORM);			 \
499169689Skan		  ediff--;						 \
500169689Skan		  if (ediff == 0)					 \
501169689Skan		    {							 \
502169689Skan		      _FP_FRAC_SUB_##wc(R, X, Y);			 \
503169689Skan		      goto sub3;					 \
504169689Skan		    }							 \
505169689Skan		  if (X##_e == _FP_EXPMAX_##fs)				 \
506169689Skan		    {							 \
507169689Skan		      _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);		 \
508169689Skan		      _FP_FRAC_COPY_##wc(R, X);				 \
509169689Skan		      goto sub_done;					 \
510169689Skan		    }							 \
511169689Skan		  goto sub1;						 \
512169689Skan		}							 \
513169689Skan	    }								 \
514169689Skan	  else if (X##_e == _FP_EXPMAX_##fs)				 \
515169689Skan	    {								 \
516169689Skan	      /* X is NaN or Inf, Y is normal.  */			 \
517169689Skan	      _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);			 \
518169689Skan	      _FP_FRAC_COPY_##wc(R, X);					 \
519169689Skan	      goto sub_done;						 \
520169689Skan	    }								 \
521169689Skan									 \
522169689Skan	  /* Insert implicit MSB of Y.  */				 \
523169689Skan	  _FP_FRAC_HIGH_##fs(Y) |= _FP_IMPLBIT_SH_##fs;			 \
524169689Skan									 \
525169689Skan	sub1:								 \
526169689Skan	  /* Shift the mantissa of Y to the right EDIFF steps;		 \
527169689Skan	     remember to account later for the implicit MSB of X.  */	 \
528169689Skan	  if (ediff <= _FP_WFRACBITS_##fs)				 \
529169689Skan	    _FP_FRAC_SRS_##wc(Y, ediff, _FP_WFRACBITS_##fs);		 \
530169689Skan	  else if (!_FP_FRAC_ZEROP_##wc(Y))				 \
531169689Skan	    _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc);			 \
532169689Skan	  _FP_FRAC_SUB_##wc(R, X, Y);					 \
533169689Skan	}								 \
534169689Skan      else if (ediff < 0)						 \
535169689Skan	{								 \
536169689Skan	  ediff = -ediff;						 \
537169689Skan	  R##_e = Y##_e;						 \
538169689Skan	  R##_s = Y##_s;						 \
539169689Skan	  if (X##_e == 0)						 \
540169689Skan	    {								 \
541169689Skan	      /* X is zero or denormalized.  */				 \
542169689Skan	      if (_FP_FRAC_ZEROP_##wc(X))				 \
543169689Skan		{							 \
544169689Skan		  _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);			 \
545169689Skan		  _FP_FRAC_COPY_##wc(R, Y);				 \
546169689Skan		  goto sub_done;					 \
547169689Skan		}							 \
548169689Skan	      else							 \
549169689Skan		{							 \
550169689Skan		  FP_SET_EXCEPTION(FP_EX_DENORM);			 \
551169689Skan		  ediff--;						 \
552169689Skan		  if (ediff == 0)					 \
553169689Skan		    {							 \
554169689Skan		      _FP_FRAC_SUB_##wc(R, Y, X);			 \
555169689Skan		      goto sub3;					 \
556169689Skan		    }							 \
557169689Skan		  if (Y##_e == _FP_EXPMAX_##fs)				 \
558169689Skan		    {							 \
559169689Skan		      _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);		 \
560169689Skan		      _FP_FRAC_COPY_##wc(R, Y);				 \
561169689Skan		      goto sub_done;					 \
562169689Skan		    }							 \
563169689Skan		  goto sub2;						 \
564169689Skan		}							 \
565169689Skan	    }								 \
566169689Skan	  else if (Y##_e == _FP_EXPMAX_##fs)				 \
567169689Skan	    {								 \
568169689Skan	      /* Y is NaN or Inf, X is normal.  */			 \
569169689Skan	      _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);			 \
570169689Skan	      _FP_FRAC_COPY_##wc(R, Y);					 \
571169689Skan	      goto sub_done;						 \
572169689Skan	    }								 \
573169689Skan									 \
574169689Skan	  /* Insert implicit MSB of X.  */				 \
575169689Skan	  _FP_FRAC_HIGH_##fs(X) |= _FP_IMPLBIT_SH_##fs;			 \
576169689Skan									 \
577169689Skan	sub2:								 \
578169689Skan	  /* Shift the mantissa of X to the right EDIFF steps;		 \
579169689Skan	     remember to account later for the implicit MSB of Y.  */	 \
580169689Skan	  if (ediff <= _FP_WFRACBITS_##fs)				 \
581169689Skan	    _FP_FRAC_SRS_##wc(X, ediff, _FP_WFRACBITS_##fs);		 \
582169689Skan	  else if (!_FP_FRAC_ZEROP_##wc(X))				 \
583169689Skan	    _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);			 \
584169689Skan	  _FP_FRAC_SUB_##wc(R, Y, X);					 \
585169689Skan	}								 \
586169689Skan      else								 \
587169689Skan	{								 \
588169689Skan	  /* ediff == 0.  */						 \
589169689Skan	  if (!_FP_EXP_NORMAL(fs, wc, X))				 \
590169689Skan	    {								 \
591169689Skan	      if (X##_e == 0)						 \
592169689Skan		{							 \
593169689Skan		  /* X and Y are zero or denormalized.  */		 \
594169689Skan		  R##_e = 0;						 \
595169689Skan		  if (_FP_FRAC_ZEROP_##wc(X))				 \
596169689Skan		    {							 \
597169689Skan		      _FP_FRAC_COPY_##wc(R, Y);				 \
598169689Skan		      if (_FP_FRAC_ZEROP_##wc(Y))			 \
599169689Skan			R##_s = (FP_ROUNDMODE == FP_RND_MINF);		 \
600169689Skan		      else						 \
601169689Skan			{						 \
602169689Skan			  FP_SET_EXCEPTION(FP_EX_DENORM);		 \
603169689Skan			  R##_s = Y##_s;				 \
604169689Skan			}						 \
605169689Skan		      goto sub_done;					 \
606169689Skan		    }							 \
607169689Skan		  else if (_FP_FRAC_ZEROP_##wc(Y))			 \
608169689Skan		    {							 \
609169689Skan		      FP_SET_EXCEPTION(FP_EX_DENORM);			 \
610169689Skan		      _FP_FRAC_COPY_##wc(R, X);				 \
611169689Skan		      R##_s = X##_s;					 \
612169689Skan		      goto sub_done;					 \
613169689Skan		    }							 \
614169689Skan		  else							 \
615169689Skan		    {							 \
616169689Skan		      FP_SET_EXCEPTION(FP_EX_DENORM);			 \
617169689Skan		      _FP_FRAC_SUB_##wc(R, X, Y);			 \
618169689Skan		      R##_s = X##_s;					 \
619169689Skan		      if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs)	 \
620169689Skan			{						 \
621169689Skan			  /* |X| < |Y|, negate result.  */		 \
622169689Skan			  _FP_FRAC_SUB_##wc(R, Y, X);			 \
623169689Skan			  R##_s = Y##_s;				 \
624169689Skan			}						 \
625169689Skan		      else if (_FP_FRAC_ZEROP_##wc(R))			 \
626169689Skan			R##_s = (FP_ROUNDMODE == FP_RND_MINF);		 \
627169689Skan		      goto sub_done;					 \
628169689Skan		    }							 \
629169689Skan		}							 \
630169689Skan	      else							 \
631169689Skan		{							 \
632169689Skan		  /* X and Y are NaN or Inf, of opposite signs.  */	 \
633169689Skan		  _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, X);			 \
634169689Skan		  _FP_CHECK_SIGNAN_SEMIRAW(fs, wc, Y);			 \
635169689Skan		  R##_e = _FP_EXPMAX_##fs;				 \
636169689Skan		  if (_FP_FRAC_ZEROP_##wc(X))				 \
637169689Skan		    {							 \
638169689Skan		      if (_FP_FRAC_ZEROP_##wc(Y))			 \
639169689Skan			{						 \
640169689Skan			  /* Inf - Inf.  */				 \
641169689Skan			  R##_s = _FP_NANSIGN_##fs;			 \
642169689Skan			  _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);	 \
643169689Skan			  _FP_FRAC_SLL_##wc(R, _FP_WORKBITS);		 \
644169689Skan			  FP_SET_EXCEPTION(FP_EX_INVALID);		 \
645169689Skan			}						 \
646169689Skan		      else						 \
647169689Skan			{						 \
648169689Skan			  /* Inf - NaN.  */				 \
649169689Skan			  R##_s = Y##_s;				 \
650169689Skan			  _FP_FRAC_COPY_##wc(R, Y);			 \
651169689Skan			}						 \
652169689Skan		    }							 \
653169689Skan		  else							 \
654169689Skan		    {							 \
655169689Skan		      if (_FP_FRAC_ZEROP_##wc(Y))			 \
656169689Skan			{						 \
657169689Skan			  /* NaN - Inf.  */				 \
658169689Skan			  R##_s = X##_s;				 \
659169689Skan			  _FP_FRAC_COPY_##wc(R, X);			 \
660169689Skan			}						 \
661169689Skan		      else						 \
662169689Skan			{						 \
663169689Skan			  /* NaN - NaN.  */				 \
664169689Skan			  _FP_CHOOSENAN_SEMIRAW(fs, wc, R, X, Y, OP);	 \
665169689Skan			}						 \
666169689Skan		    }							 \
667169689Skan		  goto sub_done;					 \
668169689Skan		}							 \
669169689Skan	    }								 \
670169689Skan	  /* The exponents of X and Y, both normal, are equal.  The	 \
671169689Skan	     implicit MSBs cancel.  */					 \
672169689Skan	  R##_e = X##_e;						 \
673169689Skan	  _FP_FRAC_SUB_##wc(R, X, Y);					 \
674169689Skan	  R##_s = X##_s;						 \
675169689Skan	  if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs)		 \
676169689Skan	    {								 \
677169689Skan	      /* |X| < |Y|, negate result.  */				 \
678169689Skan	      _FP_FRAC_SUB_##wc(R, Y, X);				 \
679169689Skan	      R##_s = Y##_s;						 \
680169689Skan	    }								 \
681169689Skan	  else if (_FP_FRAC_ZEROP_##wc(R))				 \
682169689Skan	    {								 \
683169689Skan	      R##_e = 0;						 \
684169689Skan	      R##_s = (FP_ROUNDMODE == FP_RND_MINF);			 \
685169689Skan	      goto sub_done;						 \
686169689Skan	    }								 \
687169689Skan	  goto norm;							 \
688169689Skan	}								 \
689169689Skan    sub3:								 \
690169689Skan      if (_FP_FRAC_HIGH_##fs(R) & _FP_IMPLBIT_SH_##fs)			 \
691169689Skan	{								 \
692169689Skan	  int diff;							 \
693169689Skan	  /* Carry into most significant bit of larger one of X and Y,	 \
694169689Skan	     canceling it; renormalize.  */				 \
695169689Skan	  _FP_FRAC_HIGH_##fs(R) &= _FP_IMPLBIT_SH_##fs - 1;		 \
696169689Skan	norm:								 \
697169689Skan	  _FP_FRAC_CLZ_##wc(diff, R);					 \
698169689Skan	  diff -= _FP_WFRACXBITS_##fs;					 \
699169689Skan	  _FP_FRAC_SLL_##wc(R, diff);					 \
700169689Skan	  if (R##_e <= diff)						 \
701169689Skan	    {								 \
702169689Skan	      /* R is denormalized.  */					 \
703169689Skan	      diff = diff - R##_e + 1;					 \
704169689Skan	      _FP_FRAC_SRS_##wc(R, diff, _FP_WFRACBITS_##fs);		 \
705169689Skan	      R##_e = 0;						 \
706169689Skan	    }								 \
707169689Skan	  else								 \
708169689Skan	    {								 \
709169689Skan	      R##_e -= diff;						 \
710169689Skan	      _FP_FRAC_HIGH_##fs(R) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs; \
711169689Skan	    }								 \
712169689Skan	}								 \
713169689Skan    sub_done: ;								 \
714169689Skan    }									 \
715169689Skan} while (0)
716169689Skan
717169689Skan#define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+')
718169689Skan#define _FP_SUB(fs, wc, R, X, Y)					    \
719169689Skan  do {									    \
720169689Skan    if (!(Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) Y##_s ^= 1; \
721169689Skan    _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-');				    \
722169689Skan  } while (0)
723169689Skan
724169689Skan
725169689Skan/*
726169689Skan * Main negation routine.  FIXME -- when we care about setting exception
727169689Skan * bits reliably, this will not do.  We should examine all of the fp classes.
728169689Skan */
729169689Skan
730169689Skan#define _FP_NEG(fs, wc, R, X)		\
731169689Skan  do {					\
732169689Skan    _FP_FRAC_COPY_##wc(R, X);		\
733169689Skan    R##_c = X##_c;			\
734169689Skan    R##_e = X##_e;			\
735169689Skan    R##_s = 1 ^ X##_s;			\
736169689Skan  } while (0)
737169689Skan
738169689Skan
739169689Skan/*
740169689Skan * Main multiplication routine.  The input values should be cooked.
741169689Skan */
742169689Skan
743169689Skan#define _FP_MUL(fs, wc, R, X, Y)			\
744169689Skando {							\
745169689Skan  R##_s = X##_s ^ Y##_s;				\
746169689Skan  switch (_FP_CLS_COMBINE(X##_c, Y##_c))		\
747169689Skan  {							\
748169689Skan  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):	\
749169689Skan    R##_c = FP_CLS_NORMAL;				\
750169689Skan    R##_e = X##_e + Y##_e + 1;				\
751169689Skan							\
752169689Skan    _FP_MUL_MEAT_##fs(R,X,Y);				\
753169689Skan							\
754169689Skan    if (_FP_FRAC_OVERP_##wc(fs, R))			\
755169689Skan      _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);	\
756169689Skan    else						\
757169689Skan      R##_e--;						\
758169689Skan    break;						\
759169689Skan							\
760169689Skan  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):		\
761169689Skan    _FP_CHOOSENAN(fs, wc, R, X, Y, '*');		\
762169689Skan    break;						\
763169689Skan							\
764169689Skan  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):	\
765169689Skan  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):		\
766169689Skan  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):		\
767169689Skan    R##_s = X##_s;					\
768169689Skan							\
769169689Skan  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):		\
770169689Skan  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):	\
771169689Skan  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):	\
772169689Skan  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):	\
773169689Skan    _FP_FRAC_COPY_##wc(R, X);				\
774169689Skan    R##_c = X##_c;					\
775169689Skan    break;						\
776169689Skan							\
777169689Skan  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):	\
778169689Skan  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):		\
779169689Skan  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):		\
780169689Skan    R##_s = Y##_s;					\
781169689Skan							\
782169689Skan  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):	\
783169689Skan  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):	\
784169689Skan    _FP_FRAC_COPY_##wc(R, Y);				\
785169689Skan    R##_c = Y##_c;					\
786169689Skan    break;						\
787169689Skan							\
788169689Skan  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):		\
789169689Skan  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):		\
790169689Skan    R##_s = _FP_NANSIGN_##fs;				\
791169689Skan    R##_c = FP_CLS_NAN;					\
792169689Skan    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
793169689Skan    FP_SET_EXCEPTION(FP_EX_INVALID);			\
794169689Skan    break;						\
795169689Skan							\
796169689Skan  default:						\
797169689Skan    abort();						\
798169689Skan  }							\
799169689Skan} while (0)
800169689Skan
801169689Skan
802169689Skan/*
803169689Skan * Main division routine.  The input values should be cooked.
804169689Skan */
805169689Skan
806169689Skan#define _FP_DIV(fs, wc, R, X, Y)			\
807169689Skando {							\
808169689Skan  R##_s = X##_s ^ Y##_s;				\
809169689Skan  switch (_FP_CLS_COMBINE(X##_c, Y##_c))		\
810169689Skan  {							\
811169689Skan  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):	\
812169689Skan    R##_c = FP_CLS_NORMAL;				\
813169689Skan    R##_e = X##_e - Y##_e;				\
814169689Skan							\
815169689Skan    _FP_DIV_MEAT_##fs(R,X,Y);				\
816169689Skan    break;						\
817169689Skan							\
818169689Skan  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):		\
819169689Skan    _FP_CHOOSENAN(fs, wc, R, X, Y, '/');		\
820169689Skan    break;						\
821169689Skan							\
822169689Skan  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):	\
823169689Skan  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):		\
824169689Skan  case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):		\
825169689Skan    R##_s = X##_s;					\
826169689Skan    _FP_FRAC_COPY_##wc(R, X);				\
827169689Skan    R##_c = X##_c;					\
828169689Skan    break;						\
829169689Skan							\
830169689Skan  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):	\
831169689Skan  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):		\
832169689Skan  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):		\
833169689Skan    R##_s = Y##_s;					\
834169689Skan    _FP_FRAC_COPY_##wc(R, Y);				\
835169689Skan    R##_c = Y##_c;					\
836169689Skan    break;						\
837169689Skan							\
838169689Skan  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):	\
839169689Skan  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):		\
840169689Skan  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):	\
841169689Skan    R##_c = FP_CLS_ZERO;				\
842169689Skan    break;						\
843169689Skan							\
844169689Skan  case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):	\
845169689Skan    FP_SET_EXCEPTION(FP_EX_DIVZERO);			\
846169689Skan  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):		\
847169689Skan  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):	\
848169689Skan    R##_c = FP_CLS_INF;					\
849169689Skan    break;						\
850169689Skan							\
851169689Skan  case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):		\
852169689Skan  case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):	\
853169689Skan    R##_s = _FP_NANSIGN_##fs;				\
854169689Skan    R##_c = FP_CLS_NAN;					\
855169689Skan    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);		\
856169689Skan    FP_SET_EXCEPTION(FP_EX_INVALID);			\
857169689Skan    break;						\
858169689Skan							\
859169689Skan  default:						\
860169689Skan    abort();						\
861169689Skan  }							\
862169689Skan} while (0)
863169689Skan
864169689Skan
865169689Skan/*
866169689Skan * Main differential comparison routine.  The inputs should be raw not
867169689Skan * cooked.  The return is -1,0,1 for normal values, 2 otherwise.
868169689Skan */
869169689Skan
870169689Skan#define _FP_CMP(fs, wc, ret, X, Y, un)					\
871169689Skan  do {									\
872169689Skan    /* NANs are unordered */						\
873169689Skan    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))		\
874169689Skan	|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))	\
875169689Skan      {									\
876169689Skan	ret = un;							\
877169689Skan      }									\
878169689Skan    else								\
879169689Skan      {									\
880169689Skan	int __is_zero_x;						\
881169689Skan	int __is_zero_y;						\
882169689Skan									\
883169689Skan	__is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0;	\
884169689Skan	__is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0;	\
885169689Skan									\
886169689Skan	if (__is_zero_x && __is_zero_y)					\
887169689Skan		ret = 0;						\
888169689Skan	else if (__is_zero_x)						\
889169689Skan		ret = Y##_s ? 1 : -1;					\
890169689Skan	else if (__is_zero_y)						\
891169689Skan		ret = X##_s ? -1 : 1;					\
892169689Skan	else if (X##_s != Y##_s)					\
893169689Skan	  ret = X##_s ? -1 : 1;						\
894169689Skan	else if (X##_e > Y##_e)						\
895169689Skan	  ret = X##_s ? -1 : 1;						\
896169689Skan	else if (X##_e < Y##_e)						\
897169689Skan	  ret = X##_s ? 1 : -1;						\
898169689Skan	else if (_FP_FRAC_GT_##wc(X, Y))				\
899169689Skan	  ret = X##_s ? -1 : 1;						\
900169689Skan	else if (_FP_FRAC_GT_##wc(Y, X))				\
901169689Skan	  ret = X##_s ? 1 : -1;						\
902169689Skan	else								\
903169689Skan	  ret = 0;							\
904169689Skan      }									\
905169689Skan  } while (0)
906169689Skan
907169689Skan
908169689Skan/* Simplification for strict equality.  */
909169689Skan
910169689Skan#define _FP_CMP_EQ(fs, wc, ret, X, Y)					    \
911169689Skan  do {									    \
912169689Skan    /* NANs are unordered */						    \
913169689Skan    if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))		    \
914169689Skan	|| (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))	    \
915169689Skan      {									    \
916169689Skan	ret = 1;							    \
917169689Skan      }									    \
918169689Skan    else								    \
919169689Skan      {									    \
920169689Skan	ret = !(X##_e == Y##_e						    \
921169689Skan		&& _FP_FRAC_EQ_##wc(X, Y)				    \
922169689Skan		&& (X##_s == Y##_s || (!X##_e && _FP_FRAC_ZEROP_##wc(X)))); \
923169689Skan      }									    \
924169689Skan  } while (0)
925169689Skan
926169689Skan/* Version to test unordered.  */
927169689Skan
928169689Skan#define _FP_CMP_UNORD(fs, wc, ret, X, Y)				\
929169689Skan  do {									\
930169689Skan    ret = ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))	\
931169689Skan	   || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)));	\
932169689Skan  } while (0)
933169689Skan
934169689Skan/*
935169689Skan * Main square root routine.  The input value should be cooked.
936169689Skan */
937169689Skan
938169689Skan#define _FP_SQRT(fs, wc, R, X)						\
939169689Skando {									\
940169689Skan    _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S);			\
941169689Skan    _FP_W_TYPE q;							\
942169689Skan    switch (X##_c)							\
943169689Skan    {									\
944169689Skan    case FP_CLS_NAN:							\
945169689Skan	_FP_FRAC_COPY_##wc(R, X);					\
946169689Skan	R##_s = X##_s;							\
947169689Skan    	R##_c = FP_CLS_NAN;						\
948169689Skan    	break;								\
949169689Skan    case FP_CLS_INF:							\
950169689Skan    	if (X##_s)							\
951169689Skan    	  {								\
952169689Skan    	    R##_s = _FP_NANSIGN_##fs;					\
953169689Skan	    R##_c = FP_CLS_NAN; /* NAN */				\
954169689Skan	    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);			\
955169689Skan	    FP_SET_EXCEPTION(FP_EX_INVALID);				\
956169689Skan    	  }								\
957169689Skan    	else								\
958169689Skan    	  {								\
959169689Skan    	    R##_s = 0;							\
960169689Skan    	    R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */			\
961169689Skan    	  }								\
962169689Skan    	break;								\
963169689Skan    case FP_CLS_ZERO:							\
964169689Skan	R##_s = X##_s;							\
965169689Skan	R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */			\
966169689Skan	break;								\
967169689Skan    case FP_CLS_NORMAL:							\
968169689Skan    	R##_s = 0;							\
969169689Skan        if (X##_s)							\
970169689Skan          {								\
971169689Skan	    R##_c = FP_CLS_NAN; /* sNAN */				\
972169689Skan	    R##_s = _FP_NANSIGN_##fs;					\
973169689Skan	    _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);			\
974169689Skan	    FP_SET_EXCEPTION(FP_EX_INVALID);				\
975169689Skan	    break;							\
976169689Skan          }								\
977169689Skan    	R##_c = FP_CLS_NORMAL;						\
978169689Skan        if (X##_e & 1)							\
979169689Skan          _FP_FRAC_SLL_##wc(X, 1);					\
980169689Skan        R##_e = X##_e >> 1;						\
981169689Skan        _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc);			\
982169689Skan        _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc);			\
983169689Skan        q = _FP_OVERFLOW_##fs >> 1;					\
984169689Skan        _FP_SQRT_MEAT_##wc(R, S, T, X, q);				\
985169689Skan    }									\
986169689Skan  } while (0)
987169689Skan
988169689Skan/*
989169689Skan * Convert from FP to integer.  Input is raw.
990169689Skan */
991169689Skan
992169689Skan/* RSIGNED can have following values:
993169689Skan * 0:  the number is required to be 0..(2^rsize)-1, if not, NV is set plus
994169689Skan *     the result is either 0 or (2^rsize)-1 depending on the sign in such
995169689Skan *     case.
996169689Skan * 1:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not,
997169689Skan *     NV is set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
998169689Skan *     depending on the sign in such case.
999169689Skan * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
1000169689Skan *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1
1001169689Skan *     depending on the sign in such case.
1002169689Skan */
1003169689Skan#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)			\
1004169689Skando {									\
1005169689Skan  if (X##_e < _FP_EXPBIAS_##fs)						\
1006169689Skan    {									\
1007169689Skan      r = 0;								\
1008169689Skan      if (X##_e == 0)							\
1009169689Skan	{								\
1010169689Skan	  if (!_FP_FRAC_ZEROP_##wc(X))					\
1011169689Skan	    {								\
1012169689Skan	      FP_SET_EXCEPTION(FP_EX_INEXACT);				\
1013169689Skan	      FP_SET_EXCEPTION(FP_EX_DENORM);				\
1014169689Skan	    }								\
1015169689Skan	}								\
1016169689Skan      else								\
1017169689Skan	FP_SET_EXCEPTION(FP_EX_INEXACT);				\
1018169689Skan    }									\
1019169689Skan  else if (X##_e >= _FP_EXPBIAS_##fs + rsize - (rsigned > 0 || X##_s)	\
1020169689Skan	   || (!rsigned && X##_s))					\
1021169689Skan    {									\
1022169689Skan      /* Overflow or converting to the most negative integer.  */	\
1023169689Skan      if (rsigned)							\
1024169689Skan	{								\
1025169689Skan	  r = 1;							\
1026169689Skan	  r <<= rsize - 1;						\
1027169689Skan	  r -= 1 - X##_s;						\
1028169689Skan	} else {							\
1029169689Skan	  r = 0;							\
1030169689Skan	  if (X##_s)							\
1031169689Skan	    r = ~r;							\
1032169689Skan	}								\
1033169689Skan									\
1034169689Skan      if (rsigned && X##_s && X##_e == _FP_EXPBIAS_##fs + rsize - 1)	\
1035169689Skan	{								\
1036169689Skan	  /* Possibly converting to most negative integer; check the	\
1037169689Skan	     mantissa.  */						\
1038169689Skan	  int inexact = 0;						\
1039169689Skan	  (void)((_FP_FRACBITS_##fs > rsize)				\
1040169689Skan		 ? ({ _FP_FRAC_SRST_##wc(X, inexact,			\
1041169689Skan					 _FP_FRACBITS_##fs - rsize,	\
1042169689Skan					 _FP_FRACBITS_##fs); 0; })	\
1043169689Skan		 : 0);							\
1044169689Skan	  if (!_FP_FRAC_ZEROP_##wc(X))					\
1045169689Skan	    FP_SET_EXCEPTION(FP_EX_INVALID);				\
1046169689Skan	  else if (inexact)						\
1047169689Skan	    FP_SET_EXCEPTION(FP_EX_INEXACT);				\
1048169689Skan	}								\
1049169689Skan      else								\
1050169689Skan	FP_SET_EXCEPTION(FP_EX_INVALID);				\
1051169689Skan    }									\
1052169689Skan  else									\
1053169689Skan    {									\
1054169689Skan      _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs;			\
1055169689Skan      if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1)		\
1056169689Skan	{								\
1057169689Skan	  _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);				\
1058169689Skan	  r <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1;	\
1059169689Skan	}								\
1060169689Skan      else								\
1061169689Skan	{								\
1062169689Skan	  int inexact;							\
1063169689Skan	  _FP_FRAC_SRST_##wc(X, inexact,				\
1064169689Skan			    (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs - 1	\
1065169689Skan			     - X##_e),					\
1066169689Skan			    _FP_FRACBITS_##fs);				\
1067169689Skan	  if (inexact)							\
1068169689Skan	    FP_SET_EXCEPTION(FP_EX_INEXACT);				\
1069169689Skan	  _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);				\
1070169689Skan	}								\
1071169689Skan      if (rsigned && X##_s)						\
1072169689Skan	r = -r;								\
1073169689Skan    }									\
1074169689Skan} while (0)
1075169689Skan
1076169689Skan/* Convert integer to fp.  Output is raw.  RTYPE is unsigned even if
1077169689Skan   input is signed.  */
1078169689Skan#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)			     \
1079169689Skan  do {									     \
1080169689Skan    if (r)								     \
1081169689Skan      {									     \
1082169689Skan	rtype ur_;							     \
1083169689Skan									     \
1084169689Skan	if ((X##_s = (r < 0)))						     \
1085169689Skan	  r = -(rtype)r;						     \
1086169689Skan									     \
1087169689Skan	ur_ = (rtype) r;						     \
1088169689Skan	(void)((rsize <= _FP_W_TYPE_SIZE)				     \
1089169689Skan	       ? ({							     \
1090169689Skan		    int lz_;						     \
1091169689Skan		    __FP_CLZ(lz_, (_FP_W_TYPE)ur_);			     \
1092169689Skan		    X##_e = _FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 - lz_;    \
1093169689Skan		  })							     \
1094169689Skan	       : ((rsize <= 2 * _FP_W_TYPE_SIZE)			     \
1095169689Skan		  ? ({							     \
1096169689Skan		       int lz_;						     \
1097169689Skan		       __FP_CLZ_2(lz_, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE), \
1098169689Skan				  (_FP_W_TYPE)ur_);			     \
1099169689Skan		       X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1   \
1100169689Skan				- lz_);					     \
1101169689Skan		     })							     \
1102169689Skan		  : (abort(), 0)));					     \
1103169689Skan									     \
1104169689Skan	if (rsize - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs		     \
1105169689Skan	    && X##_e >= _FP_EXPMAX_##fs)				     \
1106169689Skan	  {								     \
1107169689Skan	    /* Exponent too big; overflow to infinity.  (May also	     \
1108169689Skan	       happen after rounding below.)  */			     \
1109169689Skan	    _FP_OVERFLOW_SEMIRAW(fs, wc, X);				     \
1110169689Skan	    goto pack_semiraw;						     \
1111169689Skan	  }								     \
1112169689Skan									     \
1113169689Skan	if (rsize <= _FP_FRACBITS_##fs					     \
1114169689Skan	    || X##_e < _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs)		     \
1115169689Skan	  {								     \
1116169689Skan	    /* Exactly representable; shift left.  */			     \
1117169689Skan	    _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize);			     \
1118169689Skan	    _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs			     \
1119169689Skan				  + _FP_FRACBITS_##fs - 1 - X##_e));	     \
1120169689Skan	  }								     \
1121169689Skan	else								     \
1122169689Skan	  {								     \
1123169689Skan	    /* More bits in integer than in floating type; need to	     \
1124169689Skan	       round.  */						     \
1125169689Skan	    if (_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 < X##_e)	     \
1126169689Skan	      ur_ = ((ur_ >> (X##_e - _FP_EXPBIAS_##fs			     \
1127169689Skan			      - _FP_WFRACBITS_##fs + 1))		     \
1128169689Skan		     | ((ur_ << (rsize - (X##_e - _FP_EXPBIAS_##fs	     \
1129169689Skan					  - _FP_WFRACBITS_##fs + 1)))	     \
1130169689Skan			!= 0));						     \
1131169689Skan	    _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize);			     \
1132169689Skan	    if ((_FP_EXPBIAS_##fs + _FP_WFRACBITS_##fs - 1 - X##_e) > 0)     \
1133169689Skan	      _FP_FRAC_SLL_##wc(X, (_FP_EXPBIAS_##fs			     \
1134169689Skan				    + _FP_WFRACBITS_##fs - 1 - X##_e));	     \
1135169689Skan	    _FP_FRAC_HIGH_##fs(X) &= ~(_FP_W_TYPE)_FP_IMPLBIT_SH_##fs;	     \
1136169689Skan	  pack_semiraw:							     \
1137169689Skan	    _FP_PACK_SEMIRAW(fs, wc, X);				     \
1138169689Skan	  }								     \
1139169689Skan      }									     \
1140169689Skan    else								     \
1141169689Skan      {									     \
1142169689Skan	X##_s = 0;							     \
1143169689Skan	X##_e = 0;							     \
1144169689Skan	_FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);			     \
1145169689Skan      }									     \
1146169689Skan  } while (0)
1147169689Skan
1148169689Skan
1149169689Skan/* Extend from a narrower floating-point format to a wider one.  Input
1150169689Skan   and output are raw.  */
1151169689Skan#define FP_EXTEND(dfs,sfs,dwc,swc,D,S)					 \
1152169689Skando {									 \
1153169689Skan  if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs				 \
1154169689Skan      || (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs				 \
1155169689Skan	  < _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs)			 \
1156171825Skan      || (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \
1157171825Skan	  && _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs))			 \
1158169689Skan    abort();								 \
1159169689Skan  D##_s = S##_s;							 \
1160169689Skan  _FP_FRAC_COPY_##dwc##_##swc(D, S);					 \
1161169689Skan  if (_FP_EXP_NORMAL(sfs, swc, S))					 \
1162169689Skan    {									 \
1163169689Skan      D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs;		 \
1164169689Skan      _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs - _FP_FRACBITS_##sfs));	 \
1165169689Skan    }									 \
1166169689Skan  else									 \
1167169689Skan    {									 \
1168169689Skan      if (S##_e == 0)							 \
1169169689Skan	{								 \
1170169689Skan	  if (_FP_FRAC_ZEROP_##swc(S))					 \
1171169689Skan	    D##_e = 0;							 \
1172171825Skan	  else if (_FP_EXPBIAS_##dfs					 \
1173171825Skan		   < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1)	 \
1174171825Skan	    {								 \
1175171825Skan	      FP_SET_EXCEPTION(FP_EX_DENORM);				 \
1176171825Skan	      _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs			 \
1177171825Skan				     - _FP_FRACBITS_##sfs));		 \
1178171825Skan	      D##_e = 0;						 \
1179171825Skan	    }								 \
1180169689Skan	  else								 \
1181169689Skan	    {								 \
1182169689Skan	      int _lz;							 \
1183169689Skan	      FP_SET_EXCEPTION(FP_EX_DENORM);				 \
1184169689Skan	      _FP_FRAC_CLZ_##swc(_lz, S);				 \
1185169689Skan	      _FP_FRAC_SLL_##dwc(D,					 \
1186169689Skan				 _lz + _FP_FRACBITS_##dfs		 \
1187169689Skan				 - _FP_FRACTBITS_##sfs);		 \
1188169689Skan	      D##_e = (_FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs + 1	 \
1189169689Skan		       + _FP_FRACXBITS_##sfs - _lz);			 \
1190169689Skan	    }								 \
1191169689Skan	}								 \
1192169689Skan      else								 \
1193169689Skan	{								 \
1194169689Skan	  D##_e = _FP_EXPMAX_##dfs;					 \
1195169689Skan	  if (!_FP_FRAC_ZEROP_##swc(S))					 \
1196169689Skan	    {								 \
1197169689Skan	      if (!(_FP_FRAC_HIGH_RAW_##sfs(S) & _FP_QNANBIT_##sfs))	 \
1198169689Skan		FP_SET_EXCEPTION(FP_EX_INVALID);			 \
1199169689Skan	      _FP_FRAC_SLL_##dwc(D, (_FP_FRACBITS_##dfs			 \
1200169689Skan				     - _FP_FRACBITS_##sfs));		 \
1201169689Skan	    }								 \
1202169689Skan	}								 \
1203169689Skan    }									 \
1204169689Skan} while (0)
1205169689Skan
1206169689Skan/* Truncate from a wider floating-point format to a narrower one.
1207169689Skan   Input and output are semi-raw.  */
1208169689Skan#define FP_TRUNC(dfs,sfs,dwc,swc,D,S)					     \
1209169689Skando {									     \
1210169689Skan  if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs				     \
1211171825Skan      || (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1     \
1212171825Skan	  && _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs))			     \
1213169689Skan    abort();								     \
1214169689Skan  D##_s = S##_s;							     \
1215169689Skan  if (_FP_EXP_NORMAL(sfs, swc, S))					     \
1216169689Skan    {									     \
1217169689Skan      D##_e = S##_e + _FP_EXPBIAS_##dfs - _FP_EXPBIAS_##sfs;		     \
1218169689Skan      if (D##_e >= _FP_EXPMAX_##dfs)					     \
1219169689Skan	_FP_OVERFLOW_SEMIRAW(dfs, dwc, D);				     \
1220169689Skan      else								     \
1221169689Skan	{								     \
1222169689Skan	  if (D##_e <= 0)						     \
1223169689Skan	    {								     \
1224171825Skan	      if (D##_e < 1 - _FP_FRACBITS_##dfs)			     \
1225171825Skan		{							     \
1226171825Skan		  _FP_FRAC_SET_##swc(S, _FP_ZEROFRAC_##swc);		     \
1227171825Skan		  _FP_FRAC_LOW_##swc(S) |= 1;				     \
1228171825Skan		}							     \
1229169689Skan	      else							     \
1230169689Skan		{							     \
1231169689Skan		  _FP_FRAC_HIGH_##sfs(S) |= _FP_IMPLBIT_SH_##sfs;	     \
1232169689Skan		  _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs		     \
1233169689Skan					 - _FP_WFRACBITS_##dfs + 1 - D##_e), \
1234169689Skan				     _FP_WFRACBITS_##sfs);		     \
1235169689Skan		}							     \
1236169689Skan	      D##_e = 0;						     \
1237169689Skan	    }								     \
1238169689Skan	  else								     \
1239169689Skan	    _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs			     \
1240169689Skan				   - _FP_WFRACBITS_##dfs),		     \
1241169689Skan			       _FP_WFRACBITS_##sfs);			     \
1242169689Skan	  _FP_FRAC_COPY_##dwc##_##swc(D, S);				     \
1243169689Skan	}								     \
1244169689Skan    }									     \
1245169689Skan  else									     \
1246169689Skan    {									     \
1247169689Skan      if (S##_e == 0)							     \
1248169689Skan	{								     \
1249169689Skan	  D##_e = 0;							     \
1250171825Skan	  if (_FP_FRAC_ZEROP_##swc(S))					     \
1251171825Skan	    _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc);			     \
1252171825Skan	  else								     \
1253169689Skan	    {								     \
1254169689Skan	      FP_SET_EXCEPTION(FP_EX_DENORM);				     \
1255171825Skan	      if (_FP_EXPBIAS_##sfs					     \
1256171825Skan		  < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1)		     \
1257171825Skan		{							     \
1258171825Skan		  _FP_FRAC_SRS_##swc(S, (_FP_WFRACBITS_##sfs		     \
1259171825Skan					 - _FP_WFRACBITS_##dfs),	     \
1260171825Skan				     _FP_WFRACBITS_##sfs);		     \
1261171825Skan		  _FP_FRAC_COPY_##dwc##_##swc(D, S);			     \
1262171825Skan		}							     \
1263171825Skan	      else							     \
1264171825Skan		{							     \
1265171825Skan		  _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc);		     \
1266171825Skan		  _FP_FRAC_LOW_##dwc(D) |= 1;				     \
1267171825Skan		}							     \
1268169689Skan	    }								     \
1269169689Skan	}								     \
1270169689Skan      else								     \
1271169689Skan	{								     \
1272169689Skan	  D##_e = _FP_EXPMAX_##dfs;					     \
1273169689Skan	  if (_FP_FRAC_ZEROP_##swc(S))					     \
1274169689Skan	    _FP_FRAC_SET_##dwc(D, _FP_ZEROFRAC_##dwc);			     \
1275169689Skan	  else								     \
1276169689Skan	    {								     \
1277169689Skan	      _FP_CHECK_SIGNAN_SEMIRAW(sfs, swc, S);			     \
1278169689Skan	      _FP_FRAC_SRL_##swc(S, (_FP_WFRACBITS_##sfs		     \
1279169689Skan				     - _FP_WFRACBITS_##dfs));		     \
1280169689Skan	      _FP_FRAC_COPY_##dwc##_##swc(D, S);			     \
1281169689Skan	      /* Semi-raw NaN must have all workbits cleared.  */	     \
1282169689Skan	      _FP_FRAC_LOW_##dwc(D)					     \
1283169689Skan		&= ~(_FP_W_TYPE) ((1 << _FP_WORKBITS) - 1);		     \
1284169689Skan	      _FP_FRAC_HIGH_##dfs(D) |= _FP_QNANBIT_SH_##dfs;		     \
1285169689Skan	    }								     \
1286169689Skan	}								     \
1287169689Skan    }									     \
1288169689Skan} while (0)
1289169689Skan
1290169689Skan/*
1291169689Skan * Helper primitives.
1292169689Skan */
1293169689Skan
1294169689Skan/* Count leading zeros in a word.  */
1295169689Skan
1296169689Skan#ifndef __FP_CLZ
1297169689Skan/* GCC 3.4 and later provide the builtins for us.  */
1298169689Skan#define __FP_CLZ(r, x)							      \
1299169689Skan  do {									      \
1300169689Skan    if (sizeof (_FP_W_TYPE) == sizeof (unsigned int))			      \
1301169689Skan      r = __builtin_clz (x);						      \
1302169689Skan    else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long))		      \
1303169689Skan      r = __builtin_clzl (x);						      \
1304169689Skan    else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long))	      \
1305169689Skan      r = __builtin_clzll (x);						      \
1306169689Skan    else								      \
1307169689Skan      abort ();								      \
1308169689Skan  } while (0)
1309169689Skan#endif /* ndef __FP_CLZ */
1310169689Skan
1311169689Skan#define _FP_DIV_HELP_imm(q, r, n, d)		\
1312169689Skan  do {						\
1313169689Skan    q = n / d, r = n % d;			\
1314169689Skan  } while (0)
1315169689Skan
1316169689Skan
1317169689Skan/* A restoring bit-by-bit division primitive.  */
1318169689Skan
1319169689Skan#define _FP_DIV_MEAT_N_loop(fs, wc, R, X, Y)				\
1320169689Skan  do {									\
1321169689Skan    int count = _FP_WFRACBITS_##fs;					\
1322169689Skan    _FP_FRAC_DECL_##wc (u);						\
1323169689Skan    _FP_FRAC_DECL_##wc (v);						\
1324169689Skan    _FP_FRAC_COPY_##wc (u, X);						\
1325169689Skan    _FP_FRAC_COPY_##wc (v, Y);						\
1326169689Skan    _FP_FRAC_SET_##wc (R, _FP_ZEROFRAC_##wc);				\
1327169689Skan    /* Normalize U and V.  */						\
1328169689Skan    _FP_FRAC_SLL_##wc (u, _FP_WFRACXBITS_##fs);				\
1329169689Skan    _FP_FRAC_SLL_##wc (v, _FP_WFRACXBITS_##fs);				\
1330169689Skan    /* First round.  Since the operands are normalized, either the	\
1331169689Skan       first or second bit will be set in the fraction.  Produce a	\
1332169689Skan       normalized result by checking which and adjusting the loop	\
1333169689Skan       count and exponent accordingly.  */				\
1334169689Skan    if (_FP_FRAC_GE_1 (u, v))						\
1335169689Skan      {									\
1336169689Skan	_FP_FRAC_SUB_##wc (u, u, v);					\
1337169689Skan	_FP_FRAC_LOW_##wc (R) |= 1;					\
1338169689Skan	count--;							\
1339169689Skan      }									\
1340169689Skan    else								\
1341169689Skan      R##_e--;								\
1342169689Skan    /* Subsequent rounds.  */						\
1343169689Skan    do {								\
1344169689Skan      int msb = (_FP_WS_TYPE) _FP_FRAC_HIGH_##wc (u) < 0;		\
1345169689Skan      _FP_FRAC_SLL_##wc (u, 1);						\
1346169689Skan      _FP_FRAC_SLL_##wc (R, 1);						\
1347169689Skan      if (msb || _FP_FRAC_GE_1 (u, v))					\
1348169689Skan	{								\
1349169689Skan	  _FP_FRAC_SUB_##wc (u, u, v);					\
1350169689Skan	  _FP_FRAC_LOW_##wc (R) |= 1;					\
1351169689Skan	}								\
1352169689Skan    } while (--count > 0);						\
1353169689Skan    /* If there's anything left in U, the result is inexact.  */	\
1354169689Skan    _FP_FRAC_LOW_##wc (R) |= !_FP_FRAC_ZEROP_##wc (u);			\
1355169689Skan  } while (0)
1356169689Skan
1357169689Skan#define _FP_DIV_MEAT_1_loop(fs, R, X, Y)  _FP_DIV_MEAT_N_loop (fs, 1, R, X, Y)
1358169689Skan#define _FP_DIV_MEAT_2_loop(fs, R, X, Y)  _FP_DIV_MEAT_N_loop (fs, 2, R, X, Y)
1359169689Skan#define _FP_DIV_MEAT_4_loop(fs, R, X, Y)  _FP_DIV_MEAT_N_loop (fs, 4, R, X, Y)
1360