1169689Skan/* Software floating-point emulation.
2169689Skan   Basic one-word fraction declaration and manipulation.
3169689Skan   Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
4169689Skan   This file is part of the GNU C Library.
5169689Skan   Contributed by Richard Henderson (rth@cygnus.com),
6169689Skan		  Jakub Jelinek (jj@ultra.linux.cz),
7169689Skan		  David S. Miller (davem@redhat.com) and
8169689Skan		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
9169689Skan
10169689Skan   The GNU C Library is free software; you can redistribute it and/or
11169689Skan   modify it under the terms of the GNU Lesser General Public
12169689Skan   License as published by the Free Software Foundation; either
13169689Skan   version 2.1 of the License, or (at your option) any later version.
14169689Skan
15169689Skan   In addition to the permissions in the GNU Lesser General Public
16169689Skan   License, the Free Software Foundation gives you unlimited
17169689Skan   permission to link the compiled version of this file into
18169689Skan   combinations with other programs, and to distribute those
19169689Skan   combinations without any restriction coming from the use of this
20169689Skan   file.  (The Lesser General Public License restrictions do apply in
21169689Skan   other respects; for example, they cover modification of the file,
22169689Skan   and distribution when not linked into a combine executable.)
23169689Skan
24169689Skan   The GNU C Library is distributed in the hope that it will be useful,
25169689Skan   but WITHOUT ANY WARRANTY; without even the implied warranty of
26169689Skan   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27169689Skan   Lesser General Public License for more details.
28169689Skan
29169689Skan   You should have received a copy of the GNU Lesser General Public
30169689Skan   License along with the GNU C Library; if not, write to the Free
31169689Skan   Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
32169689Skan   MA 02110-1301, USA.  */
33169689Skan
34169689Skan#define _FP_FRAC_DECL_1(X)	_FP_W_TYPE X##_f
35169689Skan#define _FP_FRAC_COPY_1(D,S)	(D##_f = S##_f)
36169689Skan#define _FP_FRAC_SET_1(X,I)	(X##_f = I)
37169689Skan#define _FP_FRAC_HIGH_1(X)	(X##_f)
38169689Skan#define _FP_FRAC_LOW_1(X)	(X##_f)
39169689Skan#define _FP_FRAC_WORD_1(X,w)	(X##_f)
40169689Skan
41169689Skan#define _FP_FRAC_ADDI_1(X,I)	(X##_f += I)
42169689Skan#define _FP_FRAC_SLL_1(X,N)			\
43169689Skan  do {						\
44169689Skan    if (__builtin_constant_p(N) && (N) == 1)	\
45169689Skan      X##_f += X##_f;				\
46169689Skan    else					\
47169689Skan      X##_f <<= (N);				\
48169689Skan  } while (0)
49169689Skan#define _FP_FRAC_SRL_1(X,N)	(X##_f >>= N)
50169689Skan
51169689Skan/* Right shift with sticky-lsb.  */
52169689Skan#define _FP_FRAC_SRST_1(X,S,N,sz)	__FP_FRAC_SRST_1(X##_f, S, N, sz)
53169689Skan#define _FP_FRAC_SRS_1(X,N,sz)	__FP_FRAC_SRS_1(X##_f, N, sz)
54169689Skan
55169689Skan#define __FP_FRAC_SRST_1(X,S,N,sz)			\
56169689Skando {							\
57169689Skan  S = (__builtin_constant_p(N) && (N) == 1		\
58169689Skan       ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0);	\
59169689Skan  X = X >> (N);						\
60169689Skan} while (0)
61169689Skan
62169689Skan#define __FP_FRAC_SRS_1(X,N,sz)						\
63169689Skan   (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1		\
64169689Skan		     ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0)))
65169689Skan
66169689Skan#define _FP_FRAC_ADD_1(R,X,Y)	(R##_f = X##_f + Y##_f)
67169689Skan#define _FP_FRAC_SUB_1(R,X,Y)	(R##_f = X##_f - Y##_f)
68169689Skan#define _FP_FRAC_DEC_1(X,Y)	(X##_f -= Y##_f)
69169689Skan#define _FP_FRAC_CLZ_1(z, X)	__FP_CLZ(z, X##_f)
70169689Skan
71169689Skan/* Predicates */
72169689Skan#define _FP_FRAC_NEGP_1(X)	((_FP_WS_TYPE)X##_f < 0)
73169689Skan#define _FP_FRAC_ZEROP_1(X)	(X##_f == 0)
74169689Skan#define _FP_FRAC_OVERP_1(fs,X)	(X##_f & _FP_OVERFLOW_##fs)
75169689Skan#define _FP_FRAC_CLEAR_OVERP_1(fs,X)	(X##_f &= ~_FP_OVERFLOW_##fs)
76169689Skan#define _FP_FRAC_EQ_1(X, Y)	(X##_f == Y##_f)
77169689Skan#define _FP_FRAC_GE_1(X, Y)	(X##_f >= Y##_f)
78169689Skan#define _FP_FRAC_GT_1(X, Y)	(X##_f > Y##_f)
79169689Skan
80169689Skan#define _FP_ZEROFRAC_1		0
81169689Skan#define _FP_MINFRAC_1		1
82169689Skan#define _FP_MAXFRAC_1		(~(_FP_WS_TYPE)0)
83169689Skan
84169689Skan/*
85169689Skan * Unpack the raw bits of a native fp value.  Do not classify or
86169689Skan * normalize the data.
87169689Skan */
88169689Skan
89169689Skan#define _FP_UNPACK_RAW_1(fs, X, val)				\
90169689Skan  do {								\
91169689Skan    union _FP_UNION_##fs _flo; _flo.flt = (val);		\
92169689Skan								\
93169689Skan    X##_f = _flo.bits.frac;					\
94169689Skan    X##_e = _flo.bits.exp;					\
95169689Skan    X##_s = _flo.bits.sign;					\
96169689Skan  } while (0)
97169689Skan
98169689Skan#define _FP_UNPACK_RAW_1_P(fs, X, val)				\
99169689Skan  do {								\
100169689Skan    union _FP_UNION_##fs *_flo =				\
101169689Skan      (union _FP_UNION_##fs *)(val);				\
102169689Skan								\
103169689Skan    X##_f = _flo->bits.frac;					\
104169689Skan    X##_e = _flo->bits.exp;					\
105169689Skan    X##_s = _flo->bits.sign;					\
106169689Skan  } while (0)
107169689Skan
108169689Skan/*
109169689Skan * Repack the raw bits of a native fp value.
110169689Skan */
111169689Skan
112169689Skan#define _FP_PACK_RAW_1(fs, val, X)				\
113169689Skan  do {								\
114169689Skan    union _FP_UNION_##fs _flo;					\
115169689Skan								\
116169689Skan    _flo.bits.frac = X##_f;					\
117169689Skan    _flo.bits.exp  = X##_e;					\
118169689Skan    _flo.bits.sign = X##_s;					\
119169689Skan								\
120169689Skan    (val) = _flo.flt;						\
121169689Skan  } while (0)
122169689Skan
123169689Skan#define _FP_PACK_RAW_1_P(fs, val, X)				\
124169689Skan  do {								\
125169689Skan    union _FP_UNION_##fs *_flo =				\
126169689Skan      (union _FP_UNION_##fs *)(val);				\
127169689Skan								\
128169689Skan    _flo->bits.frac = X##_f;					\
129169689Skan    _flo->bits.exp  = X##_e;					\
130169689Skan    _flo->bits.sign = X##_s;					\
131169689Skan  } while (0)
132169689Skan
133169689Skan
134169689Skan/*
135169689Skan * Multiplication algorithms:
136169689Skan */
137169689Skan
138169689Skan/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
139169689Skan   multiplication immediately.  */
140169689Skan
141169689Skan#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y)				\
142169689Skan  do {									\
143169689Skan    R##_f = X##_f * Y##_f;						\
144169689Skan    /* Normalize since we know where the msb of the multiplicands	\
145169689Skan       were (bit B), we know that the msb of the of the product is	\
146169689Skan       at either 2B or 2B-1.  */					\
147169689Skan    _FP_FRAC_SRS_1(R, wfracbits-1, 2*wfracbits);			\
148169689Skan  } while (0)
149169689Skan
150169689Skan/* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
151169689Skan
152169689Skan#define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit)			\
153169689Skan  do {									\
154169689Skan    _FP_W_TYPE _Z_f0, _Z_f1;						\
155169689Skan    doit(_Z_f1, _Z_f0, X##_f, Y##_f);					\
156169689Skan    /* Normalize since we know where the msb of the multiplicands	\
157169689Skan       were (bit B), we know that the msb of the of the product is	\
158169689Skan       at either 2B or 2B-1.  */					\
159169689Skan    _FP_FRAC_SRS_2(_Z, wfracbits-1, 2*wfracbits);			\
160169689Skan    R##_f = _Z_f0;							\
161169689Skan  } while (0)
162169689Skan
163169689Skan/* Finally, a simple widening multiply algorithm.  What fun!  */
164169689Skan
165169689Skan#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y)				\
166169689Skan  do {									\
167169689Skan    _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1;		\
168169689Skan									\
169169689Skan    /* split the words in half */					\
170169689Skan    _xh = X##_f >> (_FP_W_TYPE_SIZE/2);					\
171169689Skan    _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1);		\
172169689Skan    _yh = Y##_f >> (_FP_W_TYPE_SIZE/2);					\
173169689Skan    _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1);		\
174169689Skan									\
175169689Skan    /* multiply the pieces */						\
176169689Skan    _z_f0 = _xl * _yl;							\
177169689Skan    _a_f0 = _xh * _yl;							\
178169689Skan    _a_f1 = _xl * _yh;							\
179169689Skan    _z_f1 = _xh * _yh;							\
180169689Skan									\
181169689Skan    /* reassemble into two full words */				\
182169689Skan    if ((_a_f0 += _a_f1) < _a_f1)					\
183169689Skan      _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2);			\
184169689Skan    _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2);				\
185169689Skan    _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2);				\
186169689Skan    _FP_FRAC_ADD_2(_z, _z, _a);						\
187169689Skan									\
188169689Skan    /* normalize */							\
189169689Skan    _FP_FRAC_SRS_2(_z, wfracbits - 1, 2*wfracbits);			\
190169689Skan    R##_f = _z_f0;							\
191169689Skan  } while (0)
192169689Skan
193169689Skan
194169689Skan/*
195169689Skan * Division algorithms:
196169689Skan */
197169689Skan
198169689Skan/* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
199169689Skan   division immediately.  Give this macro either _FP_DIV_HELP_imm for
200169689Skan   C primitives or _FP_DIV_HELP_ldiv for the ISO function.  Which you
201169689Skan   choose will depend on what the compiler does with divrem4.  */
202169689Skan
203169689Skan#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit)		\
204169689Skan  do {							\
205169689Skan    _FP_W_TYPE _q, _r;					\
206169689Skan    X##_f <<= (X##_f < Y##_f				\
207169689Skan	       ? R##_e--, _FP_WFRACBITS_##fs		\
208169689Skan	       : _FP_WFRACBITS_##fs - 1);		\
209169689Skan    doit(_q, _r, X##_f, Y##_f);				\
210169689Skan    R##_f = _q | (_r != 0);				\
211169689Skan  } while (0)
212169689Skan
213169689Skan/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
214169689Skan   that may be useful in this situation.  This first is for a primitive
215169689Skan   that requires normalization, the second for one that does not.  Look
216169689Skan   for UDIV_NEEDS_NORMALIZATION to tell which your machine needs.  */
217169689Skan
218169689Skan#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y)				\
219169689Skan  do {									\
220169689Skan    _FP_W_TYPE _nh, _nl, _q, _r, _y;					\
221169689Skan									\
222169689Skan    /* Normalize Y -- i.e. make the most significant bit set.  */	\
223169689Skan    _y = Y##_f << _FP_WFRACXBITS_##fs;					\
224169689Skan									\
225169689Skan    /* Shift X op correspondingly high, that is, up one full word.  */	\
226169689Skan    if (X##_f < Y##_f)							\
227169689Skan      {									\
228169689Skan	R##_e--;							\
229169689Skan	_nl = 0;							\
230169689Skan	_nh = X##_f;							\
231169689Skan      }									\
232169689Skan    else								\
233169689Skan      {									\
234169689Skan	_nl = X##_f << (_FP_W_TYPE_SIZE - 1);				\
235169689Skan	_nh = X##_f >> 1;						\
236169689Skan      }									\
237169689Skan    									\
238169689Skan    udiv_qrnnd(_q, _r, _nh, _nl, _y);					\
239169689Skan    R##_f = _q | (_r != 0);						\
240169689Skan  } while (0)
241169689Skan
242169689Skan#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y)		\
243169689Skan  do {							\
244169689Skan    _FP_W_TYPE _nh, _nl, _q, _r;			\
245169689Skan    if (X##_f < Y##_f)					\
246169689Skan      {							\
247169689Skan	R##_e--;					\
248169689Skan	_nl = X##_f << _FP_WFRACBITS_##fs;		\
249169689Skan	_nh = X##_f >> _FP_WFRACXBITS_##fs;		\
250169689Skan      }							\
251169689Skan    else						\
252169689Skan      {							\
253169689Skan	_nl = X##_f << (_FP_WFRACBITS_##fs - 1);	\
254169689Skan	_nh = X##_f >> (_FP_WFRACXBITS_##fs + 1);	\
255169689Skan      }							\
256169689Skan    udiv_qrnnd(_q, _r, _nh, _nl, Y##_f);		\
257169689Skan    R##_f = _q | (_r != 0);				\
258169689Skan  } while (0)
259169689Skan
260169689Skan
261169689Skan/*
262169689Skan * Square root algorithms:
263169689Skan * We have just one right now, maybe Newton approximation
264169689Skan * should be added for those machines where division is fast.
265169689Skan */
266169689Skan
267169689Skan#define _FP_SQRT_MEAT_1(R, S, T, X, q)			\
268169689Skan  do {							\
269169689Skan    while (q != _FP_WORK_ROUND)				\
270169689Skan      {							\
271169689Skan        T##_f = S##_f + q;				\
272169689Skan        if (T##_f <= X##_f)				\
273169689Skan          {						\
274169689Skan            S##_f = T##_f + q;				\
275169689Skan            X##_f -= T##_f;				\
276169689Skan            R##_f += q;					\
277169689Skan          }						\
278169689Skan        _FP_FRAC_SLL_1(X, 1);				\
279169689Skan        q >>= 1;					\
280169689Skan      }							\
281169689Skan    if (X##_f)						\
282169689Skan      {							\
283169689Skan	if (S##_f < X##_f)				\
284169689Skan	  R##_f |= _FP_WORK_ROUND;			\
285169689Skan	R##_f |= _FP_WORK_STICKY;			\
286169689Skan      }							\
287169689Skan  } while (0)
288169689Skan
289169689Skan/*
290169689Skan * Assembly/disassembly for converting to/from integral types.
291169689Skan * No shifting or overflow handled here.
292169689Skan */
293169689Skan
294169689Skan#define _FP_FRAC_ASSEMBLE_1(r, X, rsize)	(r = X##_f)
295169689Skan#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize)	(X##_f = r)
296169689Skan
297169689Skan
298169689Skan/*
299169689Skan * Convert FP values between word sizes
300169689Skan */
301169689Skan
302169689Skan#define _FP_FRAC_COPY_1_1(D, S)		(D##_f = S##_f)
303