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