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