Fix memory handling in strxfrm_l [BZ #16009]
[platform/upstream/glibc.git] / soft-fp / extended.h
1 /* Software floating-point emulation.
2    Definitions for IEEE Extended Precision.
3    Copyright (C) 1999-2015 Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5    Contributed by Jakub Jelinek (jj@ultra.linux.cz).
6
7    The GNU C Library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public
9    License as published by the Free Software Foundation; either
10    version 2.1 of the License, or (at your option) any later version.
11
12    In addition to the permissions in the GNU Lesser General Public
13    License, the Free Software Foundation gives you unlimited
14    permission to link the compiled version of this file into
15    combinations with other programs, and to distribute those
16    combinations without any restriction coming from the use of this
17    file.  (The Lesser General Public License restrictions do apply in
18    other respects; for example, they cover modification of the file,
19    and distribution when not linked into a combine executable.)
20
21    The GNU C Library is distributed in the hope that it will be useful,
22    but WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24    Lesser General Public License for more details.
25
26    You should have received a copy of the GNU Lesser General Public
27    License along with the GNU C Library; if not, see
28    <http://www.gnu.org/licenses/>.  */
29
30 #if _FP_W_TYPE_SIZE < 32
31 # error "Here's a nickel, kid. Go buy yourself a real computer."
32 #endif
33
34 #if _FP_W_TYPE_SIZE < 64
35 # define _FP_FRACTBITS_E        (4*_FP_W_TYPE_SIZE)
36 # define _FP_FRACTBITS_DW_E     (8*_FP_W_TYPE_SIZE)
37 #else
38 # define _FP_FRACTBITS_E        (2*_FP_W_TYPE_SIZE)
39 # define _FP_FRACTBITS_DW_E     (4*_FP_W_TYPE_SIZE)
40 #endif
41
42 #define _FP_FRACBITS_E          64
43 #define _FP_FRACXBITS_E         (_FP_FRACTBITS_E - _FP_FRACBITS_E)
44 #define _FP_WFRACBITS_E         (_FP_WORKBITS + _FP_FRACBITS_E)
45 #define _FP_WFRACXBITS_E        (_FP_FRACTBITS_E - _FP_WFRACBITS_E)
46 #define _FP_EXPBITS_E           15
47 #define _FP_EXPBIAS_E           16383
48 #define _FP_EXPMAX_E            32767
49
50 #define _FP_QNANBIT_E           \
51         ((_FP_W_TYPE) 1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE)
52 #define _FP_QNANBIT_SH_E                \
53         ((_FP_W_TYPE) 1 << (_FP_FRACBITS_E-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
54 #define _FP_IMPLBIT_E           \
55         ((_FP_W_TYPE) 1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE)
56 #define _FP_IMPLBIT_SH_E                \
57         ((_FP_W_TYPE) 1 << (_FP_FRACBITS_E-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
58 #define _FP_OVERFLOW_E          \
59         ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE))
60
61 #define _FP_WFRACBITS_DW_E      (2 * _FP_WFRACBITS_E)
62 #define _FP_WFRACXBITS_DW_E     (_FP_FRACTBITS_DW_E - _FP_WFRACBITS_DW_E)
63 #define _FP_HIGHBIT_DW_E        \
64   ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_DW_E - 1) % _FP_W_TYPE_SIZE)
65
66 typedef float XFtype __attribute__ ((mode (XF)));
67
68 #if _FP_W_TYPE_SIZE < 64
69
70 union _FP_UNION_E
71 {
72   XFtype flt;
73   struct _FP_STRUCT_LAYOUT
74   {
75 # if __BYTE_ORDER == __BIG_ENDIAN
76     unsigned long pad1 : _FP_W_TYPE_SIZE;
77     unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
78     unsigned long sign : 1;
79     unsigned long exp : _FP_EXPBITS_E;
80     unsigned long frac1 : _FP_W_TYPE_SIZE;
81     unsigned long frac0 : _FP_W_TYPE_SIZE;
82 # else
83     unsigned long frac0 : _FP_W_TYPE_SIZE;
84     unsigned long frac1 : _FP_W_TYPE_SIZE;
85     unsigned exp : _FP_EXPBITS_E;
86     unsigned sign : 1;
87 # endif /* not bigendian */
88   } bits __attribute__ ((packed));
89 };
90
91
92 # define FP_DECL_E(X)           _FP_DECL (4, X)
93
94 # define FP_UNPACK_RAW_E(X, val)                        \
95   do                                                    \
96     {                                                   \
97       union _FP_UNION_E FP_UNPACK_RAW_E_flo;            \
98       FP_UNPACK_RAW_E_flo.flt = (val);                  \
99                                                         \
100       X##_f[2] = 0;                                     \
101       X##_f[3] = 0;                                     \
102       X##_f[0] = FP_UNPACK_RAW_E_flo.bits.frac0;        \
103       X##_f[1] = FP_UNPACK_RAW_E_flo.bits.frac1;        \
104       X##_e  = FP_UNPACK_RAW_E_flo.bits.exp;            \
105       X##_s  = FP_UNPACK_RAW_E_flo.bits.sign;           \
106     }                                                   \
107   while (0)
108
109 # define FP_UNPACK_RAW_EP(X, val)                       \
110   do                                                    \
111     {                                                   \
112       union _FP_UNION_E *FP_UNPACK_RAW_EP_flo           \
113         = (union _FP_UNION_E *) (val);                  \
114                                                         \
115       X##_f[2] = 0;                                     \
116       X##_f[3] = 0;                                     \
117       X##_f[0] = FP_UNPACK_RAW_EP_flo->bits.frac0;      \
118       X##_f[1] = FP_UNPACK_RAW_EP_flo->bits.frac1;      \
119       X##_e  = FP_UNPACK_RAW_EP_flo->bits.exp;          \
120       X##_s  = FP_UNPACK_RAW_EP_flo->bits.sign;         \
121     }                                                   \
122   while (0)
123
124 # define FP_PACK_RAW_E(val, X)                  \
125   do                                            \
126     {                                           \
127       union _FP_UNION_E FP_PACK_RAW_E_flo;      \
128                                                 \
129       if (X##_e)                                \
130         X##_f[1] |= _FP_IMPLBIT_E;              \
131       else                                      \
132         X##_f[1] &= ~(_FP_IMPLBIT_E);           \
133       FP_PACK_RAW_E_flo.bits.frac0 = X##_f[0];  \
134       FP_PACK_RAW_E_flo.bits.frac1 = X##_f[1];  \
135       FP_PACK_RAW_E_flo.bits.exp   = X##_e;     \
136       FP_PACK_RAW_E_flo.bits.sign  = X##_s;     \
137                                                 \
138       (val) = FP_PACK_RAW_E_flo.flt;            \
139     }                                           \
140   while (0)
141
142 # define FP_PACK_RAW_EP(val, X)                         \
143   do                                                    \
144     {                                                   \
145       if (!FP_INHIBIT_RESULTS)                          \
146         {                                               \
147           union _FP_UNION_E *FP_PACK_RAW_EP_flo         \
148             = (union _FP_UNION_E *) (val);              \
149                                                         \
150           if (X##_e)                                    \
151             X##_f[1] |= _FP_IMPLBIT_E;                  \
152           else                                          \
153             X##_f[1] &= ~(_FP_IMPLBIT_E);               \
154           FP_PACK_RAW_EP_flo->bits.frac0 = X##_f[0];    \
155           FP_PACK_RAW_EP_flo->bits.frac1 = X##_f[1];    \
156           FP_PACK_RAW_EP_flo->bits.exp   = X##_e;       \
157           FP_PACK_RAW_EP_flo->bits.sign  = X##_s;       \
158         }                                               \
159     }                                                   \
160   while (0)
161
162 # define FP_UNPACK_E(X, val)                    \
163   do                                            \
164     {                                           \
165       FP_UNPACK_RAW_E (X, (val));               \
166       _FP_UNPACK_CANONICAL (E, 4, X);           \
167     }                                           \
168   while (0)
169
170 # define FP_UNPACK_EP(X, val)                   \
171   do                                            \
172     {                                           \
173       FP_UNPACK_RAW_EP (X, (val));              \
174       _FP_UNPACK_CANONICAL (E, 4, X);           \
175     }                                           \
176   while (0)
177
178 # define FP_UNPACK_SEMIRAW_E(X, val)            \
179   do                                            \
180     {                                           \
181       FP_UNPACK_RAW_E (X, (val));               \
182       _FP_UNPACK_SEMIRAW (E, 4, X);             \
183     }                                           \
184   while (0)
185
186 # define FP_UNPACK_SEMIRAW_EP(X, val)           \
187   do                                            \
188     {                                           \
189       FP_UNPACK_RAW_EP (X, (val));              \
190       _FP_UNPACK_SEMIRAW (E, 4, X);             \
191     }                                           \
192   while (0)
193
194 # define FP_PACK_E(val, X)                      \
195   do                                            \
196     {                                           \
197       _FP_PACK_CANONICAL (E, 4, X);             \
198       FP_PACK_RAW_E ((val), X);                 \
199     }                                           \
200   while (0)
201
202 # define FP_PACK_EP(val, X)                     \
203   do                                            \
204     {                                           \
205       _FP_PACK_CANONICAL (E, 4, X);             \
206       FP_PACK_RAW_EP ((val), X);                \
207     }                                           \
208   while (0)
209
210 # define FP_PACK_SEMIRAW_E(val, X)              \
211   do                                            \
212     {                                           \
213       _FP_PACK_SEMIRAW (E, 4, X);               \
214       FP_PACK_RAW_E ((val), X);                 \
215     }                                           \
216   while (0)
217
218 # define FP_PACK_SEMIRAW_EP(val, X)             \
219   do                                            \
220     {                                           \
221       _FP_PACK_SEMIRAW (E, 4, X);               \
222       FP_PACK_RAW_EP ((val), X);                \
223     }                                           \
224   while (0)
225
226 # define FP_ISSIGNAN_E(X)       _FP_ISSIGNAN (E, 4, X)
227 # define FP_NEG_E(R, X)         _FP_NEG (E, 4, R, X)
228 # define FP_ADD_E(R, X, Y)      _FP_ADD (E, 4, R, X, Y)
229 # define FP_SUB_E(R, X, Y)      _FP_SUB (E, 4, R, X, Y)
230 # define FP_MUL_E(R, X, Y)      _FP_MUL (E, 4, R, X, Y)
231 # define FP_DIV_E(R, X, Y)      _FP_DIV (E, 4, R, X, Y)
232 # define FP_SQRT_E(R, X)        _FP_SQRT (E, 4, R, X)
233 # define FP_FMA_E(R, X, Y, Z)   _FP_FMA (E, 4, 8, R, X, Y, Z)
234
235 /* Square root algorithms:
236    We have just one right now, maybe Newton approximation
237    should be added for those machines where division is fast.
238    This has special _E version because standard _4 square
239    root would not work (it has to start normally with the
240    second word and not the first), but as we have to do it
241    anyway, we optimize it by doing most of the calculations
242    in two UWtype registers instead of four.  */
243
244 # define _FP_SQRT_MEAT_E(R, S, T, X, q)                 \
245   do                                                    \
246     {                                                   \
247       (q) = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1);    \
248       _FP_FRAC_SRL_4 (X, (_FP_WORKBITS));               \
249       while (q)                                         \
250         {                                               \
251           T##_f[1] = S##_f[1] + (q);                    \
252           if (T##_f[1] <= X##_f[1])                     \
253             {                                           \
254               S##_f[1] = T##_f[1] + (q);                \
255               X##_f[1] -= T##_f[1];                     \
256               R##_f[1] += (q);                          \
257             }                                           \
258           _FP_FRAC_SLL_2 (X, 1);                        \
259           (q) >>= 1;                                    \
260         }                                               \
261       (q) = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1);    \
262       while (q)                                         \
263         {                                               \
264           T##_f[0] = S##_f[0] + (q);                    \
265           T##_f[1] = S##_f[1];                          \
266           if (T##_f[1] < X##_f[1]                       \
267               || (T##_f[1] == X##_f[1]                  \
268                   && T##_f[0] <= X##_f[0]))             \
269             {                                           \
270               S##_f[0] = T##_f[0] + (q);                \
271               S##_f[1] += (T##_f[0] > S##_f[0]);        \
272               _FP_FRAC_DEC_2 (X, T);                    \
273               R##_f[0] += (q);                          \
274             }                                           \
275           _FP_FRAC_SLL_2 (X, 1);                        \
276           (q) >>= 1;                                    \
277         }                                               \
278       _FP_FRAC_SLL_4 (R, (_FP_WORKBITS));               \
279       if (X##_f[0] | X##_f[1])                          \
280         {                                               \
281           if (S##_f[1] < X##_f[1]                       \
282               || (S##_f[1] == X##_f[1]                  \
283                   && S##_f[0] < X##_f[0]))              \
284             R##_f[0] |= _FP_WORK_ROUND;                 \
285           R##_f[0] |= _FP_WORK_STICKY;                  \
286         }                                               \
287     }                                                   \
288   while (0)
289
290 # define FP_CMP_E(r, X, Y, un, ex)      _FP_CMP (E, 4, (r), X, Y, (un), (ex))
291 # define FP_CMP_EQ_E(r, X, Y, ex)       _FP_CMP_EQ (E, 4, (r), X, Y, (ex))
292 # define FP_CMP_UNORD_E(r, X, Y, ex)    _FP_CMP_UNORD (E, 4, (r), X, Y, (ex))
293
294 # define FP_TO_INT_E(r, X, rsz, rsg)    _FP_TO_INT (E, 4, (r), X, (rsz), (rsg))
295 # define FP_TO_INT_ROUND_E(r, X, rsz, rsg)      \
296   _FP_TO_INT_ROUND (E, 4, (r), X, (rsz), (rsg))
297 # define FP_FROM_INT_E(X, r, rs, rt)    _FP_FROM_INT (E, 4, X, (r), (rs), rt)
298
299 # define _FP_FRAC_HIGH_E(X)     (X##_f[2])
300 # define _FP_FRAC_HIGH_RAW_E(X) (X##_f[1])
301
302 # define _FP_FRAC_HIGH_DW_E(X)  (X##_f[4])
303
304 #else   /* not _FP_W_TYPE_SIZE < 64 */
305 union _FP_UNION_E
306 {
307   XFtype flt;
308   struct _FP_STRUCT_LAYOUT
309   {
310 # if __BYTE_ORDER == __BIG_ENDIAN
311     _FP_W_TYPE pad  : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
312     unsigned sign   : 1;
313     unsigned exp    : _FP_EXPBITS_E;
314     _FP_W_TYPE frac : _FP_W_TYPE_SIZE;
315 # else
316     _FP_W_TYPE frac : _FP_W_TYPE_SIZE;
317     unsigned exp    : _FP_EXPBITS_E;
318     unsigned sign   : 1;
319 # endif
320   } bits;
321 };
322
323 # define FP_DECL_E(X)           _FP_DECL (2, X)
324
325 # define FP_UNPACK_RAW_E(X, val)                \
326   do                                            \
327     {                                           \
328       union _FP_UNION_E FP_UNPACK_RAW_E_flo;    \
329       FP_UNPACK_RAW_E_flo.flt = (val);          \
330                                                 \
331       X##_f0 = FP_UNPACK_RAW_E_flo.bits.frac;   \
332       X##_f1 = 0;                               \
333       X##_e = FP_UNPACK_RAW_E_flo.bits.exp;     \
334       X##_s = FP_UNPACK_RAW_E_flo.bits.sign;    \
335     }                                           \
336   while (0)
337
338 # define FP_UNPACK_RAW_EP(X, val)               \
339   do                                            \
340     {                                           \
341       union _FP_UNION_E *FP_UNPACK_RAW_EP_flo   \
342         = (union _FP_UNION_E *) (val);          \
343                                                 \
344       X##_f0 = FP_UNPACK_RAW_EP_flo->bits.frac; \
345       X##_f1 = 0;                               \
346       X##_e = FP_UNPACK_RAW_EP_flo->bits.exp;   \
347       X##_s = FP_UNPACK_RAW_EP_flo->bits.sign;  \
348     }                                           \
349   while (0)
350
351 # define FP_PACK_RAW_E(val, X)                  \
352   do                                            \
353     {                                           \
354       union _FP_UNION_E FP_PACK_RAW_E_flo;      \
355                                                 \
356       if (X##_e)                                \
357         X##_f0 |= _FP_IMPLBIT_E;                \
358       else                                      \
359         X##_f0 &= ~(_FP_IMPLBIT_E);             \
360       FP_PACK_RAW_E_flo.bits.frac = X##_f0;     \
361       FP_PACK_RAW_E_flo.bits.exp  = X##_e;      \
362       FP_PACK_RAW_E_flo.bits.sign = X##_s;      \
363                                                 \
364       (val) = FP_PACK_RAW_E_flo.flt;            \
365     }                                           \
366   while (0)
367
368 # define FP_PACK_RAW_EP(fs, val, X)                     \
369   do                                                    \
370     {                                                   \
371       if (!FP_INHIBIT_RESULTS)                          \
372         {                                               \
373           union _FP_UNION_E *FP_PACK_RAW_EP_flo         \
374             = (union _FP_UNION_E *) (val);              \
375                                                         \
376           if (X##_e)                                    \
377             X##_f0 |= _FP_IMPLBIT_E;                    \
378           else                                          \
379             X##_f0 &= ~(_FP_IMPLBIT_E);                 \
380           FP_PACK_RAW_EP_flo->bits.frac = X##_f0;       \
381           FP_PACK_RAW_EP_flo->bits.exp  = X##_e;        \
382           FP_PACK_RAW_EP_flo->bits.sign = X##_s;        \
383         }                                               \
384     }                                                   \
385   while (0)
386
387
388 # define FP_UNPACK_E(X, val)                    \
389   do                                            \
390     {                                           \
391       FP_UNPACK_RAW_E (X, (val));               \
392       _FP_UNPACK_CANONICAL (E, 2, X);           \
393     }                                           \
394   while (0)
395
396 # define FP_UNPACK_EP(X, val)                   \
397   do                                            \
398     {                                           \
399       FP_UNPACK_RAW_EP (X, (val));              \
400       _FP_UNPACK_CANONICAL (E, 2, X);           \
401     }                                           \
402   while (0)
403
404 # define FP_UNPACK_SEMIRAW_E(X, val)            \
405   do                                            \
406     {                                           \
407       FP_UNPACK_RAW_E (X, (val));               \
408       _FP_UNPACK_SEMIRAW (E, 2, X);             \
409     }                                           \
410   while (0)
411
412 # define FP_UNPACK_SEMIRAW_EP(X, val)           \
413   do                                            \
414     {                                           \
415       FP_UNPACK_RAW_EP (X, (val));              \
416       _FP_UNPACK_SEMIRAW (E, 2, X);             \
417     }                                           \
418   while (0)
419
420 # define FP_PACK_E(val, X)                      \
421   do                                            \
422     {                                           \
423       _FP_PACK_CANONICAL (E, 2, X);             \
424       FP_PACK_RAW_E ((val), X);                 \
425     }                                           \
426   while (0)
427
428 # define FP_PACK_EP(val, X)                     \
429   do                                            \
430     {                                           \
431       _FP_PACK_CANONICAL (E, 2, X);             \
432       FP_PACK_RAW_EP ((val), X);                \
433     }                                           \
434   while (0)
435
436 # define FP_PACK_SEMIRAW_E(val, X)              \
437   do                                            \
438     {                                           \
439       _FP_PACK_SEMIRAW (E, 2, X);               \
440       FP_PACK_RAW_E ((val), X);                 \
441     }                                           \
442   while (0)
443
444 # define FP_PACK_SEMIRAW_EP(val, X)             \
445   do                                            \
446     {                                           \
447       _FP_PACK_SEMIRAW (E, 2, X);               \
448       FP_PACK_RAW_EP ((val), X);                \
449     }                                           \
450   while (0)
451
452 # define FP_ISSIGNAN_E(X)       _FP_ISSIGNAN (E, 2, X)
453 # define FP_NEG_E(R, X)         _FP_NEG (E, 2, R, X)
454 # define FP_ADD_E(R, X, Y)      _FP_ADD (E, 2, R, X, Y)
455 # define FP_SUB_E(R, X, Y)      _FP_SUB (E, 2, R, X, Y)
456 # define FP_MUL_E(R, X, Y)      _FP_MUL (E, 2, R, X, Y)
457 # define FP_DIV_E(R, X, Y)      _FP_DIV (E, 2, R, X, Y)
458 # define FP_SQRT_E(R, X)        _FP_SQRT (E, 2, R, X)
459 # define FP_FMA_E(R, X, Y, Z)   _FP_FMA (E, 2, 4, R, X, Y, Z)
460
461 /* Square root algorithms:
462    We have just one right now, maybe Newton approximation
463    should be added for those machines where division is fast.
464    We optimize it by doing most of the calculations
465    in one UWtype registers instead of two, although we don't
466    have to.  */
467 # define _FP_SQRT_MEAT_E(R, S, T, X, q)                 \
468   do                                                    \
469     {                                                   \
470       (q) = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1);    \
471       _FP_FRAC_SRL_2 (X, (_FP_WORKBITS));               \
472       while (q)                                         \
473         {                                               \
474           T##_f0 = S##_f0 + (q);                        \
475           if (T##_f0 <= X##_f0)                         \
476             {                                           \
477               S##_f0 = T##_f0 + (q);                    \
478               X##_f0 -= T##_f0;                         \
479               R##_f0 += (q);                            \
480             }                                           \
481           _FP_FRAC_SLL_1 (X, 1);                        \
482           (q) >>= 1;                                    \
483         }                                               \
484       _FP_FRAC_SLL_2 (R, (_FP_WORKBITS));               \
485       if (X##_f0)                                       \
486         {                                               \
487           if (S##_f0 < X##_f0)                          \
488             R##_f0 |= _FP_WORK_ROUND;                   \
489           R##_f0 |= _FP_WORK_STICKY;                    \
490         }                                               \
491     }                                                   \
492   while (0)
493
494 # define FP_CMP_E(r, X, Y, un, ex)      _FP_CMP (E, 2, (r), X, Y, (un), (ex))
495 # define FP_CMP_EQ_E(r, X, Y, ex)       _FP_CMP_EQ (E, 2, (r), X, Y, (ex))
496 # define FP_CMP_UNORD_E(r, X, Y, ex)    _FP_CMP_UNORD (E, 2, (r), X, Y, (ex))
497
498 # define FP_TO_INT_E(r, X, rsz, rsg)    _FP_TO_INT (E, 2, (r), X, (rsz), (rsg))
499 # define FP_TO_INT_ROUND_E(r, X, rsz, rsg)      \
500   _FP_TO_INT_ROUND (E, 2, (r), X, (rsz), (rsg))
501 # define FP_FROM_INT_E(X, r, rs, rt)    _FP_FROM_INT (E, 2, X, (r), (rs), rt)
502
503 # define _FP_FRAC_HIGH_E(X)     (X##_f1)
504 # define _FP_FRAC_HIGH_RAW_E(X) (X##_f0)
505
506 # define _FP_FRAC_HIGH_DW_E(X)  (X##_f[2])
507
508 #endif /* not _FP_W_TYPE_SIZE < 64 */