]> git.ipfire.org Git - thirdparty/glibc.git/blame - soft-fp/op-1.h
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / soft-fp / op-1.h
CommitLineData
d876f532
UD
1/* Software floating-point emulation.
2 Basic one-word fraction declaration and manipulation.
d4697bc9 3 Copyright (C) 1997-2014 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_1(X) _FP_W_TYPE X##_f
51ca9e29
JM
34#define _FP_FRAC_COPY_1(D, S) (D##_f = S##_f)
35#define _FP_FRAC_SET_1(X, I) (X##_f = I)
d876f532
UD
36#define _FP_FRAC_HIGH_1(X) (X##_f)
37#define _FP_FRAC_LOW_1(X) (X##_f)
51ca9e29 38#define _FP_FRAC_WORD_1(X, w) (X##_f)
d876f532 39
51ca9e29
JM
40#define _FP_FRAC_ADDI_1(X, I) (X##_f += I)
41#define _FP_FRAC_SLL_1(X, N) \
1e145589
JM
42 do \
43 { \
51ca9e29 44 if (__builtin_constant_p (N) && (N) == 1) \
1e145589
JM
45 X##_f += X##_f; \
46 else \
47 X##_f <<= (N); \
48 } \
49 while (0)
51ca9e29 50#define _FP_FRAC_SRL_1(X, N) (X##_f >>= N)
d876f532
UD
51
52/* Right shift with sticky-lsb. */
51ca9e29
JM
53#define _FP_FRAC_SRST_1(X, S, N, sz) __FP_FRAC_SRST_1 (X##_f, S, N, sz)
54#define _FP_FRAC_SRS_1(X, N, sz) __FP_FRAC_SRS_1 (X##_f, N, sz)
d876f532 55
51ca9e29 56#define __FP_FRAC_SRST_1(X, S, N, sz) \
1e145589
JM
57 do \
58 { \
51ca9e29 59 S = (__builtin_constant_p (N) && (N) == 1 \
1e145589
JM
60 ? X & 1 \
61 : (X << (_FP_W_TYPE_SIZE - (N))) != 0); \
62 X = X >> (N); \
63 } \
64 while (0)
65
51ca9e29
JM
66#define __FP_FRAC_SRS_1(X, N, sz) \
67 (X = (X >> (N) | (__builtin_constant_p (N) && (N) == 1 \
1e145589
JM
68 ? X & 1 \
69 : (X << (_FP_W_TYPE_SIZE - (N))) != 0)))
d876f532 70
51ca9e29
JM
71#define _FP_FRAC_ADD_1(R, X, Y) (R##_f = X##_f + Y##_f)
72#define _FP_FRAC_SUB_1(R, X, Y) (R##_f = X##_f - Y##_f)
73#define _FP_FRAC_DEC_1(X, Y) (X##_f -= Y##_f)
74#define _FP_FRAC_CLZ_1(z, X) __FP_CLZ (z, X##_f)
d876f532
UD
75
76/* Predicates */
51ca9e29 77#define _FP_FRAC_NEGP_1(X) ((_FP_WS_TYPE) X##_f < 0)
d876f532 78#define _FP_FRAC_ZEROP_1(X) (X##_f == 0)
51ca9e29
JM
79#define _FP_FRAC_OVERP_1(fs, X) (X##_f & _FP_OVERFLOW_##fs)
80#define _FP_FRAC_CLEAR_OVERP_1(fs, X) (X##_f &= ~_FP_OVERFLOW_##fs)
81#define _FP_FRAC_HIGHBIT_DW_1(fs, X) (X##_f & _FP_HIGHBIT_DW_##fs)
d876f532
UD
82#define _FP_FRAC_EQ_1(X, Y) (X##_f == Y##_f)
83#define _FP_FRAC_GE_1(X, Y) (X##_f >= Y##_f)
84#define _FP_FRAC_GT_1(X, Y) (X##_f > Y##_f)
85
86#define _FP_ZEROFRAC_1 0
87#define _FP_MINFRAC_1 1
51ca9e29 88#define _FP_MAXFRAC_1 (~(_FP_WS_TYPE) 0)
d876f532
UD
89
90/*
91 * Unpack the raw bits of a native fp value. Do not classify or
92 * normalize the data.
93 */
94
1e145589
JM
95#define _FP_UNPACK_RAW_1(fs, X, val) \
96 do \
97 { \
98 union _FP_UNION_##fs _flo; \
99 _flo.flt = (val); \
100 \
101 X##_f = _flo.bits.frac; \
102 X##_e = _flo.bits.exp; \
103 X##_s = _flo.bits.sign; \
104 } \
105 while (0)
106
107#define _FP_UNPACK_RAW_1_P(fs, X, val) \
108 do \
109 { \
51ca9e29 110 union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *) (val); \
1e145589
JM
111 \
112 X##_f = _flo->bits.frac; \
113 X##_e = _flo->bits.exp; \
114 X##_s = _flo->bits.sign; \
115 } \
116 while (0)
d876f532
UD
117
118/*
119 * Repack the raw bits of a native fp value.
120 */
121
1e145589
JM
122#define _FP_PACK_RAW_1(fs, val, X) \
123 do \
124 { \
125 union _FP_UNION_##fs _flo; \
126 \
127 _flo.bits.frac = X##_f; \
128 _flo.bits.exp = X##_e; \
129 _flo.bits.sign = X##_s; \
130 \
131 (val) = _flo.flt; \
132 } \
133 while (0)
134
135#define _FP_PACK_RAW_1_P(fs, val, X) \
136 do \
137 { \
51ca9e29 138 union _FP_UNION_##fs *_flo = (union _FP_UNION_##fs *) (val); \
1e145589
JM
139 \
140 _flo->bits.frac = X##_f; \
141 _flo->bits.exp = X##_e; \
142 _flo->bits.sign = X##_s; \
143 } \
144 while (0)
d876f532
UD
145
146
147/*
148 * Multiplication algorithms:
149 */
150
151/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the
152 multiplication immediately. */
153
1e145589
JM
154#define _FP_MUL_MEAT_DW_1_imm(wfracbits, R, X, Y) \
155 do \
156 { \
157 R##_f = X##_f * Y##_f; \
158 } \
159 while (0)
77f01ab5
JM
160
161#define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y) \
1e145589
JM
162 do \
163 { \
51ca9e29 164 _FP_MUL_MEAT_DW_1_imm (wfracbits, R, X, Y); \
1e145589
JM
165 /* Normalize since we know where the msb of the multiplicands \
166 were (bit B), we know that the msb of the of the product is \
167 at either 2B or 2B-1. */ \
51ca9e29 168 _FP_FRAC_SRS_1 (R, wfracbits-1, 2*wfracbits); \
1e145589
JM
169 } \
170 while (0)
d876f532
UD
171
172/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
173
1e145589
JM
174#define _FP_MUL_MEAT_DW_1_wide(wfracbits, R, X, Y, doit) \
175 do \
176 { \
51ca9e29 177 doit (R##_f1, R##_f0, X##_f, Y##_f); \
1e145589
JM
178 } \
179 while (0)
77f01ab5 180
d876f532 181#define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit) \
1e145589
JM
182 do \
183 { \
51ca9e29
JM
184 _FP_FRAC_DECL_2 (_Z); \
185 _FP_MUL_MEAT_DW_1_wide (wfracbits, _Z, X, Y, doit); \
1e145589
JM
186 /* Normalize since we know where the msb of the multiplicands \
187 were (bit B), we know that the msb of the of the product is \
188 at either 2B or 2B-1. */ \
51ca9e29 189 _FP_FRAC_SRS_2 (_Z, wfracbits-1, 2*wfracbits); \
1e145589
JM
190 R##_f = _Z_f0; \
191 } \
192 while (0)
d876f532
UD
193
194/* Finally, a simple widening multiply algorithm. What fun! */
195
77f01ab5 196#define _FP_MUL_MEAT_DW_1_hard(wfracbits, R, X, Y) \
1e145589
JM
197 do \
198 { \
199 _FP_W_TYPE _xh, _xl, _yh, _yl; \
51ca9e29 200 _FP_FRAC_DECL_2 (_a); \
d876f532 201 \
1e145589
JM
202 /* split the words in half */ \
203 _xh = X##_f >> (_FP_W_TYPE_SIZE/2); \
51ca9e29 204 _xl = X##_f & (((_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2)) - 1); \
1e145589 205 _yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \
51ca9e29 206 _yl = Y##_f & (((_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2)) - 1); \
d876f532 207 \
1e145589
JM
208 /* multiply the pieces */ \
209 R##_f0 = _xl * _yl; \
210 _a_f0 = _xh * _yl; \
211 _a_f1 = _xl * _yh; \
212 R##_f1 = _xh * _yh; \
d876f532 213 \
1e145589
JM
214 /* reassemble into two full words */ \
215 if ((_a_f0 += _a_f1) < _a_f1) \
51ca9e29 216 R##_f1 += (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2); \
1e145589
JM
217 _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \
218 _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \
51ca9e29 219 _FP_FRAC_ADD_2 (R, R, _a); \
1e145589
JM
220 } \
221 while (0)
222
223#define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y) \
224 do \
225 { \
51ca9e29
JM
226 _FP_FRAC_DECL_2 (_z); \
227 _FP_MUL_MEAT_DW_1_hard (wfracbits, _z, X, Y); \
1e145589
JM
228 \
229 /* normalize */ \
51ca9e29 230 _FP_FRAC_SRS_2 (_z, wfracbits - 1, 2*wfracbits); \
1e145589
JM
231 R##_f = _z_f0; \
232 } \
233 while (0)
d876f532
UD
234
235
236/*
237 * Division algorithms:
238 */
239
240/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the
241 division immediately. Give this macro either _FP_DIV_HELP_imm for
242 C primitives or _FP_DIV_HELP_ldiv for the ISO function. Which you
243 choose will depend on what the compiler does with divrem4. */
244
1e145589
JM
245#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \
246 do \
247 { \
248 _FP_W_TYPE _q, _r; \
249 X##_f <<= (X##_f < Y##_f \
250 ? R##_e--, _FP_WFRACBITS_##fs \
251 : _FP_WFRACBITS_##fs - 1); \
51ca9e29 252 doit (_q, _r, X##_f, Y##_f); \
1e145589
JM
253 R##_f = _q | (_r != 0); \
254 } \
255 while (0)
d876f532
UD
256
257/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
258 that may be useful in this situation. This first is for a primitive
259 that requires normalization, the second for one that does not. Look
260 for UDIV_NEEDS_NORMALIZATION to tell which your machine needs. */
261
262#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \
1e145589
JM
263 do \
264 { \
265 _FP_W_TYPE _nh, _nl, _q, _r, _y; \
d876f532 266 \
1e145589
JM
267 /* Normalize Y -- i.e. make the most significant bit set. */ \
268 _y = Y##_f << _FP_WFRACXBITS_##fs; \
d876f532 269 \
1e145589
JM
270 /* Shift X op correspondingly high, that is, up one full word. */ \
271 if (X##_f < Y##_f) \
272 { \
273 R##_e--; \
274 _nl = 0; \
275 _nh = X##_f; \
276 } \
277 else \
278 { \
279 _nl = X##_f << (_FP_W_TYPE_SIZE - 1); \
280 _nh = X##_f >> 1; \
281 } \
350635a5 282 \
51ca9e29 283 udiv_qrnnd (_q, _r, _nh, _nl, _y); \
1e145589
JM
284 R##_f = _q | (_r != 0); \
285 } \
286 while (0)
d876f532
UD
287
288#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \
1e145589
JM
289 do \
290 { \
291 _FP_W_TYPE _nh, _nl, _q, _r; \
292 if (X##_f < Y##_f) \
293 { \
294 R##_e--; \
295 _nl = X##_f << _FP_WFRACBITS_##fs; \
296 _nh = X##_f >> _FP_WFRACXBITS_##fs; \
297 } \
298 else \
299 { \
300 _nl = X##_f << (_FP_WFRACBITS_##fs - 1); \
301 _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \
302 } \
51ca9e29 303 udiv_qrnnd (_q, _r, _nh, _nl, Y##_f); \
1e145589
JM
304 R##_f = _q | (_r != 0); \
305 } \
306 while (0)
9c84384c
JM
307
308
d876f532
UD
309/*
310 * Square root algorithms:
311 * We have just one right now, maybe Newton approximation
312 * should be added for those machines where division is fast.
313 */
9c84384c 314
1e145589
JM
315#define _FP_SQRT_MEAT_1(R, S, T, X, q) \
316 do \
317 { \
318 while (q != _FP_WORK_ROUND) \
319 { \
320 T##_f = S##_f + q; \
321 if (T##_f <= X##_f) \
322 { \
323 S##_f = T##_f + q; \
324 X##_f -= T##_f; \
325 R##_f += q; \
326 } \
51ca9e29 327 _FP_FRAC_SLL_1 (X, 1); \
1e145589
JM
328 q >>= 1; \
329 } \
330 if (X##_f) \
331 { \
332 if (S##_f < X##_f) \
333 R##_f |= _FP_WORK_ROUND; \
334 R##_f |= _FP_WORK_STICKY; \
335 } \
336 } \
337 while (0)
d876f532
UD
338
339/*
9c84384c 340 * Assembly/disassembly for converting to/from integral types.
d876f532
UD
341 * No shifting or overflow handled here.
342 */
343
344#define _FP_FRAC_ASSEMBLE_1(r, X, rsize) (r = X##_f)
345#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize) (X##_f = r)
346
347
348/*
349 * Convert FP values between word sizes
350 */
351
fe0b1e85 352#define _FP_FRAC_COPY_1_1(D, S) (D##_f = S##_f)