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