1169689Skan/* Software floating-point emulation.
2169689Skan   Definitions for IEEE Double Precision
3171825Skan   Copyright (C) 1997,1998,1999,2006,2007 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#if _FP_W_TYPE_SIZE < 32
35169689Skan#error "Here's a nickel kid.  Go buy yourself a real computer."
36169689Skan#endif
37169689Skan
38169689Skan#if _FP_W_TYPE_SIZE < 64
39169689Skan#define _FP_FRACTBITS_D		(2 * _FP_W_TYPE_SIZE)
40169689Skan#else
41169689Skan#define _FP_FRACTBITS_D		_FP_W_TYPE_SIZE
42169689Skan#endif
43169689Skan
44169689Skan#define _FP_FRACBITS_D		53
45169689Skan#define _FP_FRACXBITS_D		(_FP_FRACTBITS_D - _FP_FRACBITS_D)
46169689Skan#define _FP_WFRACBITS_D		(_FP_WORKBITS + _FP_FRACBITS_D)
47169689Skan#define _FP_WFRACXBITS_D	(_FP_FRACTBITS_D - _FP_WFRACBITS_D)
48169689Skan#define _FP_EXPBITS_D		11
49169689Skan#define _FP_EXPBIAS_D		1023
50169689Skan#define _FP_EXPMAX_D		2047
51169689Skan
52169689Skan#define _FP_QNANBIT_D		\
53169689Skan	((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE)
54169689Skan#define _FP_QNANBIT_SH_D		\
55169689Skan	((_FP_W_TYPE)1 << (_FP_FRACBITS_D-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
56169689Skan#define _FP_IMPLBIT_D		\
57169689Skan	((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE)
58169689Skan#define _FP_IMPLBIT_SH_D		\
59169689Skan	((_FP_W_TYPE)1 << (_FP_FRACBITS_D-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
60169689Skan#define _FP_OVERFLOW_D		\
61169689Skan	((_FP_W_TYPE)1 << _FP_WFRACBITS_D % _FP_W_TYPE_SIZE)
62169689Skan
63169689Skantypedef float DFtype __attribute__((mode(DF)));
64169689Skan
65169689Skan#if _FP_W_TYPE_SIZE < 64
66169689Skan
67169689Skanunion _FP_UNION_D
68169689Skan{
69169689Skan  DFtype flt;
70169689Skan  struct {
71169689Skan#if __BYTE_ORDER == __BIG_ENDIAN
72169689Skan    unsigned sign  : 1;
73169689Skan    unsigned exp   : _FP_EXPBITS_D;
74169689Skan    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
75169689Skan    unsigned frac0 : _FP_W_TYPE_SIZE;
76169689Skan#else
77169689Skan    unsigned frac0 : _FP_W_TYPE_SIZE;
78169689Skan    unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
79169689Skan    unsigned exp   : _FP_EXPBITS_D;
80169689Skan    unsigned sign  : 1;
81169689Skan#endif
82169689Skan  } bits __attribute__((packed));
83169689Skan};
84169689Skan
85169689Skan#define FP_DECL_D(X)		_FP_DECL(2,X)
86169689Skan#define FP_UNPACK_RAW_D(X,val)	_FP_UNPACK_RAW_2(D,X,val)
87169689Skan#define FP_UNPACK_RAW_DP(X,val)	_FP_UNPACK_RAW_2_P(D,X,val)
88169689Skan#define FP_PACK_RAW_D(val,X)	_FP_PACK_RAW_2(D,val,X)
89169689Skan#define FP_PACK_RAW_DP(val,X)		\
90169689Skan  do {					\
91169689Skan    if (!FP_INHIBIT_RESULTS)		\
92169689Skan      _FP_PACK_RAW_2_P(D,val,X);	\
93169689Skan  } while (0)
94169689Skan
95169689Skan#define FP_UNPACK_D(X,val)		\
96169689Skan  do {					\
97169689Skan    _FP_UNPACK_RAW_2(D,X,val);		\
98169689Skan    _FP_UNPACK_CANONICAL(D,2,X);	\
99169689Skan  } while (0)
100169689Skan
101169689Skan#define FP_UNPACK_DP(X,val)		\
102169689Skan  do {					\
103169689Skan    _FP_UNPACK_RAW_2_P(D,X,val);	\
104169689Skan    _FP_UNPACK_CANONICAL(D,2,X);	\
105169689Skan  } while (0)
106169689Skan
107169689Skan#define FP_UNPACK_SEMIRAW_D(X,val)	\
108169689Skan  do {					\
109169689Skan    _FP_UNPACK_RAW_2(D,X,val);		\
110169689Skan    _FP_UNPACK_SEMIRAW(D,2,X);		\
111169689Skan  } while (0)
112169689Skan
113169689Skan#define FP_UNPACK_SEMIRAW_DP(X,val)	\
114169689Skan  do {					\
115169689Skan    _FP_UNPACK_RAW_2_P(D,X,val);	\
116169689Skan    _FP_UNPACK_SEMIRAW(D,2,X);		\
117169689Skan  } while (0)
118169689Skan
119169689Skan#define FP_PACK_D(val,X)		\
120169689Skan  do {					\
121169689Skan    _FP_PACK_CANONICAL(D,2,X);		\
122169689Skan    _FP_PACK_RAW_2(D,val,X);		\
123169689Skan  } while (0)
124169689Skan
125169689Skan#define FP_PACK_DP(val,X)		\
126169689Skan  do {					\
127169689Skan    _FP_PACK_CANONICAL(D,2,X);		\
128169689Skan    if (!FP_INHIBIT_RESULTS)		\
129169689Skan      _FP_PACK_RAW_2_P(D,val,X);	\
130169689Skan  } while (0)
131169689Skan
132169689Skan#define FP_PACK_SEMIRAW_D(val,X)	\
133169689Skan  do {					\
134169689Skan    _FP_PACK_SEMIRAW(D,2,X);		\
135169689Skan    _FP_PACK_RAW_2(D,val,X);		\
136169689Skan  } while (0)
137169689Skan
138169689Skan#define FP_PACK_SEMIRAW_DP(val,X)	\
139169689Skan  do {					\
140169689Skan    _FP_PACK_SEMIRAW(D,2,X);		\
141169689Skan    if (!FP_INHIBIT_RESULTS)		\
142169689Skan      _FP_PACK_RAW_2_P(D,val,X);	\
143169689Skan  } while (0)
144169689Skan
145169689Skan#define FP_ISSIGNAN_D(X)		_FP_ISSIGNAN(D,2,X)
146169689Skan#define FP_NEG_D(R,X)			_FP_NEG(D,2,R,X)
147169689Skan#define FP_ADD_D(R,X,Y)			_FP_ADD(D,2,R,X,Y)
148169689Skan#define FP_SUB_D(R,X,Y)			_FP_SUB(D,2,R,X,Y)
149169689Skan#define FP_MUL_D(R,X,Y)			_FP_MUL(D,2,R,X,Y)
150169689Skan#define FP_DIV_D(R,X,Y)			_FP_DIV(D,2,R,X,Y)
151169689Skan#define FP_SQRT_D(R,X)			_FP_SQRT(D,2,R,X)
152169689Skan#define _FP_SQRT_MEAT_D(R,S,T,X,Q)	_FP_SQRT_MEAT_2(R,S,T,X,Q)
153169689Skan
154169689Skan#define FP_CMP_D(r,X,Y,un)	_FP_CMP(D,2,r,X,Y,un)
155169689Skan#define FP_CMP_EQ_D(r,X,Y)	_FP_CMP_EQ(D,2,r,X,Y)
156169689Skan#define FP_CMP_UNORD_D(r,X,Y)	_FP_CMP_UNORD(D,2,r,X,Y)
157169689Skan
158169689Skan#define FP_TO_INT_D(r,X,rsz,rsg)	_FP_TO_INT(D,2,r,X,rsz,rsg)
159169689Skan#define FP_FROM_INT_D(X,r,rs,rt)	_FP_FROM_INT(D,2,X,r,rs,rt)
160169689Skan
161169689Skan#define _FP_FRAC_HIGH_D(X)	_FP_FRAC_HIGH_2(X)
162169689Skan#define _FP_FRAC_HIGH_RAW_D(X)	_FP_FRAC_HIGH_2(X)
163169689Skan
164169689Skan#else
165169689Skan
166169689Skanunion _FP_UNION_D
167169689Skan{
168169689Skan  DFtype flt;
169169689Skan  struct {
170169689Skan#if __BYTE_ORDER == __BIG_ENDIAN
171171825Skan    unsigned sign   : 1;
172171825Skan    unsigned exp    : _FP_EXPBITS_D;
173171825Skan    _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
174169689Skan#else
175171825Skan    _FP_W_TYPE frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
176171825Skan    unsigned exp    : _FP_EXPBITS_D;
177171825Skan    unsigned sign   : 1;
178169689Skan#endif
179169689Skan  } bits __attribute__((packed));
180169689Skan};
181169689Skan
182169689Skan#define FP_DECL_D(X)		_FP_DECL(1,X)
183169689Skan#define FP_UNPACK_RAW_D(X,val)	_FP_UNPACK_RAW_1(D,X,val)
184169689Skan#define FP_UNPACK_RAW_DP(X,val)	_FP_UNPACK_RAW_1_P(D,X,val)
185169689Skan#define FP_PACK_RAW_D(val,X)	_FP_PACK_RAW_1(D,val,X)
186169689Skan#define FP_PACK_RAW_DP(val,X)		\
187169689Skan  do {					\
188169689Skan    if (!FP_INHIBIT_RESULTS)		\
189169689Skan      _FP_PACK_RAW_1_P(D,val,X);	\
190169689Skan  } while (0)
191169689Skan
192169689Skan#define FP_UNPACK_D(X,val)		\
193169689Skan  do {					\
194169689Skan    _FP_UNPACK_RAW_1(D,X,val);		\
195169689Skan    _FP_UNPACK_CANONICAL(D,1,X);	\
196169689Skan  } while (0)
197169689Skan
198169689Skan#define FP_UNPACK_DP(X,val)		\
199169689Skan  do {					\
200169689Skan    _FP_UNPACK_RAW_1_P(D,X,val);	\
201169689Skan    _FP_UNPACK_CANONICAL(D,1,X);	\
202169689Skan  } while (0)
203169689Skan
204169689Skan#define FP_UNPACK_SEMIRAW_D(X,val)	\
205169689Skan  do {					\
206169689Skan    _FP_UNPACK_RAW_2(1,X,val);		\
207169689Skan    _FP_UNPACK_SEMIRAW(D,1,X);		\
208169689Skan  } while (0)
209169689Skan
210169689Skan#define FP_UNPACK_SEMIRAW_DP(X,val)	\
211169689Skan  do {					\
212169689Skan    _FP_UNPACK_RAW_2_P(1,X,val);	\
213169689Skan    _FP_UNPACK_SEMIRAW(D,1,X);		\
214169689Skan  } while (0)
215169689Skan
216169689Skan#define FP_PACK_D(val,X)		\
217169689Skan  do {					\
218169689Skan    _FP_PACK_CANONICAL(D,1,X);		\
219169689Skan    _FP_PACK_RAW_1(D,val,X);		\
220169689Skan  } while (0)
221169689Skan
222169689Skan#define FP_PACK_DP(val,X)		\
223169689Skan  do {					\
224169689Skan    _FP_PACK_CANONICAL(D,1,X);		\
225169689Skan    if (!FP_INHIBIT_RESULTS)		\
226169689Skan      _FP_PACK_RAW_1_P(D,val,X);	\
227169689Skan  } while (0)
228169689Skan
229169689Skan#define FP_PACK_SEMIRAW_D(val,X)	\
230169689Skan  do {					\
231169689Skan    _FP_PACK_SEMIRAW(D,1,X);		\
232169689Skan    _FP_PACK_RAW_1(D,val,X);		\
233169689Skan  } while (0)
234169689Skan
235169689Skan#define FP_PACK_SEMIRAW_DP(val,X)	\
236169689Skan  do {					\
237169689Skan    _FP_PACK_SEMIRAW(D,1,X);		\
238169689Skan    if (!FP_INHIBIT_RESULTS)		\
239169689Skan      _FP_PACK_RAW_1_P(D,val,X);	\
240169689Skan  } while (0)
241169689Skan
242169689Skan#define FP_ISSIGNAN_D(X)		_FP_ISSIGNAN(D,1,X)
243169689Skan#define FP_NEG_D(R,X)			_FP_NEG(D,1,R,X)
244169689Skan#define FP_ADD_D(R,X,Y)			_FP_ADD(D,1,R,X,Y)
245169689Skan#define FP_SUB_D(R,X,Y)			_FP_SUB(D,1,R,X,Y)
246169689Skan#define FP_MUL_D(R,X,Y)			_FP_MUL(D,1,R,X,Y)
247169689Skan#define FP_DIV_D(R,X,Y)			_FP_DIV(D,1,R,X,Y)
248169689Skan#define FP_SQRT_D(R,X)			_FP_SQRT(D,1,R,X)
249169689Skan#define _FP_SQRT_MEAT_D(R,S,T,X,Q)	_FP_SQRT_MEAT_1(R,S,T,X,Q)
250169689Skan
251169689Skan/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by
252169689Skan   the target machine.  */
253169689Skan
254169689Skan#define FP_CMP_D(r,X,Y,un)	_FP_CMP(D,1,r,X,Y,un)
255169689Skan#define FP_CMP_EQ_D(r,X,Y)	_FP_CMP_EQ(D,1,r,X,Y)
256169689Skan#define FP_CMP_UNORD_D(r,X,Y)	_FP_CMP_UNORD(D,1,r,X,Y)
257169689Skan
258169689Skan#define FP_TO_INT_D(r,X,rsz,rsg)	_FP_TO_INT(D,1,r,X,rsz,rsg)
259169689Skan#define FP_FROM_INT_D(X,r,rs,rt)	_FP_FROM_INT(D,1,X,r,rs,rt)
260169689Skan
261169689Skan#define _FP_FRAC_HIGH_D(X)	_FP_FRAC_HIGH_1(X)
262169689Skan#define _FP_FRAC_HIGH_RAW_D(X)	_FP_FRAC_HIGH_1(X)
263169689Skan
264169689Skan#endif /* W_TYPE_SIZE < 64 */
265