Rename soft-fp op-[1248].h variables to avoid risk of shadowing.
[platform/upstream/glibc.git] / soft-fp / op-1.h
1 /* Software floating-point emulation.
2    Basic one-word fraction declaration and manipulation.
3    Copyright (C) 1997-2014 Free Software Foundation, Inc.
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
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.
14
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
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
27    Lesser General Public License for more details.
28
29    You should have received a copy of the GNU Lesser General Public
30    License along with the GNU C Library; if not, see
31    <http://www.gnu.org/licenses/>.  */
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     {                                           \
44       if (__builtin_constant_p (N) && (N) == 1) \
45         X##_f += X##_f;                         \
46       else                                      \
47         X##_f <<= (N);                          \
48     }                                           \
49   while (0)
50 #define _FP_FRAC_SRL_1(X, N)    (X##_f >>= N)
51
52 /* Right shift with sticky-lsb.  */
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)
55
56 #define __FP_FRAC_SRST_1(X, S, N, sz)                   \
57   do                                                    \
58     {                                                   \
59       S = (__builtin_constant_p (N) && (N) == 1         \
60            ? X & 1                                      \
61            : (X << (_FP_W_TYPE_SIZE - (N))) != 0);      \
62       X = X >> (N);                                     \
63     }                                                   \
64   while (0)
65
66 #define __FP_FRAC_SRS_1(X, N, sz)                               \
67   (X = (X >> (N) | (__builtin_constant_p (N) && (N) == 1        \
68                     ? X & 1                                     \
69                     : (X << (_FP_W_TYPE_SIZE - (N))) != 0)))
70
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)
75
76 /* Predicates */
77 #define _FP_FRAC_NEGP_1(X)      ((_FP_WS_TYPE) X##_f < 0)
78 #define _FP_FRAC_ZEROP_1(X)     (X##_f == 0)
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)
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
88 #define _FP_MAXFRAC_1           (~(_FP_WS_TYPE) 0)
89
90 /*
91  * Unpack the raw bits of a native fp value.  Do not classify or
92  * normalize the data.
93  */
94
95 #define _FP_UNPACK_RAW_1(fs, X, val)                    \
96   do                                                    \
97     {                                                   \
98       union _FP_UNION_##fs _FP_UNPACK_RAW_1_flo;        \
99       _FP_UNPACK_RAW_1_flo.flt = (val);                 \
100                                                         \
101       X##_f = _FP_UNPACK_RAW_1_flo.bits.frac;           \
102       X##_e = _FP_UNPACK_RAW_1_flo.bits.exp;            \
103       X##_s = _FP_UNPACK_RAW_1_flo.bits.sign;           \
104     }                                                   \
105   while (0)
106
107 #define _FP_UNPACK_RAW_1_P(fs, X, val)                  \
108   do                                                    \
109     {                                                   \
110       union _FP_UNION_##fs *_FP_UNPACK_RAW_1_P_flo      \
111         = (union _FP_UNION_##fs *) (val);               \
112                                                         \
113       X##_f = _FP_UNPACK_RAW_1_P_flo->bits.frac;        \
114       X##_e = _FP_UNPACK_RAW_1_P_flo->bits.exp;         \
115       X##_s = _FP_UNPACK_RAW_1_P_flo->bits.sign;        \
116     }                                                   \
117   while (0)
118
119 /*
120  * Repack the raw bits of a native fp value.
121  */
122
123 #define _FP_PACK_RAW_1(fs, val, X)              \
124   do                                            \
125     {                                           \
126       union _FP_UNION_##fs _FP_PACK_RAW_1_flo;  \
127                                                 \
128       _FP_PACK_RAW_1_flo.bits.frac = X##_f;     \
129       _FP_PACK_RAW_1_flo.bits.exp  = X##_e;     \
130       _FP_PACK_RAW_1_flo.bits.sign = X##_s;     \
131                                                 \
132       (val) = _FP_PACK_RAW_1_flo.flt;           \
133     }                                           \
134   while (0)
135
136 #define _FP_PACK_RAW_1_P(fs, val, X)                    \
137   do                                                    \
138     {                                                   \
139       union _FP_UNION_##fs *_FP_PACK_RAW_1_P_flo        \
140         = (union _FP_UNION_##fs *) (val);               \
141                                                         \
142       _FP_PACK_RAW_1_P_flo->bits.frac = X##_f;          \
143       _FP_PACK_RAW_1_P_flo->bits.exp  = X##_e;          \
144       _FP_PACK_RAW_1_P_flo->bits.sign = X##_s;          \
145     }                                                   \
146   while (0)
147
148
149 /*
150  * Multiplication algorithms:
151  */
152
153 /* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
154    multiplication immediately.  */
155
156 #define _FP_MUL_MEAT_DW_1_imm(wfracbits, R, X, Y)       \
157   do                                                    \
158     {                                                   \
159       R##_f = X##_f * Y##_f;                            \
160     }                                                   \
161   while (0)
162
163 #define _FP_MUL_MEAT_1_imm(wfracbits, R, X, Y)                          \
164   do                                                                    \
165     {                                                                   \
166       _FP_MUL_MEAT_DW_1_imm (wfracbits, R, X, Y);                       \
167       /* Normalize since we know where the msb of the multiplicands     \
168          were (bit B), we know that the msb of the of the product is    \
169          at either 2B or 2B-1.  */                                      \
170       _FP_FRAC_SRS_1 (R, wfracbits-1, 2*wfracbits);                     \
171     }                                                                   \
172   while (0)
173
174 /* Given a 1W * 1W => 2W primitive, do the extended multiplication.  */
175
176 #define _FP_MUL_MEAT_DW_1_wide(wfracbits, R, X, Y, doit)        \
177   do                                                            \
178     {                                                           \
179       doit (R##_f1, R##_f0, X##_f, Y##_f);                      \
180     }                                                           \
181   while (0)
182
183 #define _FP_MUL_MEAT_1_wide(wfracbits, R, X, Y, doit)                   \
184   do                                                                    \
185     {                                                                   \
186       _FP_FRAC_DECL_2 (_FP_MUL_MEAT_1_wide_Z);                          \
187       _FP_MUL_MEAT_DW_1_wide (wfracbits, _FP_MUL_MEAT_1_wide_Z,         \
188                               X, Y, doit);                              \
189       /* Normalize since we know where the msb of the multiplicands     \
190          were (bit B), we know that the msb of the of the product is    \
191          at either 2B or 2B-1.  */                                      \
192       _FP_FRAC_SRS_2 (_FP_MUL_MEAT_1_wide_Z, wfracbits-1, 2*wfracbits); \
193       R##_f = _FP_MUL_MEAT_1_wide_Z_f0;                                 \
194     }                                                                   \
195   while (0)
196
197 /* Finally, a simple widening multiply algorithm.  What fun!  */
198
199 #define _FP_MUL_MEAT_DW_1_hard(wfracbits, R, X, Y)                      \
200   do                                                                    \
201     {                                                                   \
202       _FP_W_TYPE _FP_MUL_MEAT_DW_1_hard_xh, _FP_MUL_MEAT_DW_1_hard_xl;  \
203       _FP_W_TYPE _FP_MUL_MEAT_DW_1_hard_yh, _FP_MUL_MEAT_DW_1_hard_yl;  \
204       _FP_FRAC_DECL_2 (_FP_MUL_MEAT_DW_1_hard_a);                       \
205                                                                         \
206       /* split the words in half */                                     \
207       _FP_MUL_MEAT_DW_1_hard_xh = X##_f >> (_FP_W_TYPE_SIZE/2);         \
208       _FP_MUL_MEAT_DW_1_hard_xl                                         \
209         = X##_f & (((_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2)) - 1);        \
210       _FP_MUL_MEAT_DW_1_hard_yh = Y##_f >> (_FP_W_TYPE_SIZE/2);         \
211       _FP_MUL_MEAT_DW_1_hard_yl                                         \
212         = Y##_f & (((_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2)) - 1);        \
213                                                                         \
214       /* multiply the pieces */                                         \
215       R##_f0 = _FP_MUL_MEAT_DW_1_hard_xl * _FP_MUL_MEAT_DW_1_hard_yl;   \
216       _FP_MUL_MEAT_DW_1_hard_a_f0                                       \
217         = _FP_MUL_MEAT_DW_1_hard_xh * _FP_MUL_MEAT_DW_1_hard_yl;        \
218       _FP_MUL_MEAT_DW_1_hard_a_f1                                       \
219         = _FP_MUL_MEAT_DW_1_hard_xl * _FP_MUL_MEAT_DW_1_hard_yh;        \
220       R##_f1 = _FP_MUL_MEAT_DW_1_hard_xh * _FP_MUL_MEAT_DW_1_hard_yh;   \
221                                                                         \
222       /* reassemble into two full words */                              \
223       if ((_FP_MUL_MEAT_DW_1_hard_a_f0 += _FP_MUL_MEAT_DW_1_hard_a_f1)  \
224           < _FP_MUL_MEAT_DW_1_hard_a_f1)                                \
225         R##_f1 += (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE/2);                \
226       _FP_MUL_MEAT_DW_1_hard_a_f1                                       \
227         = _FP_MUL_MEAT_DW_1_hard_a_f0 >> (_FP_W_TYPE_SIZE/2);           \
228       _FP_MUL_MEAT_DW_1_hard_a_f0                                       \
229         = _FP_MUL_MEAT_DW_1_hard_a_f0 << (_FP_W_TYPE_SIZE/2);           \
230       _FP_FRAC_ADD_2 (R, R, _FP_MUL_MEAT_DW_1_hard_a);                  \
231     }                                                                   \
232   while (0)
233
234 #define _FP_MUL_MEAT_1_hard(wfracbits, R, X, Y)                         \
235   do                                                                    \
236     {                                                                   \
237       _FP_FRAC_DECL_2 (_FP_MUL_MEAT_1_hard_z);                          \
238       _FP_MUL_MEAT_DW_1_hard (wfracbits, _FP_MUL_MEAT_1_hard_z, X, Y);  \
239                                                                         \
240       /* normalize */                                                   \
241       _FP_FRAC_SRS_2 (_FP_MUL_MEAT_1_hard_z,                            \
242                       wfracbits - 1, 2*wfracbits);                      \
243       R##_f = _FP_MUL_MEAT_1_hard_z_f0;                                 \
244     }                                                                   \
245   while (0)
246
247
248 /*
249  * Division algorithms:
250  */
251
252 /* Basic.  Assuming the host word size is >= 2*FRACBITS, we can do the
253    division immediately.  Give this macro either _FP_DIV_HELP_imm for
254    C primitives or _FP_DIV_HELP_ldiv for the ISO function.  Which you
255    choose will depend on what the compiler does with divrem4.  */
256
257 #define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit)                           \
258   do                                                                    \
259     {                                                                   \
260       _FP_W_TYPE _FP_DIV_MEAT_1_imm_q, _FP_DIV_MEAT_1_imm_r;            \
261       X##_f <<= (X##_f < Y##_f                                          \
262                  ? R##_e--, _FP_WFRACBITS_##fs                          \
263                  : _FP_WFRACBITS_##fs - 1);                             \
264       doit (_FP_DIV_MEAT_1_imm_q, _FP_DIV_MEAT_1_imm_r, X##_f, Y##_f);  \
265       R##_f = _FP_DIV_MEAT_1_imm_q | (_FP_DIV_MEAT_1_imm_r != 0);       \
266     }                                                                   \
267   while (0)
268
269 /* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
270    that may be useful in this situation.  This first is for a primitive
271    that requires normalization, the second for one that does not.  Look
272    for UDIV_NEEDS_NORMALIZATION to tell which your machine needs.  */
273
274 #define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y)                           \
275   do                                                                    \
276     {                                                                   \
277       _FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_nh;                           \
278       _FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_nl;                           \
279       _FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_q;                            \
280       _FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_r;                            \
281       _FP_W_TYPE _FP_DIV_MEAT_1_udiv_norm_y;                            \
282                                                                         \
283       /* Normalize Y -- i.e. make the most significant bit set.  */     \
284       _FP_DIV_MEAT_1_udiv_norm_y = Y##_f << _FP_WFRACXBITS_##fs;        \
285                                                                         \
286       /* Shift X op correspondingly high, that is, up one full word.  */ \
287       if (X##_f < Y##_f)                                                \
288         {                                                               \
289           R##_e--;                                                      \
290           _FP_DIV_MEAT_1_udiv_norm_nl = 0;                              \
291           _FP_DIV_MEAT_1_udiv_norm_nh = X##_f;                          \
292         }                                                               \
293       else                                                              \
294         {                                                               \
295           _FP_DIV_MEAT_1_udiv_norm_nl = X##_f << (_FP_W_TYPE_SIZE - 1); \
296           _FP_DIV_MEAT_1_udiv_norm_nh = X##_f >> 1;                     \
297         }                                                               \
298                                                                         \
299       udiv_qrnnd (_FP_DIV_MEAT_1_udiv_norm_q,                           \
300                   _FP_DIV_MEAT_1_udiv_norm_r,                           \
301                   _FP_DIV_MEAT_1_udiv_norm_nh,                          \
302                   _FP_DIV_MEAT_1_udiv_norm_nl,                          \
303                   _FP_DIV_MEAT_1_udiv_norm_y);                          \
304       R##_f = (_FP_DIV_MEAT_1_udiv_norm_q                               \
305                | (_FP_DIV_MEAT_1_udiv_norm_r != 0));                    \
306     }                                                                   \
307   while (0)
308
309 #define _FP_DIV_MEAT_1_udiv(fs, R, X, Y)                                \
310   do                                                                    \
311     {                                                                   \
312       _FP_W_TYPE _FP_DIV_MEAT_1_udiv_nh, _FP_DIV_MEAT_1_udiv_nl;        \
313       _FP_W_TYPE _FP_DIV_MEAT_1_udiv_q, _FP_DIV_MEAT_1_udiv_r;          \
314       if (X##_f < Y##_f)                                                \
315         {                                                               \
316           R##_e--;                                                      \
317           _FP_DIV_MEAT_1_udiv_nl = X##_f << _FP_WFRACBITS_##fs;         \
318           _FP_DIV_MEAT_1_udiv_nh = X##_f >> _FP_WFRACXBITS_##fs;        \
319         }                                                               \
320       else                                                              \
321         {                                                               \
322           _FP_DIV_MEAT_1_udiv_nl = X##_f << (_FP_WFRACBITS_##fs - 1);   \
323           _FP_DIV_MEAT_1_udiv_nh = X##_f >> (_FP_WFRACXBITS_##fs + 1);  \
324         }                                                               \
325       udiv_qrnnd (_FP_DIV_MEAT_1_udiv_q, _FP_DIV_MEAT_1_udiv_r,         \
326                   _FP_DIV_MEAT_1_udiv_nh, _FP_DIV_MEAT_1_udiv_nl,       \
327                   Y##_f);                                               \
328       R##_f = _FP_DIV_MEAT_1_udiv_q | (_FP_DIV_MEAT_1_udiv_r != 0);     \
329     }                                                                   \
330   while (0)
331
332
333 /*
334  * Square root algorithms:
335  * We have just one right now, maybe Newton approximation
336  * should be added for those machines where division is fast.
337  */
338
339 #define _FP_SQRT_MEAT_1(R, S, T, X, q)          \
340   do                                            \
341     {                                           \
342       while (q != _FP_WORK_ROUND)               \
343         {                                       \
344           T##_f = S##_f + q;                    \
345           if (T##_f <= X##_f)                   \
346             {                                   \
347               S##_f = T##_f + q;                \
348               X##_f -= T##_f;                   \
349               R##_f += q;                       \
350             }                                   \
351           _FP_FRAC_SLL_1 (X, 1);                \
352           q >>= 1;                              \
353         }                                       \
354       if (X##_f)                                \
355         {                                       \
356           if (S##_f < X##_f)                    \
357             R##_f |= _FP_WORK_ROUND;            \
358           R##_f |= _FP_WORK_STICKY;             \
359         }                                       \
360     }                                           \
361   while (0)
362
363 /*
364  * Assembly/disassembly for converting to/from integral types.
365  * No shifting or overflow handled here.
366  */
367
368 #define _FP_FRAC_ASSEMBLE_1(r, X, rsize)        (r = X##_f)
369 #define _FP_FRAC_DISASSEMBLE_1(X, r, rsize)     (X##_f = r)
370
371
372 /*
373  * Convert FP values between word sizes
374  */
375
376 #define _FP_FRAC_COPY_1_1(D, S)         (D##_f = S##_f)