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