1/* Software floating-point emulation.
2   Basic one-word fraction declaration and manipulation.
3   Copyright (C) 1997-2014 Free Software Foundation, Inc.
4   This file is part of the GNU C Library.
5   Contributed by Richard Henderson (rth@cygnus.com),
6		  Jakub Jelinek (jj@ultra.linux.cz),
7		  David S. Miller (davem@redhat.com) and
8		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
9
10   The GNU C Library is free software; you can redistribute it and/or
11   modify it under the terms of the GNU Lesser General Public
12   License as published by the Free Software Foundation; either
13   version 2.1 of the License, or (at your option) any later version.
14
15   In addition to the permissions in the GNU Lesser General Public
16   License, the Free Software Foundation gives you unlimited
17   permission to link the compiled version of this file into
18   combinations with other programs, and to distribute those
19   combinations without any restriction coming from the use of this
20   file.  (The Lesser General Public License restrictions do apply in
21   other respects; for example, they cover modification of the file,
22   and distribution when not linked into a combine executable.)
23
24   The GNU C Library is distributed in the hope that it will be useful,
25   but WITHOUT ANY WARRANTY; without even the implied warranty of
26   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27   Lesser General Public License for more details.
28
29   You should have received a copy of the GNU Lesser General Public
30   License along with the GNU C Library; if not, see
31   <http://www.gnu.org/licenses/>.  */
32
33#define _FP_FRAC_DECL_1(X)	_FP_W_TYPE X##_f
34#define _FP_FRAC_COPY_1(D, S)	(D##_f = S##_f)
35#define _FP_FRAC_SET_1(X, I)	(X##_f = I)
36#define _FP_FRAC_HIGH_1(X)	(X##_f)
37#define _FP_FRAC_LOW_1(X)	(X##_f)
38#define _FP_FRAC_WORD_1(X, w)	(X##_f)
39
40#define _FP_FRAC_ADDI_1(X, I)	(X##_f += I)
41#define _FP_FRAC_SLL_1(X, N)			\
42  do						\
43    {						\
44      if (__builtin_constant_p (N) && (N) == 1)	\
45	X##_f += X##_f;				\
46      else					\
47	X##_f <<= (N);				\
48    }						\
49  while (0)
50#define _FP_FRAC_SRL_1(X, N)	(X##_f >>= N)
51
52/* Right shift with sticky-lsb.  */
53#define _FP_FRAC_SRST_1(X, S, N, sz)	__FP_FRAC_SRST_1 (X##_f, S, (N), (sz))
54#define _FP_FRAC_SRS_1(X, N, sz)	__FP_FRAC_SRS_1 (X##_f, (N), (sz))
55
56#define __FP_FRAC_SRST_1(X, S, N, sz)			\
57  do							\
58    {							\
59      S = (__builtin_constant_p (N) && (N) == 1		\
60	   ? X & 1					\
61	   : (X << (_FP_W_TYPE_SIZE - (N))) != 0);	\
62      X = X >> (N);					\
63    }							\
64  while (0)
65
66#define __FP_FRAC_SRS_1(X, N, sz)				\
67  (X = (X >> (N) | (__builtin_constant_p (N) && (N) == 1	\
68		    ? X & 1					\
69		    : (X << (_FP_W_TYPE_SIZE - (N))) != 0)))
70
71#define _FP_FRAC_ADD_1(R, X, Y)	(R##_f = X##_f + Y##_f)
72#define _FP_FRAC_SUB_1(R, X, Y)	(R##_f = X##_f - Y##_f)
73#define _FP_FRAC_DEC_1(X, Y)	(X##_f -= Y##_f)
74#define _FP_FRAC_CLZ_1(z, X)	__FP_CLZ ((z), X##_f)
75
76/* Predicates.  */
77#define _FP_FRAC_NEGP_1(X)	((_FP_WS_TYPE) X##_f < 0)
78#define _FP_FRAC_ZEROP_1(X)	(X##_f == 0)
79#define _FP_FRAC_OVERP_1(fs, X)	(X##_f & _FP_OVERFLOW_##fs)
80#define _FP_FRAC_CLEAR_OVERP_1(fs, X)	(X##_f &= ~_FP_OVERFLOW_##fs)
81#define _FP_FRAC_HIGHBIT_DW_1(fs, X)	(X##_f & _FP_HIGHBIT_DW_##fs)
82#define _FP_FRAC_EQ_1(X, Y)	(X##_f == Y##_f)
83#define _FP_FRAC_GE_1(X, Y)	(X##_f >= Y##_f)
84#define _FP_FRAC_GT_1(X, Y)	(X##_f > Y##_f)
85
86#define _FP_ZEROFRAC_1		0
87#define _FP_MINFRAC_1		1
88#define _FP_MAXFRAC_1		(~(_FP_WS_TYPE) 0)
89
90/* Unpack the raw bits of a native fp value.  Do not classify or
91   normalize the data.  */
92
93#define _FP_UNPACK_RAW_1(fs, X, val)			\
94  do							\
95    {							\
96      union _FP_UNION_##fs _FP_UNPACK_RAW_1_flo;	\
97      _FP_UNPACK_RAW_1_flo.flt = (val);			\
98							\
99      X##_f = _FP_UNPACK_RAW_1_flo.bits.frac;		\
100      X##_e = _FP_UNPACK_RAW_1_flo.bits.exp;		\
101      X##_s = _FP_UNPACK_RAW_1_flo.bits.sign;		\
102    }							\
103  while (0)
104
105#define _FP_UNPACK_RAW_1_P(fs, X, val)			\
106  do							\
107    {							\
108      union _FP_UNION_##fs *_FP_UNPACK_RAW_1_P_flo	\
109	= (union _FP_UNION_##fs *) (val);		\
110							\
111      X##_f = _FP_UNPACK_RAW_1_P_flo->bits.frac;	\
112      X##_e = _FP_UNPACK_RAW_1_P_flo->bits.exp;		\
113      X##_s = _FP_UNPACK_RAW_1_P_flo->bits.sign;	\
114    }							\
115  while (0)
116
117/* Repack the raw bits of a native fp value.  */
118
119#define _FP_PACK_RAW_1(fs, val, X)		\
120  do						\
121    {						\
122      union _FP_UNION_##fs _FP_PACK_RAW_1_flo;	\
123						\
124      _FP_PACK_RAW_1_flo.bits.frac = X##_f;	\
125      _FP_PACK_RAW_1_flo.bits.exp  = X##_e;	\
126      _FP_PACK_RAW_1_flo.bits.sign = X##_s;	\
127						\
128      (val) = _FP_PACK_RAW_1_flo.flt;		\
129    }						\
130  while (0)
131
132#define _FP_PACK_RAW_1_P(fs, val, X)			\
133  do							\
134    {							\
135      union _FP_UNION_##fs *_FP_PACK_RAW_1_P_flo	\
136	= (union _FP_UNION_##fs *) (val);		\
137							\
138      _FP_PACK_RAW_1_P_flo->bits.frac = X##_f;		\
139      _FP_PACK_RAW_1_P_flo->bits.exp  = X##_e;		\
140      _FP_PACK_RAW_1_P_flo->bits.sign = X##_s;		\
141    }							\
142  while (0)
143
144
145/* Multiplication algorithms: */
146
147/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
148   multiplication immediately.  */
149
150#define _FP_MUL_MEAT_DW_1_imm(wfracbits, R, X, Y)	\
151  do							\
152    {							\
153      R##_f = X##_f * Y##_f;				\
154    }							\
155  while (0)
156
157#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y)				\
158  do									\
159    {									\
160      _FP_MUL_MEAT_DW_1_imm ((wfracbits), R, X, Y);			\
161      /* Normalize since we know where the msb of the multiplicands	\
162	 were (bit B), we know that the msb of the of the product is	\
163	 at either 2B or 2B-1.  */					\
164      _FP_FRAC_SRS_1 (R, (wfracbits)-1, 2*(wfracbits));			\
165    }									\
166  while (0)
167
168/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
169
170#define _FP_MUL_MEAT_DW_1_wide(wfracbits, R, X, Y, doit)	\
171  do								\
172    {								\
173      doit (R##_f1, R##_f0, X##_f, Y##_f);			\
174    }								\
175  while (0)
176
177#define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit)			\
178  do									\
179    {									\
180      _FP_FRAC_DECL_2 (_FP_MUL_MEAT_1_wide_Z);				\
181      _FP_MUL_MEAT_DW_1_wide ((wfracbits), _FP_MUL_MEAT_1_wide_Z,	\
182			      X, Y, doit);				\
183      /* Normalize since we know where the msb of the multiplicands	\
184	 were (bit B), we know that the msb of the of the product is	\
185	 at either 2B or 2B-1.  */					\
186      _FP_FRAC_SRS_2 (_FP_MUL_MEAT_1_wide_Z, (wfracbits)-1,		\
187		      2*(wfracbits));					\
188      R##_f = _FP_MUL_MEAT_1_wide_Z_f0;					\
189    }									\
190  while (0)
191
192/* Finally, a simple widening multiply algorithm.  What fun!  */
193
194#define _FP_MUL_MEAT_DW_1_hard(wfracbits, R, X, Y)			\
195  do									\
196    {									\
197      _FP_W_TYPE _FP_MUL_MEAT_DW_1_hard_xh, _FP_MUL_MEAT_DW_1_hard_xl;	\
198      _FP_W_TYPE _FP_MUL_MEAT_DW_1_hard_yh, _FP_MUL_MEAT_DW_1_hard_yl;	\
199      _FP_FRAC_DECL_2 (_FP_MUL_MEAT_DW_1_hard_a);			\
200									\
201      /* Split the words in half.  */					\
202      _FP_MUL_MEAT_DW_1_hard_xh = X##_f >> (_FP_W_TYPE_SIZE/2);		\
203      _FP_MUL_MEAT_DW_1_hard_xl						\
204	= X##_f & (((_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2)) - 1);	\
205      _FP_MUL_MEAT_DW_1_hard_yh = Y##_f >> (_FP_W_TYPE_SIZE/2);		\
206      _FP_MUL_MEAT_DW_1_hard_yl						\
207	= Y##_f & (((_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2)) - 1);	\
208									\
209      /* Multiply the pieces.  */					\
210      R##_f0 = _FP_MUL_MEAT_DW_1_hard_xl * _FP_MUL_MEAT_DW_1_hard_yl;	\
211      _FP_MUL_MEAT_DW_1_hard_a_f0					\
212	= _FP_MUL_MEAT_DW_1_hard_xh * _FP_MUL_MEAT_DW_1_hard_yl;	\
213      _FP_MUL_MEAT_DW_1_hard_a_f1					\
214	= _FP_MUL_MEAT_DW_1_hard_xl * _FP_MUL_MEAT_DW_1_hard_yh;	\
215      R##_f1 = _FP_MUL_MEAT_DW_1_hard_xh * _FP_MUL_MEAT_DW_1_hard_yh;	\
216									\
217      /* Reassemble into two full words.  */				\
218      if ((_FP_MUL_MEAT_DW_1_hard_a_f0 += _FP_MUL_MEAT_DW_1_hard_a_f1)	\
219	  < _FP_MUL_MEAT_DW_1_hard_a_f1)				\
220	R##_f1 += (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2);		\
221      _FP_MUL_MEAT_DW_1_hard_a_f1					\
222	= _FP_MUL_MEAT_DW_1_hard_a_f0 >> (_FP_W_TYPE_SIZE/2);		\
223      _FP_MUL_MEAT_DW_1_hard_a_f0					\
224	= _FP_MUL_MEAT_DW_1_hard_a_f0 << (_FP_W_TYPE_SIZE/2);		\
225      _FP_FRAC_ADD_2 (R, R, _FP_MUL_MEAT_DW_1_hard_a);			\
226    }									\
227  while (0)
228
229#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y)			\
230  do								\
231    {								\
232      _FP_FRAC_DECL_2 (_FP_MUL_MEAT_1_hard_z);			\
233      _FP_MUL_MEAT_DW_1_hard ((wfracbits),			\
234			      _FP_MUL_MEAT_1_hard_z, X, Y);	\
235								\
236      /* Normalize.  */						\
237      _FP_FRAC_SRS_2 (_FP_MUL_MEAT_1_hard_z,			\
238		      (wfracbits) - 1, 2*(wfracbits));		\
239      R##_f = _FP_MUL_MEAT_1_hard_z_f0;				\
240    }								\
241  while (0)
242
243
244/* Division algorithms: */
245
246/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
247   division immediately.  Give this macro either _FP_DIV_HELP_imm for
248   C primitives or _FP_DIV_HELP_ldiv for the ISO function.  Which you
249   choose will depend on what the compiler does with divrem4.  */
250
251#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit)				\
252  do									\
253    {									\
254      _FP_W_TYPE _FP_DIV_MEAT_1_imm_q, _FP_DIV_MEAT_1_imm_r;		\
255      X##_f <<= (X##_f < Y##_f						\
256		 ? R##_e--, _FP_WFRACBITS_##fs				\
257		 : _FP_WFRACBITS_##fs - 1);				\
258      doit (_FP_DIV_MEAT_1_imm_q, _FP_DIV_MEAT_1_imm_r, X##_f, Y##_f);	\
259      R##_f = _FP_DIV_MEAT_1_imm_q | (_FP_DIV_MEAT_1_imm_r != 0);	\
260    }									\
261  while (0)
262
263/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
264   that may be useful in this situation.  This first is for a primitive
265   that requires normalization, the second for one that does not.  Look
266   for UDIV_NEEDS_NORMALIZATION to tell which your machine needs.  */
267
268#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y)				\
269  do									\
270    {									\
271      _FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_nh;				\
272      _FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_nl;				\
273      _FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_q;				\
274      _FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_r;				\
275      _FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_y;				\
276									\
277      /* Normalize Y -- i.e. make the most significant bit set.  */	\
278      _FP_DIV_MEAT_1_udiv_norm_y = Y##_f << _FP_WFRACXBITS_##fs;	\
279									\
280      /* Shift X op correspondingly high, that is, up one full word.  */ \
281      if (X##_f < Y##_f)						\
282	{								\
283	  R##_e--;							\
284	  _FP_DIV_MEAT_1_udiv_norm_nl = 0;				\
285	  _FP_DIV_MEAT_1_udiv_norm_nh = X##_f;				\
286	}								\
287      else								\
288	{								\
289	  _FP_DIV_MEAT_1_udiv_norm_nl = X##_f << (_FP_W_TYPE_SIZE - 1);	\
290	  _FP_DIV_MEAT_1_udiv_norm_nh = X##_f >> 1;			\
291	}								\
292									\
293      udiv_qrnnd (_FP_DIV_MEAT_1_udiv_norm_q,				\
294		  _FP_DIV_MEAT_1_udiv_norm_r,				\
295		  _FP_DIV_MEAT_1_udiv_norm_nh,				\
296		  _FP_DIV_MEAT_1_udiv_norm_nl,				\
297		  _FP_DIV_MEAT_1_udiv_norm_y);				\
298      R##_f = (_FP_DIV_MEAT_1_udiv_norm_q				\
299	       | (_FP_DIV_MEAT_1_udiv_norm_r != 0));			\
300    }									\
301  while (0)
302
303#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y)				\
304  do									\
305    {									\
306      _FP_W_TYPE _FP_DIV_MEAT_1_udiv_nh, _FP_DIV_MEAT_1_udiv_nl;	\
307      _FP_W_TYPE _FP_DIV_MEAT_1_udiv_q, _FP_DIV_MEAT_1_udiv_r;		\
308      if (X##_f < Y##_f)						\
309	{								\
310	  R##_e--;							\
311	  _FP_DIV_MEAT_1_udiv_nl = X##_f << _FP_WFRACBITS_##fs;		\
312	  _FP_DIV_MEAT_1_udiv_nh = X##_f >> _FP_WFRACXBITS_##fs;	\
313	}								\
314      else								\
315	{								\
316	  _FP_DIV_MEAT_1_udiv_nl = X##_f << (_FP_WFRACBITS_##fs - 1);	\
317	  _FP_DIV_MEAT_1_udiv_nh = X##_f >> (_FP_WFRACXBITS_##fs + 1);	\
318	}								\
319      udiv_qrnnd (_FP_DIV_MEAT_1_udiv_q, _FP_DIV_MEAT_1_udiv_r,		\
320		  _FP_DIV_MEAT_1_udiv_nh, _FP_DIV_MEAT_1_udiv_nl,	\
321		  Y##_f);						\
322      R##_f = _FP_DIV_MEAT_1_udiv_q | (_FP_DIV_MEAT_1_udiv_r != 0);	\
323    }									\
324  while (0)
325
326
327/* Square root algorithms:
328   We have just one right now, maybe Newton approximation
329   should be added for those machines where division is fast.  */
330
331#define _FP_SQRT_MEAT_1(R, S, T, X, q)		\
332  do						\
333    {						\
334      while ((q) != _FP_WORK_ROUND)		\
335	{					\
336	  T##_f = S##_f + (q);			\
337	  if (T##_f <= X##_f)			\
338	    {					\
339	      S##_f = T##_f + (q);		\
340	      X##_f -= T##_f;			\
341	      R##_f += (q);			\
342	    }					\
343	  _FP_FRAC_SLL_1 (X, 1);		\
344	  (q) >>= 1;				\
345	}					\
346      if (X##_f)				\
347	{					\
348	  if (S##_f < X##_f)			\
349	    R##_f |= _FP_WORK_ROUND;		\
350	  R##_f |= _FP_WORK_STICKY;		\
351	}					\
352    }						\
353  while (0)
354
355/* Assembly/disassembly for converting to/from integral types.
356   No shifting or overflow handled here.  */
357
358#define _FP_FRAC_ASSEMBLE_1(r, X, rsize)	((r) = X##_f)
359#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize)	(X##_f = (r))
360
361
362/* Convert FP values between word sizes.  */
363
364#define _FP_FRAC_COPY_1_1(D, S)		(D##_f = S##_f)
365