]> git.ipfire.org Git - thirdparty/glibc.git/blame - soft-fp/op-4.h
soft-fp: Use __label__ for all labels within macros.
[thirdparty/glibc.git] / soft-fp / op-4.h
CommitLineData
d876f532
UD
1/* Software floating-point emulation.
2 Basic four-word fraction declaration and manipulation.
b168057a 3 Copyright (C) 1997-2015 Free Software Foundation, Inc.
d876f532
UD
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
41bdb6e2
AJ
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.
d876f532 14
638a783c
RM
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
d876f532
UD
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
41bdb6e2 27 Lesser General Public License for more details.
d876f532 28
41bdb6e2 29 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
30 License along with the GNU C Library; if not, see
31 <http://www.gnu.org/licenses/>. */
d876f532
UD
32
33#define _FP_FRAC_DECL_4(X) _FP_W_TYPE X##_f[4]
51ca9e29 34#define _FP_FRAC_COPY_4(D, S) \
d876f532
UD
35 (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1], \
36 D##_f[2] = S##_f[2], D##_f[3] = S##_f[3])
51ca9e29 37#define _FP_FRAC_SET_4(X, I) __FP_FRAC_SET_4 (X, I)
d876f532
UD
38#define _FP_FRAC_HIGH_4(X) (X##_f[3])
39#define _FP_FRAC_LOW_4(X) (X##_f[0])
51ca9e29 40#define _FP_FRAC_WORD_4(X, w) (X##_f[w])
d876f532 41
3a6e9887
JM
42#define _FP_FRAC_SLL_4(X, N) \
43 do \
44 { \
45 _FP_I_TYPE _FP_FRAC_SLL_4_up, _FP_FRAC_SLL_4_down; \
46 _FP_I_TYPE _FP_FRAC_SLL_4_skip, _FP_FRAC_SLL_4_i; \
47 _FP_FRAC_SLL_4_skip = (N) / _FP_W_TYPE_SIZE; \
48 _FP_FRAC_SLL_4_up = (N) % _FP_W_TYPE_SIZE; \
49 _FP_FRAC_SLL_4_down = _FP_W_TYPE_SIZE - _FP_FRAC_SLL_4_up; \
50 if (!_FP_FRAC_SLL_4_up) \
51 for (_FP_FRAC_SLL_4_i = 3; \
52 _FP_FRAC_SLL_4_i >= _FP_FRAC_SLL_4_skip; \
53 --_FP_FRAC_SLL_4_i) \
54 X##_f[_FP_FRAC_SLL_4_i] \
55 = X##_f[_FP_FRAC_SLL_4_i-_FP_FRAC_SLL_4_skip]; \
56 else \
57 { \
58 for (_FP_FRAC_SLL_4_i = 3; \
59 _FP_FRAC_SLL_4_i > _FP_FRAC_SLL_4_skip; \
60 --_FP_FRAC_SLL_4_i) \
61 X##_f[_FP_FRAC_SLL_4_i] \
62 = ((X##_f[_FP_FRAC_SLL_4_i-_FP_FRAC_SLL_4_skip] \
63 << _FP_FRAC_SLL_4_up) \
64 | (X##_f[_FP_FRAC_SLL_4_i-_FP_FRAC_SLL_4_skip-1] \
65 >> _FP_FRAC_SLL_4_down)); \
66 X##_f[_FP_FRAC_SLL_4_i--] = X##_f[0] << _FP_FRAC_SLL_4_up; \
67 } \
68 for (; _FP_FRAC_SLL_4_i >= 0; --_FP_FRAC_SLL_4_i) \
69 X##_f[_FP_FRAC_SLL_4_i] = 0; \
70 } \
1e145589 71 while (0)
d876f532 72
c4fe3ea7 73/* This one was broken too. */
3a6e9887
JM
74#define _FP_FRAC_SRL_4(X, N) \
75 do \
76 { \
77 _FP_I_TYPE _FP_FRAC_SRL_4_up, _FP_FRAC_SRL_4_down; \
78 _FP_I_TYPE _FP_FRAC_SRL_4_skip, _FP_FRAC_SRL_4_i; \
79 _FP_FRAC_SRL_4_skip = (N) / _FP_W_TYPE_SIZE; \
80 _FP_FRAC_SRL_4_down = (N) % _FP_W_TYPE_SIZE; \
81 _FP_FRAC_SRL_4_up = _FP_W_TYPE_SIZE - _FP_FRAC_SRL_4_down; \
82 if (!_FP_FRAC_SRL_4_down) \
83 for (_FP_FRAC_SRL_4_i = 0; \
84 _FP_FRAC_SRL_4_i <= 3-_FP_FRAC_SRL_4_skip; \
85 ++_FP_FRAC_SRL_4_i) \
86 X##_f[_FP_FRAC_SRL_4_i] \
87 = X##_f[_FP_FRAC_SRL_4_i+_FP_FRAC_SRL_4_skip]; \
88 else \
89 { \
90 for (_FP_FRAC_SRL_4_i = 0; \
91 _FP_FRAC_SRL_4_i < 3-_FP_FRAC_SRL_4_skip; \
92 ++_FP_FRAC_SRL_4_i) \
93 X##_f[_FP_FRAC_SRL_4_i] \
94 = ((X##_f[_FP_FRAC_SRL_4_i+_FP_FRAC_SRL_4_skip] \
95 >> _FP_FRAC_SRL_4_down) \
96 | (X##_f[_FP_FRAC_SRL_4_i+_FP_FRAC_SRL_4_skip+1] \
97 << _FP_FRAC_SRL_4_up)); \
98 X##_f[_FP_FRAC_SRL_4_i++] = X##_f[3] >> _FP_FRAC_SRL_4_down; \
99 } \
100 for (; _FP_FRAC_SRL_4_i < 4; ++_FP_FRAC_SRL_4_i) \
101 X##_f[_FP_FRAC_SRL_4_i] = 0; \
102 } \
1e145589 103 while (0)
d876f532
UD
104
105
9c84384c 106/* Right shift with sticky-lsb.
c4fe3ea7
JM
107 What this actually means is that we do a standard right-shift,
108 but that if any of the bits that fall off the right hand side
109 were one then we always set the LSbit. */
3a6e9887
JM
110#define _FP_FRAC_SRST_4(X, S, N, size) \
111 do \
112 { \
113 _FP_I_TYPE _FP_FRAC_SRST_4_up, _FP_FRAC_SRST_4_down; \
114 _FP_I_TYPE _FP_FRAC_SRST_4_skip, _FP_FRAC_SRST_4_i; \
115 _FP_W_TYPE _FP_FRAC_SRST_4_s; \
116 _FP_FRAC_SRST_4_skip = (N) / _FP_W_TYPE_SIZE; \
117 _FP_FRAC_SRST_4_down = (N) % _FP_W_TYPE_SIZE; \
118 _FP_FRAC_SRST_4_up = _FP_W_TYPE_SIZE - _FP_FRAC_SRST_4_down; \
119 for (_FP_FRAC_SRST_4_s = _FP_FRAC_SRST_4_i = 0; \
120 _FP_FRAC_SRST_4_i < _FP_FRAC_SRST_4_skip; \
121 ++_FP_FRAC_SRST_4_i) \
122 _FP_FRAC_SRST_4_s |= X##_f[_FP_FRAC_SRST_4_i]; \
123 if (!_FP_FRAC_SRST_4_down) \
124 for (_FP_FRAC_SRST_4_i = 0; \
125 _FP_FRAC_SRST_4_i <= 3-_FP_FRAC_SRST_4_skip; \
126 ++_FP_FRAC_SRST_4_i) \
127 X##_f[_FP_FRAC_SRST_4_i] \
128 = X##_f[_FP_FRAC_SRST_4_i+_FP_FRAC_SRST_4_skip]; \
129 else \
130 { \
131 _FP_FRAC_SRST_4_s \
132 |= X##_f[_FP_FRAC_SRST_4_i] << _FP_FRAC_SRST_4_up; \
133 for (_FP_FRAC_SRST_4_i = 0; \
134 _FP_FRAC_SRST_4_i < 3-_FP_FRAC_SRST_4_skip; \
135 ++_FP_FRAC_SRST_4_i) \
136 X##_f[_FP_FRAC_SRST_4_i] \
137 = ((X##_f[_FP_FRAC_SRST_4_i+_FP_FRAC_SRST_4_skip] \
138 >> _FP_FRAC_SRST_4_down) \
139 | (X##_f[_FP_FRAC_SRST_4_i+_FP_FRAC_SRST_4_skip+1] \
140 << _FP_FRAC_SRST_4_up)); \
141 X##_f[_FP_FRAC_SRST_4_i++] \
142 = X##_f[3] >> _FP_FRAC_SRST_4_down; \
143 } \
144 for (; _FP_FRAC_SRST_4_i < 4; ++_FP_FRAC_SRST_4_i) \
145 X##_f[_FP_FRAC_SRST_4_i] = 0; \
146 S = (_FP_FRAC_SRST_4_s != 0); \
147 } \
1e145589 148 while (0)
fe0b1e85 149
3a6e9887
JM
150#define _FP_FRAC_SRS_4(X, N, size) \
151 do \
152 { \
153 int _FP_FRAC_SRS_4_sticky; \
5c0508a3 154 _FP_FRAC_SRST_4 (X, _FP_FRAC_SRS_4_sticky, (N), (size)); \
3a6e9887
JM
155 X##_f[0] |= _FP_FRAC_SRS_4_sticky; \
156 } \
1e145589 157 while (0)
d876f532 158
51ca9e29
JM
159#define _FP_FRAC_ADD_4(R, X, Y) \
160 __FP_FRAC_ADD_4 (R##_f[3], R##_f[2], R##_f[1], R##_f[0], \
161 X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
162 Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
d876f532 163
51ca9e29
JM
164#define _FP_FRAC_SUB_4(R, X, Y) \
165 __FP_FRAC_SUB_4 (R##_f[3], R##_f[2], R##_f[1], R##_f[0], \
166 X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
167 Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
d876f532 168
51ca9e29
JM
169#define _FP_FRAC_DEC_4(X, Y) \
170 __FP_FRAC_DEC_4 (X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
171 Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
d876f532 172
51ca9e29
JM
173#define _FP_FRAC_ADDI_4(X, I) \
174 __FP_FRAC_ADDI_4 (X##_f[3], X##_f[2], X##_f[1], X##_f[0], I)
d876f532 175
51ca9e29
JM
176#define _FP_ZEROFRAC_4 0, 0, 0, 0
177#define _FP_MINFRAC_4 0, 0, 0, 1
178#define _FP_MAXFRAC_4 (~(_FP_WS_TYPE) 0), (~(_FP_WS_TYPE) 0), (~(_FP_WS_TYPE) 0), (~(_FP_WS_TYPE) 0)
d876f532
UD
179
180#define _FP_FRAC_ZEROP_4(X) ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
51ca9e29
JM
181#define _FP_FRAC_NEGP_4(X) ((_FP_WS_TYPE) X##_f[3] < 0)
182#define _FP_FRAC_OVERP_4(fs, X) (_FP_FRAC_HIGH_##fs (X) & _FP_OVERFLOW_##fs)
183#define _FP_FRAC_HIGHBIT_DW_4(fs, X) \
184 (_FP_FRAC_HIGH_DW_##fs (X) & _FP_HIGHBIT_DW_##fs)
185#define _FP_FRAC_CLEAR_OVERP_4(fs, X) (_FP_FRAC_HIGH_##fs (X) &= ~_FP_OVERFLOW_##fs)
d876f532 186
51ca9e29 187#define _FP_FRAC_EQ_4(X, Y) \
1e145589
JM
188 (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \
189 && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3])
d876f532 190
51ca9e29 191#define _FP_FRAC_GT_4(X, Y) \
1e145589
JM
192 (X##_f[3] > Y##_f[3] \
193 || (X##_f[3] == Y##_f[3] \
194 && (X##_f[2] > Y##_f[2] \
195 || (X##_f[2] == Y##_f[2] \
196 && (X##_f[1] > Y##_f[1] \
197 || (X##_f[1] == Y##_f[1] \
198 && X##_f[0] > Y##_f[0]))))))
d876f532 199
51ca9e29 200#define _FP_FRAC_GE_4(X, Y) \
1e145589
JM
201 (X##_f[3] > Y##_f[3] \
202 || (X##_f[3] == Y##_f[3] \
203 && (X##_f[2] > Y##_f[2] \
204 || (X##_f[2] == Y##_f[2] \
205 && (X##_f[1] > Y##_f[1] \
206 || (X##_f[1] == Y##_f[1] \
207 && X##_f[0] >= Y##_f[0]))))))
208
209
51ca9e29 210#define _FP_FRAC_CLZ_4(R, X) \
1e145589
JM
211 do \
212 { \
213 if (X##_f[3]) \
5c0508a3 214 __FP_CLZ ((R), X##_f[3]); \
1e145589
JM
215 else if (X##_f[2]) \
216 { \
5c0508a3
JM
217 __FP_CLZ ((R), X##_f[2]); \
218 (R) += _FP_W_TYPE_SIZE; \
1e145589
JM
219 } \
220 else if (X##_f[1]) \
221 { \
5c0508a3
JM
222 __FP_CLZ ((R), X##_f[1]); \
223 (R) += _FP_W_TYPE_SIZE*2; \
1e145589
JM
224 } \
225 else \
226 { \
5c0508a3
JM
227 __FP_CLZ ((R), X##_f[0]); \
228 (R) += _FP_W_TYPE_SIZE*3; \
1e145589
JM
229 } \
230 } \
51ca9e29 231 while (0)
1e145589
JM
232
233
3a6e9887
JM
234#define _FP_UNPACK_RAW_4(fs, X, val) \
235 do \
236 { \
237 union _FP_UNION_##fs _FP_UNPACK_RAW_4_flo; \
238 _FP_UNPACK_RAW_4_flo.flt = (val); \
239 X##_f[0] = _FP_UNPACK_RAW_4_flo.bits.frac0; \
240 X##_f[1] = _FP_UNPACK_RAW_4_flo.bits.frac1; \
241 X##_f[2] = _FP_UNPACK_RAW_4_flo.bits.frac2; \
242 X##_f[3] = _FP_UNPACK_RAW_4_flo.bits.frac3; \
243 X##_e = _FP_UNPACK_RAW_4_flo.bits.exp; \
244 X##_s = _FP_UNPACK_RAW_4_flo.bits.sign; \
245 } \
1e145589
JM
246 while (0)
247
3a6e9887
JM
248#define _FP_UNPACK_RAW_4_P(fs, X, val) \
249 do \
250 { \
251 union _FP_UNION_##fs *_FP_UNPACK_RAW_4_P_flo \
252 = (union _FP_UNION_##fs *) (val); \
253 \
254 X##_f[0] = _FP_UNPACK_RAW_4_P_flo->bits.frac0; \
255 X##_f[1] = _FP_UNPACK_RAW_4_P_flo->bits.frac1; \
256 X##_f[2] = _FP_UNPACK_RAW_4_P_flo->bits.frac2; \
257 X##_f[3] = _FP_UNPACK_RAW_4_P_flo->bits.frac3; \
258 X##_e = _FP_UNPACK_RAW_4_P_flo->bits.exp; \
259 X##_s = _FP_UNPACK_RAW_4_P_flo->bits.sign; \
260 } \
1e145589
JM
261 while (0)
262
263#define _FP_PACK_RAW_4(fs, val, X) \
264 do \
265 { \
3a6e9887
JM
266 union _FP_UNION_##fs _FP_PACK_RAW_4_flo; \
267 _FP_PACK_RAW_4_flo.bits.frac0 = X##_f[0]; \
268 _FP_PACK_RAW_4_flo.bits.frac1 = X##_f[1]; \
269 _FP_PACK_RAW_4_flo.bits.frac2 = X##_f[2]; \
270 _FP_PACK_RAW_4_flo.bits.frac3 = X##_f[3]; \
271 _FP_PACK_RAW_4_flo.bits.exp = X##_e; \
272 _FP_PACK_RAW_4_flo.bits.sign = X##_s; \
273 (val) = _FP_PACK_RAW_4_flo.flt; \
1e145589
JM
274 } \
275 while (0)
276
3a6e9887
JM
277#define _FP_PACK_RAW_4_P(fs, val, X) \
278 do \
279 { \
280 union _FP_UNION_##fs *_FP_PACK_RAW_4_P_flo \
281 = (union _FP_UNION_##fs *) (val); \
282 \
283 _FP_PACK_RAW_4_P_flo->bits.frac0 = X##_f[0]; \
284 _FP_PACK_RAW_4_P_flo->bits.frac1 = X##_f[1]; \
285 _FP_PACK_RAW_4_P_flo->bits.frac2 = X##_f[2]; \
286 _FP_PACK_RAW_4_P_flo->bits.frac3 = X##_f[3]; \
287 _FP_PACK_RAW_4_P_flo->bits.exp = X##_e; \
288 _FP_PACK_RAW_4_P_flo->bits.sign = X##_s; \
289 } \
1e145589 290 while (0)
d876f532 291
c4fe3ea7 292/* Multiplication algorithms: */
d876f532
UD
293
294/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
295
1e145589
JM
296#define _FP_MUL_MEAT_DW_4_wide(wfracbits, R, X, Y, doit) \
297 do \
298 { \
3a6e9887
JM
299 _FP_FRAC_DECL_2 (_FP_MUL_MEAT_DW_4_wide_b); \
300 _FP_FRAC_DECL_2 (_FP_MUL_MEAT_DW_4_wide_c); \
301 _FP_FRAC_DECL_2 (_FP_MUL_MEAT_DW_4_wide_d); \
302 _FP_FRAC_DECL_2 (_FP_MUL_MEAT_DW_4_wide_e); \
303 _FP_FRAC_DECL_2 (_FP_MUL_MEAT_DW_4_wide_f); \
1e145589 304 \
3a6e9887
JM
305 doit (_FP_FRAC_WORD_8 (R, 1), _FP_FRAC_WORD_8 (R, 0), \
306 X##_f[0], Y##_f[0]); \
307 doit (_FP_MUL_MEAT_DW_4_wide_b_f1, _FP_MUL_MEAT_DW_4_wide_b_f0, \
308 X##_f[0], Y##_f[1]); \
309 doit (_FP_MUL_MEAT_DW_4_wide_c_f1, _FP_MUL_MEAT_DW_4_wide_c_f0, \
310 X##_f[1], Y##_f[0]); \
311 doit (_FP_MUL_MEAT_DW_4_wide_d_f1, _FP_MUL_MEAT_DW_4_wide_d_f0, \
312 X##_f[1], Y##_f[1]); \
313 doit (_FP_MUL_MEAT_DW_4_wide_e_f1, _FP_MUL_MEAT_DW_4_wide_e_f0, \
314 X##_f[0], Y##_f[2]); \
315 doit (_FP_MUL_MEAT_DW_4_wide_f_f1, _FP_MUL_MEAT_DW_4_wide_f_f0, \
316 X##_f[2], Y##_f[0]); \
51ca9e29 317 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 3), _FP_FRAC_WORD_8 (R, 2), \
3a6e9887
JM
318 _FP_FRAC_WORD_8 (R, 1), 0, \
319 _FP_MUL_MEAT_DW_4_wide_b_f1, \
320 _FP_MUL_MEAT_DW_4_wide_b_f0, \
51ca9e29
JM
321 0, 0, _FP_FRAC_WORD_8 (R, 1)); \
322 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 3), _FP_FRAC_WORD_8 (R, 2), \
3a6e9887
JM
323 _FP_FRAC_WORD_8 (R, 1), 0, \
324 _FP_MUL_MEAT_DW_4_wide_c_f1, \
325 _FP_MUL_MEAT_DW_4_wide_c_f0, \
51ca9e29
JM
326 _FP_FRAC_WORD_8 (R, 3), _FP_FRAC_WORD_8 (R, 2), \
327 _FP_FRAC_WORD_8 (R, 1)); \
328 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 4), _FP_FRAC_WORD_8 (R, 3), \
3a6e9887
JM
329 _FP_FRAC_WORD_8 (R, 2), 0, \
330 _FP_MUL_MEAT_DW_4_wide_d_f1, \
331 _FP_MUL_MEAT_DW_4_wide_d_f0, \
51ca9e29
JM
332 0, _FP_FRAC_WORD_8 (R, 3), _FP_FRAC_WORD_8 (R, 2)); \
333 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 4), _FP_FRAC_WORD_8 (R, 3), \
3a6e9887
JM
334 _FP_FRAC_WORD_8 (R, 2), 0, \
335 _FP_MUL_MEAT_DW_4_wide_e_f1, \
336 _FP_MUL_MEAT_DW_4_wide_e_f0, \
51ca9e29
JM
337 _FP_FRAC_WORD_8 (R, 4), _FP_FRAC_WORD_8 (R, 3), \
338 _FP_FRAC_WORD_8 (R, 2)); \
339 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 4), _FP_FRAC_WORD_8 (R, 3), \
3a6e9887
JM
340 _FP_FRAC_WORD_8 (R, 2), 0, \
341 _FP_MUL_MEAT_DW_4_wide_f_f1, \
342 _FP_MUL_MEAT_DW_4_wide_f_f0, \
51ca9e29
JM
343 _FP_FRAC_WORD_8 (R, 4), _FP_FRAC_WORD_8 (R, 3), \
344 _FP_FRAC_WORD_8 (R, 2)); \
3a6e9887
JM
345 doit (_FP_MUL_MEAT_DW_4_wide_b_f1, \
346 _FP_MUL_MEAT_DW_4_wide_b_f0, X##_f[0], Y##_f[3]); \
347 doit (_FP_MUL_MEAT_DW_4_wide_c_f1, \
348 _FP_MUL_MEAT_DW_4_wide_c_f0, X##_f[3], Y##_f[0]); \
349 doit (_FP_MUL_MEAT_DW_4_wide_d_f1, _FP_MUL_MEAT_DW_4_wide_d_f0, \
350 X##_f[1], Y##_f[2]); \
351 doit (_FP_MUL_MEAT_DW_4_wide_e_f1, _FP_MUL_MEAT_DW_4_wide_e_f0, \
352 X##_f[2], Y##_f[1]); \
51ca9e29 353 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \
3a6e9887
JM
354 _FP_FRAC_WORD_8 (R, 3), 0, \
355 _FP_MUL_MEAT_DW_4_wide_b_f1, \
356 _FP_MUL_MEAT_DW_4_wide_b_f0, \
51ca9e29
JM
357 0, _FP_FRAC_WORD_8 (R, 4), _FP_FRAC_WORD_8 (R, 3)); \
358 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \
3a6e9887
JM
359 _FP_FRAC_WORD_8 (R, 3), 0, \
360 _FP_MUL_MEAT_DW_4_wide_c_f1, \
361 _FP_MUL_MEAT_DW_4_wide_c_f0, \
51ca9e29
JM
362 _FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \
363 _FP_FRAC_WORD_8 (R, 3)); \
364 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \
3a6e9887
JM
365 _FP_FRAC_WORD_8 (R, 3), 0, \
366 _FP_MUL_MEAT_DW_4_wide_d_f1, \
367 _FP_MUL_MEAT_DW_4_wide_d_f0, \
51ca9e29
JM
368 _FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \
369 _FP_FRAC_WORD_8 (R, 3)); \
370 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \
3a6e9887
JM
371 _FP_FRAC_WORD_8 (R, 3), 0, \
372 _FP_MUL_MEAT_DW_4_wide_e_f1, \
373 _FP_MUL_MEAT_DW_4_wide_e_f0, \
51ca9e29
JM
374 _FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4), \
375 _FP_FRAC_WORD_8 (R, 3)); \
3a6e9887
JM
376 doit (_FP_MUL_MEAT_DW_4_wide_b_f1, _FP_MUL_MEAT_DW_4_wide_b_f0, \
377 X##_f[2], Y##_f[2]); \
378 doit (_FP_MUL_MEAT_DW_4_wide_c_f1, _FP_MUL_MEAT_DW_4_wide_c_f0, \
379 X##_f[1], Y##_f[3]); \
380 doit (_FP_MUL_MEAT_DW_4_wide_d_f1, _FP_MUL_MEAT_DW_4_wide_d_f0, \
381 X##_f[3], Y##_f[1]); \
382 doit (_FP_MUL_MEAT_DW_4_wide_e_f1, _FP_MUL_MEAT_DW_4_wide_e_f0, \
383 X##_f[2], Y##_f[3]); \
384 doit (_FP_MUL_MEAT_DW_4_wide_f_f1, _FP_MUL_MEAT_DW_4_wide_f_f0, \
385 X##_f[3], Y##_f[2]); \
51ca9e29 386 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 6), _FP_FRAC_WORD_8 (R, 5), \
3a6e9887
JM
387 _FP_FRAC_WORD_8 (R, 4), 0, \
388 _FP_MUL_MEAT_DW_4_wide_b_f1, \
389 _FP_MUL_MEAT_DW_4_wide_b_f0, \
51ca9e29
JM
390 0, _FP_FRAC_WORD_8 (R, 5), _FP_FRAC_WORD_8 (R, 4)); \
391 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 6), _FP_FRAC_WORD_8 (R, 5), \
3a6e9887
JM
392 _FP_FRAC_WORD_8 (R, 4), 0, \
393 _FP_MUL_MEAT_DW_4_wide_c_f1, \
394 _FP_MUL_MEAT_DW_4_wide_c_f0, \
51ca9e29
JM
395 _FP_FRAC_WORD_8 (R, 6), _FP_FRAC_WORD_8 (R, 5), \
396 _FP_FRAC_WORD_8 (R, 4)); \
397 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 6), _FP_FRAC_WORD_8 (R, 5), \
3a6e9887
JM
398 _FP_FRAC_WORD_8 (R, 4), 0, \
399 _FP_MUL_MEAT_DW_4_wide_d_f1, \
400 _FP_MUL_MEAT_DW_4_wide_d_f0, \
51ca9e29
JM
401 _FP_FRAC_WORD_8 (R, 6), _FP_FRAC_WORD_8 (R, 5), \
402 _FP_FRAC_WORD_8 (R, 4)); \
403 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 7), _FP_FRAC_WORD_8 (R, 6), \
3a6e9887
JM
404 _FP_FRAC_WORD_8 (R, 5), 0, \
405 _FP_MUL_MEAT_DW_4_wide_e_f1, \
406 _FP_MUL_MEAT_DW_4_wide_e_f0, \
51ca9e29
JM
407 0, _FP_FRAC_WORD_8 (R, 6), _FP_FRAC_WORD_8 (R, 5)); \
408 __FP_FRAC_ADD_3 (_FP_FRAC_WORD_8 (R, 7), _FP_FRAC_WORD_8 (R, 6), \
3a6e9887
JM
409 _FP_FRAC_WORD_8 (R, 5), 0, \
410 _FP_MUL_MEAT_DW_4_wide_f_f1, \
411 _FP_MUL_MEAT_DW_4_wide_f_f0, \
51ca9e29
JM
412 _FP_FRAC_WORD_8 (R, 7), _FP_FRAC_WORD_8 (R, 6), \
413 _FP_FRAC_WORD_8 (R, 5)); \
3a6e9887
JM
414 doit (_FP_MUL_MEAT_DW_4_wide_b_f1, _FP_MUL_MEAT_DW_4_wide_b_f0, \
415 X##_f[3], Y##_f[3]); \
51ca9e29 416 __FP_FRAC_ADD_2 (_FP_FRAC_WORD_8 (R, 7), _FP_FRAC_WORD_8 (R, 6), \
3a6e9887
JM
417 _FP_MUL_MEAT_DW_4_wide_b_f1, \
418 _FP_MUL_MEAT_DW_4_wide_b_f0, \
51ca9e29 419 _FP_FRAC_WORD_8 (R, 7), _FP_FRAC_WORD_8 (R, 6)); \
1e145589
JM
420 } \
421 while (0)
422
423#define _FP_MUL_MEAT_4_wide(wfracbits, R, X, Y, doit) \
424 do \
425 { \
3a6e9887 426 _FP_FRAC_DECL_8 (_FP_MUL_MEAT_4_wide_z); \
1e145589 427 \
5c0508a3 428 _FP_MUL_MEAT_DW_4_wide ((wfracbits), _FP_MUL_MEAT_4_wide_z, \
3a6e9887 429 X, Y, doit); \
1e145589
JM
430 \
431 /* Normalize since we know where the msb of the multiplicands \
432 were (bit B), we know that the msb of the of the product is \
433 at either 2B or 2B-1. */ \
5c0508a3
JM
434 _FP_FRAC_SRS_8 (_FP_MUL_MEAT_4_wide_z, (wfracbits)-1, \
435 2*(wfracbits)); \
3a6e9887
JM
436 __FP_FRAC_SET_4 (R, _FP_FRAC_WORD_8 (_FP_MUL_MEAT_4_wide_z, 3), \
437 _FP_FRAC_WORD_8 (_FP_MUL_MEAT_4_wide_z, 2), \
438 _FP_FRAC_WORD_8 (_FP_MUL_MEAT_4_wide_z, 1), \
439 _FP_FRAC_WORD_8 (_FP_MUL_MEAT_4_wide_z, 0)); \
1e145589
JM
440 } \
441 while (0)
442
443#define _FP_MUL_MEAT_DW_4_gmp(wfracbits, R, X, Y) \
444 do \
445 { \
51ca9e29 446 mpn_mul_n (R##_f, _x_f, _y_f, 4); \
1e145589
JM
447 } \
448 while (0)
449
450#define _FP_MUL_MEAT_4_gmp(wfracbits, R, X, Y) \
451 do \
452 { \
3a6e9887 453 _FP_FRAC_DECL_8 (_FP_MUL_MEAT_4_gmp_z); \
1e145589 454 \
5c0508a3 455 _FP_MUL_MEAT_DW_4_gmp ((wfracbits), _FP_MUL_MEAT_4_gmp_z, X, Y); \
1e145589
JM
456 \
457 /* Normalize since we know where the msb of the multiplicands \
458 were (bit B), we know that the msb of the of the product is \
459 at either 2B or 2B-1. */ \
5c0508a3
JM
460 _FP_FRAC_SRS_8 (_FP_MUL_MEAT_4_gmp_z, (wfracbits)-1, \
461 2*(wfracbits)); \
3a6e9887
JM
462 __FP_FRAC_SET_4 (R, _FP_FRAC_WORD_8 (_FP_MUL_MEAT_4_gmp_z, 3), \
463 _FP_FRAC_WORD_8 (_FP_MUL_MEAT_4_gmp_z, 2), \
464 _FP_FRAC_WORD_8 (_FP_MUL_MEAT_4_gmp_z, 1), \
465 _FP_FRAC_WORD_8 (_FP_MUL_MEAT_4_gmp_z, 0)); \
1e145589
JM
466 } \
467 while (0)
d876f532 468
c4fe3ea7
JM
469/* Helper utility for _FP_DIV_MEAT_4_udiv:
470 * pppp = m * nnn. */
51ca9e29
JM
471#define umul_ppppmnnn(p3, p2, p1, p0, m, n2, n1, n0) \
472 do \
473 { \
3a6e9887 474 UWtype umul_ppppmnnn_t; \
51ca9e29 475 umul_ppmm (p1, p0, m, n0); \
3a6e9887
JM
476 umul_ppmm (p2, umul_ppppmnnn_t, m, n1); \
477 __FP_FRAC_ADDI_2 (p2, p1, umul_ppppmnnn_t); \
478 umul_ppmm (p3, umul_ppppmnnn_t, m, n2); \
479 __FP_FRAC_ADDI_2 (p3, p2, umul_ppppmnnn_t); \
51ca9e29 480 } \
1e145589 481 while (0)
d876f532 482
c4fe3ea7 483/* Division algorithms: */
d876f532 484
1e145589
JM
485#define _FP_DIV_MEAT_4_udiv(fs, R, X, Y) \
486 do \
487 { \
3a6e9887
JM
488 int _FP_DIV_MEAT_4_udiv_i; \
489 _FP_FRAC_DECL_4 (_FP_DIV_MEAT_4_udiv_n); \
490 _FP_FRAC_DECL_4 (_FP_DIV_MEAT_4_udiv_m); \
491 _FP_FRAC_SET_4 (_FP_DIV_MEAT_4_udiv_n, _FP_ZEROFRAC_4); \
51ca9e29 492 if (_FP_FRAC_GE_4 (X, Y)) \
1e145589 493 { \
3a6e9887
JM
494 _FP_DIV_MEAT_4_udiv_n_f[3] \
495 = X##_f[0] << (_FP_W_TYPE_SIZE - 1); \
51ca9e29 496 _FP_FRAC_SRL_4 (X, 1); \
1e145589
JM
497 } \
498 else \
499 R##_e--; \
500 \
501 /* Normalize, i.e. make the most significant bit of the \
c4fe3ea7 502 denominator set. */ \
51ca9e29 503 _FP_FRAC_SLL_4 (Y, _FP_WFRACXBITS_##fs); \
1e145589 504 \
3a6e9887 505 for (_FP_DIV_MEAT_4_udiv_i = 3; ; _FP_DIV_MEAT_4_udiv_i--) \
1e145589
JM
506 { \
507 if (X##_f[3] == Y##_f[3]) \
508 { \
509 /* This is a special case, not an optimization \
510 (X##_f[3]/Y##_f[3] would not fit into UWtype). \
3a6e9887
JM
511 As X## is guaranteed to be < Y, \
512 R##_f[_FP_DIV_MEAT_4_udiv_i] can be either \
1e145589 513 (UWtype)-1 or (UWtype)-2. */ \
3a6e9887
JM
514 R##_f[_FP_DIV_MEAT_4_udiv_i] = -1; \
515 if (!_FP_DIV_MEAT_4_udiv_i) \
1e145589 516 break; \
51ca9e29
JM
517 __FP_FRAC_SUB_4 (X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
518 Y##_f[2], Y##_f[1], Y##_f[0], 0, \
3a6e9887
JM
519 X##_f[2], X##_f[1], X##_f[0], \
520 _FP_DIV_MEAT_4_udiv_n_f[_FP_DIV_MEAT_4_udiv_i]); \
51ca9e29 521 _FP_FRAC_SUB_4 (X, Y, X); \
1e145589
JM
522 if (X##_f[3] > Y##_f[3]) \
523 { \
3a6e9887 524 R##_f[_FP_DIV_MEAT_4_udiv_i] = -2; \
51ca9e29 525 _FP_FRAC_ADD_4 (X, Y, X); \
1e145589
JM
526 } \
527 } \
528 else \
529 { \
3a6e9887
JM
530 udiv_qrnnd (R##_f[_FP_DIV_MEAT_4_udiv_i], \
531 X##_f[3], X##_f[3], X##_f[2], Y##_f[3]); \
532 umul_ppppmnnn (_FP_DIV_MEAT_4_udiv_m_f[3], \
533 _FP_DIV_MEAT_4_udiv_m_f[2], \
534 _FP_DIV_MEAT_4_udiv_m_f[1], \
535 _FP_DIV_MEAT_4_udiv_m_f[0], \
536 R##_f[_FP_DIV_MEAT_4_udiv_i], \
537 Y##_f[2], Y##_f[1], Y##_f[0]); \
1e145589
JM
538 X##_f[2] = X##_f[1]; \
539 X##_f[1] = X##_f[0]; \
3a6e9887
JM
540 X##_f[0] \
541 = _FP_DIV_MEAT_4_udiv_n_f[_FP_DIV_MEAT_4_udiv_i]; \
542 if (_FP_FRAC_GT_4 (_FP_DIV_MEAT_4_udiv_m, X)) \
1e145589 543 { \
3a6e9887 544 R##_f[_FP_DIV_MEAT_4_udiv_i]--; \
51ca9e29 545 _FP_FRAC_ADD_4 (X, Y, X); \
3a6e9887
JM
546 if (_FP_FRAC_GE_4 (X, Y) \
547 && _FP_FRAC_GT_4 (_FP_DIV_MEAT_4_udiv_m, X)) \
1e145589 548 { \
3a6e9887 549 R##_f[_FP_DIV_MEAT_4_udiv_i]--; \
51ca9e29 550 _FP_FRAC_ADD_4 (X, Y, X); \
1e145589
JM
551 } \
552 } \
3a6e9887
JM
553 _FP_FRAC_DEC_4 (X, _FP_DIV_MEAT_4_udiv_m); \
554 if (!_FP_DIV_MEAT_4_udiv_i) \
1e145589 555 { \
3a6e9887 556 if (!_FP_FRAC_EQ_4 (X, _FP_DIV_MEAT_4_udiv_m)) \
1e145589
JM
557 R##_f[0] |= _FP_WORK_STICKY; \
558 break; \
559 } \
560 } \
561 } \
562 } \
563 while (0)
d876f532
UD
564
565
c4fe3ea7
JM
566/* Square root algorithms:
567 We have just one right now, maybe Newton approximation
568 should be added for those machines where division is fast. */
9c84384c 569
1e145589
JM
570#define _FP_SQRT_MEAT_4(R, S, T, X, q) \
571 do \
572 { \
573 while (q) \
574 { \
5c0508a3 575 T##_f[3] = S##_f[3] + (q); \
1e145589
JM
576 if (T##_f[3] <= X##_f[3]) \
577 { \
5c0508a3 578 S##_f[3] = T##_f[3] + (q); \
1e145589 579 X##_f[3] -= T##_f[3]; \
5c0508a3 580 R##_f[3] += (q); \
1e145589 581 } \
51ca9e29 582 _FP_FRAC_SLL_4 (X, 1); \
5c0508a3 583 (q) >>= 1; \
1e145589 584 } \
5c0508a3 585 (q) = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \
1e145589
JM
586 while (q) \
587 { \
5c0508a3 588 T##_f[2] = S##_f[2] + (q); \
1e145589
JM
589 T##_f[3] = S##_f[3]; \
590 if (T##_f[3] < X##_f[3] \
591 || (T##_f[3] == X##_f[3] && T##_f[2] <= X##_f[2])) \
592 { \
5c0508a3 593 S##_f[2] = T##_f[2] + (q); \
1e145589 594 S##_f[3] += (T##_f[2] > S##_f[2]); \
51ca9e29
JM
595 __FP_FRAC_DEC_2 (X##_f[3], X##_f[2], \
596 T##_f[3], T##_f[2]); \
5c0508a3 597 R##_f[2] += (q); \
1e145589 598 } \
51ca9e29 599 _FP_FRAC_SLL_4 (X, 1); \
5c0508a3 600 (q) >>= 1; \
1e145589 601 } \
5c0508a3 602 (q) = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \
1e145589
JM
603 while (q) \
604 { \
5c0508a3 605 T##_f[1] = S##_f[1] + (q); \
1e145589
JM
606 T##_f[2] = S##_f[2]; \
607 T##_f[3] = S##_f[3]; \
608 if (T##_f[3] < X##_f[3] \
609 || (T##_f[3] == X##_f[3] \
610 && (T##_f[2] < X##_f[2] \
611 || (T##_f[2] == X##_f[2] \
612 && T##_f[1] <= X##_f[1])))) \
613 { \
5c0508a3 614 S##_f[1] = T##_f[1] + (q); \
1e145589
JM
615 S##_f[2] += (T##_f[1] > S##_f[1]); \
616 S##_f[3] += (T##_f[2] > S##_f[2]); \
51ca9e29
JM
617 __FP_FRAC_DEC_3 (X##_f[3], X##_f[2], X##_f[1], \
618 T##_f[3], T##_f[2], T##_f[1]); \
5c0508a3 619 R##_f[1] += (q); \
1e145589 620 } \
51ca9e29 621 _FP_FRAC_SLL_4 (X, 1); \
5c0508a3 622 (q) >>= 1; \
1e145589 623 } \
5c0508a3
JM
624 (q) = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1); \
625 while ((q) != _FP_WORK_ROUND) \
1e145589 626 { \
5c0508a3 627 T##_f[0] = S##_f[0] + (q); \
1e145589
JM
628 T##_f[1] = S##_f[1]; \
629 T##_f[2] = S##_f[2]; \
630 T##_f[3] = S##_f[3]; \
51ca9e29 631 if (_FP_FRAC_GE_4 (X, T)) \
1e145589 632 { \
5c0508a3 633 S##_f[0] = T##_f[0] + (q); \
1e145589
JM
634 S##_f[1] += (T##_f[0] > S##_f[0]); \
635 S##_f[2] += (T##_f[1] > S##_f[1]); \
636 S##_f[3] += (T##_f[2] > S##_f[2]); \
51ca9e29 637 _FP_FRAC_DEC_4 (X, T); \
5c0508a3 638 R##_f[0] += (q); \
1e145589 639 } \
51ca9e29 640 _FP_FRAC_SLL_4 (X, 1); \
5c0508a3 641 (q) >>= 1; \
1e145589 642 } \
51ca9e29 643 if (!_FP_FRAC_ZEROP_4 (X)) \
1e145589 644 { \
51ca9e29 645 if (_FP_FRAC_GT_4 (X, S)) \
1e145589
JM
646 R##_f[0] |= _FP_WORK_ROUND; \
647 R##_f[0] |= _FP_WORK_STICKY; \
648 } \
649 } \
650 while (0)
d876f532
UD
651
652
c4fe3ea7 653/* Internals. */
d876f532 654
51ca9e29 655#define __FP_FRAC_SET_4(X, I3, I2, I1, I0) \
d876f532
UD
656 (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)
657
658#ifndef __FP_FRAC_ADD_3
51ca9e29 659# define __FP_FRAC_ADD_3(r2, r1, r0, x2, x1, x0, y2, y1, y0) \
1e145589
JM
660 do \
661 { \
662 _FP_W_TYPE __FP_FRAC_ADD_3_c1, __FP_FRAC_ADD_3_c2; \
663 r0 = x0 + y0; \
664 __FP_FRAC_ADD_3_c1 = r0 < x0; \
665 r1 = x1 + y1; \
666 __FP_FRAC_ADD_3_c2 = r1 < x1; \
667 r1 += __FP_FRAC_ADD_3_c1; \
668 __FP_FRAC_ADD_3_c2 |= r1 < __FP_FRAC_ADD_3_c1; \
669 r2 = x2 + y2 + __FP_FRAC_ADD_3_c2; \
670 } \
671 while (0)
d876f532
UD
672#endif
673
674#ifndef __FP_FRAC_ADD_4
51ca9e29
JM
675# define __FP_FRAC_ADD_4(r3, r2, r1, r0, x3, x2, x1, x0, y3, y2, y1, y0) \
676 do \
677 { \
3a6e9887
JM
678 _FP_W_TYPE __FP_FRAC_ADD_4_c1, __FP_FRAC_ADD_4_c2; \
679 _FP_W_TYPE __FP_FRAC_ADD_4_c3; \
51ca9e29 680 r0 = x0 + y0; \
3a6e9887 681 __FP_FRAC_ADD_4_c1 = r0 < x0; \
51ca9e29 682 r1 = x1 + y1; \
3a6e9887
JM
683 __FP_FRAC_ADD_4_c2 = r1 < x1; \
684 r1 += __FP_FRAC_ADD_4_c1; \
685 __FP_FRAC_ADD_4_c2 |= r1 < __FP_FRAC_ADD_4_c1; \
51ca9e29 686 r2 = x2 + y2; \
3a6e9887
JM
687 __FP_FRAC_ADD_4_c3 = r2 < x2; \
688 r2 += __FP_FRAC_ADD_4_c2; \
689 __FP_FRAC_ADD_4_c3 |= r2 < __FP_FRAC_ADD_4_c2; \
690 r3 = x3 + y3 + __FP_FRAC_ADD_4_c3; \
51ca9e29 691 } \
1e145589 692 while (0)
d876f532
UD
693#endif
694
695#ifndef __FP_FRAC_SUB_3
51ca9e29 696# define __FP_FRAC_SUB_3(r2, r1, r0, x2, x1, x0, y2, y1, y0) \
1e145589
JM
697 do \
698 { \
3a6e9887 699 _FP_W_TYPE __FP_FRAC_SUB_3_c1, __FP_FRAC_SUB_3_c2; \
1e145589 700 r0 = x0 - y0; \
3a6e9887 701 __FP_FRAC_SUB_3_c1 = r0 > x0; \
1e145589 702 r1 = x1 - y1; \
3a6e9887
JM
703 __FP_FRAC_SUB_3_c2 = r1 > x1; \
704 r1 -= __FP_FRAC_SUB_3_c1; \
705 __FP_FRAC_SUB_3_c2 |= __FP_FRAC_SUB_3_c1 && (y1 == x1); \
706 r2 = x2 - y2 - __FP_FRAC_SUB_3_c2; \
1e145589
JM
707 } \
708 while (0)
d876f532
UD
709#endif
710
51ca9e29
JM
711#ifndef __FP_FRAC_SUB_4
712# define __FP_FRAC_SUB_4(r3, r2, r1, r0, x3, x2, x1, x0, y3, y2, y1, y0) \
713 do \
714 { \
3a6e9887
JM
715 _FP_W_TYPE __FP_FRAC_SUB_4_c1, __FP_FRAC_SUB_4_c2; \
716 _FP_W_TYPE __FP_FRAC_SUB_4_c3; \
51ca9e29 717 r0 = x0 - y0; \
3a6e9887 718 __FP_FRAC_SUB_4_c1 = r0 > x0; \
51ca9e29 719 r1 = x1 - y1; \
3a6e9887
JM
720 __FP_FRAC_SUB_4_c2 = r1 > x1; \
721 r1 -= __FP_FRAC_SUB_4_c1; \
722 __FP_FRAC_SUB_4_c2 |= __FP_FRAC_SUB_4_c1 && (y1 == x1); \
51ca9e29 723 r2 = x2 - y2; \
3a6e9887
JM
724 __FP_FRAC_SUB_4_c3 = r2 > x2; \
725 r2 -= __FP_FRAC_SUB_4_c2; \
726 __FP_FRAC_SUB_4_c3 |= __FP_FRAC_SUB_4_c2 && (y2 == x2); \
727 r3 = x3 - y3 - __FP_FRAC_SUB_4_c3; \
51ca9e29
JM
728 } \
729 while (0)
730#endif
731
d876f532 732#ifndef __FP_FRAC_DEC_3
51ca9e29 733# define __FP_FRAC_DEC_3(x2, x1, x0, y2, y1, y0) \
1e145589
JM
734 do \
735 { \
3a6e9887
JM
736 UWtype __FP_FRAC_DEC_3_t0, __FP_FRAC_DEC_3_t1; \
737 UWtype __FP_FRAC_DEC_3_t2; \
738 __FP_FRAC_DEC_3_t0 = x0; \
739 __FP_FRAC_DEC_3_t1 = x1; \
740 __FP_FRAC_DEC_3_t2 = x2; \
741 __FP_FRAC_SUB_3 (x2, x1, x0, __FP_FRAC_DEC_3_t2, \
742 __FP_FRAC_DEC_3_t1, __FP_FRAC_DEC_3_t0, \
743 y2, y1, y0); \
1e145589
JM
744 } \
745 while (0)
d876f532
UD
746#endif
747
748#ifndef __FP_FRAC_DEC_4
3a6e9887
JM
749# define __FP_FRAC_DEC_4(x3, x2, x1, x0, y3, y2, y1, y0) \
750 do \
751 { \
752 UWtype __FP_FRAC_DEC_4_t0, __FP_FRAC_DEC_4_t1; \
753 UWtype __FP_FRAC_DEC_4_t2, __FP_FRAC_DEC_4_t3; \
754 __FP_FRAC_DEC_4_t0 = x0; \
755 __FP_FRAC_DEC_4_t1 = x1; \
756 __FP_FRAC_DEC_4_t2 = x2; \
757 __FP_FRAC_DEC_4_t3 = x3; \
758 __FP_FRAC_SUB_4 (x3, x2, x1, x0, __FP_FRAC_DEC_4_t3, \
759 __FP_FRAC_DEC_4_t2, __FP_FRAC_DEC_4_t1, \
760 __FP_FRAC_DEC_4_t0, y3, y2, y1, y0); \
761 } \
1e145589 762 while (0)
d876f532
UD
763#endif
764
765#ifndef __FP_FRAC_ADDI_4
3a6e9887
JM
766# define __FP_FRAC_ADDI_4(x3, x2, x1, x0, i) \
767 do \
768 { \
769 UWtype __FP_FRAC_ADDI_4_t; \
770 __FP_FRAC_ADDI_4_t = ((x0 += i) < i); \
771 x1 += __FP_FRAC_ADDI_4_t; \
772 __FP_FRAC_ADDI_4_t = (x1 < __FP_FRAC_ADDI_4_t); \
773 x2 += __FP_FRAC_ADDI_4_t; \
774 __FP_FRAC_ADDI_4_t = (x2 < __FP_FRAC_ADDI_4_t); \
775 x3 += __FP_FRAC_ADDI_4_t; \
776 } \
1e145589 777 while (0)
d876f532
UD
778#endif
779
780/* Convert FP values between word sizes. This appears to be more
c4fe3ea7
JM
781 complicated than I'd have expected it to be, so these might be
782 wrong... These macros are in any case somewhat bogus because they
783 use information about what various FRAC_n variables look like
784 internally [eg, that 2 word vars are X_f0 and x_f1]. But so do
785 the ones in op-2.h and op-1.h. */
fe0b1e85 786#define _FP_FRAC_COPY_1_4(D, S) (D##_f = S##_f[0])
d876f532 787
fe0b1e85 788#define _FP_FRAC_COPY_2_4(D, S) \
1e145589
JM
789 do \
790 { \
791 D##_f0 = S##_f[0]; \
792 D##_f1 = S##_f[1]; \
793 } \
794 while (0)
d876f532 795
9c84384c 796/* Assembly/disassembly for converting to/from integral types.
c4fe3ea7
JM
797 No shifting or overflow handled here. */
798/* Put the FP value X into r, which is an integer of size rsize. */
d876f532 799#define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \
1e145589 800 do \
d876f532 801 { \
5c0508a3
JM
802 if ((rsize) <= _FP_W_TYPE_SIZE) \
803 (r) = X##_f[0]; \
804 else if ((rsize) <= 2*_FP_W_TYPE_SIZE) \
1e145589 805 { \
5c0508a3
JM
806 (r) = X##_f[1]; \
807 (r) = ((rsize) <= _FP_W_TYPE_SIZE \
808 ? 0 \
809 : (r) << _FP_W_TYPE_SIZE); \
810 (r) += X##_f[0]; \
1e145589
JM
811 } \
812 else \
813 { \
c4fe3ea7
JM
814 /* I'm feeling lazy so we deal with int == 3words \
815 (implausible) and int == 4words as a single case. */ \
5c0508a3
JM
816 (r) = X##_f[3]; \
817 (r) = ((rsize) <= _FP_W_TYPE_SIZE \
818 ? 0 \
819 : (r) << _FP_W_TYPE_SIZE); \
820 (r) += X##_f[2]; \
821 (r) = ((rsize) <= _FP_W_TYPE_SIZE \
822 ? 0 \
823 : (r) << _FP_W_TYPE_SIZE); \
824 (r) += X##_f[1]; \
825 (r) = ((rsize) <= _FP_W_TYPE_SIZE \
826 ? 0 \
827 : (r) << _FP_W_TYPE_SIZE); \
828 (r) += X##_f[0]; \
1e145589 829 } \
d876f532 830 } \
1e145589 831 while (0)
d876f532
UD
832
833/* "No disassemble Number Five!" */
c4fe3ea7
JM
834/* Move an integer of size rsize into X's fractional part. We rely on
835 the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid
836 having to mask the values we store into it. */
5c0508a3
JM
837#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \
838 do \
839 { \
840 X##_f[0] = (r); \
841 X##_f[1] = ((rsize) <= _FP_W_TYPE_SIZE \
842 ? 0 \
843 : (r) >> _FP_W_TYPE_SIZE); \
844 X##_f[2] = ((rsize) <= 2*_FP_W_TYPE_SIZE \
845 ? 0 \
846 : (r) >> 2*_FP_W_TYPE_SIZE); \
847 X##_f[3] = ((rsize) <= 3*_FP_W_TYPE_SIZE \
848 ? 0 \
849 : (r) >> 3*_FP_W_TYPE_SIZE); \
850 } \
1e145589 851 while (0)
d876f532 852
fe0b1e85 853#define _FP_FRAC_COPY_4_1(D, S) \
1e145589
JM
854 do \
855 { \
856 D##_f[0] = S##_f; \
857 D##_f[1] = D##_f[2] = D##_f[3] = 0; \
858 } \
859 while (0)
fe0b1e85
RM
860
861#define _FP_FRAC_COPY_4_2(D, S) \
1e145589
JM
862 do \
863 { \
864 D##_f[0] = S##_f0; \
865 D##_f[1] = S##_f1; \
866 D##_f[2] = D##_f[3] = 0; \
867 } \
868 while (0)
37002cbc 869
51ca9e29 870#define _FP_FRAC_COPY_4_4(D, S) _FP_FRAC_COPY_4 (D, S)