Back to index

glibc  2.9
extended.h
Go to the documentation of this file.
00001 /* Software floating-point emulation.
00002    Definitions for IEEE Extended Precision.
00003    Copyright (C) 1999,2006,2007 Free Software Foundation, Inc.
00004    This file is part of the GNU C Library.
00005    Contributed by Jakub Jelinek (jj@ultra.linux.cz).
00006 
00007    The GNU C Library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public
00009    License as published by the Free Software Foundation; either
00010    version 2.1 of the License, or (at your option) any later version.
00011 
00012    In addition to the permissions in the GNU Lesser General Public
00013    License, the Free Software Foundation gives you unlimited
00014    permission to link the compiled version of this file into
00015    combinations with other programs, and to distribute those
00016    combinations without any restriction coming from the use of this
00017    file.  (The Lesser General Public License restrictions do apply in
00018    other respects; for example, they cover modification of the file,
00019    and distribution when not linked into a combine executable.)
00020 
00021    The GNU C Library is distributed in the hope that it will be useful,
00022    but WITHOUT ANY WARRANTY; without even the implied warranty of
00023    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00024    Lesser General Public License for more details.
00025 
00026    You should have received a copy of the GNU Lesser General Public
00027    License along with the GNU C Library; if not, write to the Free
00028    Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
00029    MA 02110-1301, USA.  */
00030 
00031 #if _FP_W_TYPE_SIZE < 32
00032 #error "Here's a nickel, kid. Go buy yourself a real computer."
00033 #endif
00034 
00035 #if _FP_W_TYPE_SIZE < 64
00036 #define _FP_FRACTBITS_E         (4*_FP_W_TYPE_SIZE)
00037 #else
00038 #define _FP_FRACTBITS_E            (2*_FP_W_TYPE_SIZE)
00039 #endif
00040 
00041 #define _FP_FRACBITS_E             64
00042 #define _FP_FRACXBITS_E            (_FP_FRACTBITS_E - _FP_FRACBITS_E)
00043 #define _FP_WFRACBITS_E            (_FP_WORKBITS + _FP_FRACBITS_E)
00044 #define _FP_WFRACXBITS_E    (_FP_FRACTBITS_E - _FP_WFRACBITS_E)
00045 #define _FP_EXPBITS_E              15
00046 #define _FP_EXPBIAS_E              16383
00047 #define _FP_EXPMAX_E        32767
00048 
00049 #define _FP_QNANBIT_E              \
00050        ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE)
00051 #define _FP_QNANBIT_SH_E           \
00052        ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
00053 #define _FP_IMPLBIT_E              \
00054        ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE)
00055 #define _FP_IMPLBIT_SH_E           \
00056        ((_FP_W_TYPE)1 << (_FP_FRACBITS_E-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
00057 #define _FP_OVERFLOW_E             \
00058        ((_FP_W_TYPE)1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE))
00059 
00060 typedef float XFtype __attribute__((mode(XF)));
00061 
00062 #if _FP_W_TYPE_SIZE < 64
00063 
00064 union _FP_UNION_E
00065 {
00066    XFtype flt;
00067    struct 
00068    {
00069 #if __BYTE_ORDER == __BIG_ENDIAN
00070       unsigned long pad1 : _FP_W_TYPE_SIZE;
00071       unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
00072       unsigned long sign : 1;
00073       unsigned long exp : _FP_EXPBITS_E;
00074       unsigned long frac1 : _FP_W_TYPE_SIZE;
00075       unsigned long frac0 : _FP_W_TYPE_SIZE;
00076 #else
00077       unsigned long frac0 : _FP_W_TYPE_SIZE;
00078       unsigned long frac1 : _FP_W_TYPE_SIZE;
00079       unsigned exp : _FP_EXPBITS_E;
00080       unsigned sign : 1;
00081 #endif /* not bigendian */
00082    } bits __attribute__((packed));
00083 };
00084 
00085 
00086 #define FP_DECL_E(X)        _FP_DECL(4,X)
00087 
00088 #define FP_UNPACK_RAW_E(X, val)                         \
00089   do {                                           \
00090     union _FP_UNION_E _flo; _flo.flt = (val);           \
00091                                                  \
00092     X##_f[2] = 0; X##_f[3] = 0;                         \
00093     X##_f[0] = _flo.bits.frac0;                         \
00094     X##_f[1] = _flo.bits.frac1;                         \
00095     X##_e  = _flo.bits.exp;                      \
00096     X##_s  = _flo.bits.sign;                            \
00097   } while (0)
00098 
00099 #define FP_UNPACK_RAW_EP(X, val)                 \
00100   do {                                           \
00101     union _FP_UNION_E *_flo =                           \
00102     (union _FP_UNION_E *)(val);                         \
00103                                                  \
00104     X##_f[2] = 0; X##_f[3] = 0;                         \
00105     X##_f[0] = _flo->bits.frac0;                 \
00106     X##_f[1] = _flo->bits.frac1;                 \
00107     X##_e  = _flo->bits.exp;                            \
00108     X##_s  = _flo->bits.sign;                           \
00109   } while (0)
00110 
00111 #define FP_PACK_RAW_E(val, X)                           \
00112   do {                                           \
00113     union _FP_UNION_E _flo;                      \
00114                                                  \
00115     if (X##_e) X##_f[1] |= _FP_IMPLBIT_E;        \
00116     else X##_f[1] &= ~(_FP_IMPLBIT_E);                  \
00117     _flo.bits.frac0 = X##_f[0];                         \
00118     _flo.bits.frac1 = X##_f[1];                         \
00119     _flo.bits.exp   = X##_e;                            \
00120     _flo.bits.sign  = X##_s;                            \
00121                                                  \
00122     (val) = _flo.flt;                                   \
00123   } while (0)
00124 
00125 #define FP_PACK_RAW_EP(val, X)                          \
00126   do {                                           \
00127     if (!FP_INHIBIT_RESULTS)                            \
00128       {                                                 \
00129        union _FP_UNION_E *_flo =                 \
00130          (union _FP_UNION_E *)(val);                    \
00131                                                  \
00132        if (X##_e) X##_f[1] |= _FP_IMPLBIT_E;            \
00133        else X##_f[1] &= ~(_FP_IMPLBIT_E);        \
00134        _flo->bits.frac0 = X##_f[0];                     \
00135        _flo->bits.frac1 = X##_f[1];                     \
00136        _flo->bits.exp   = X##_e;                 \
00137        _flo->bits.sign  = X##_s;                 \
00138       }                                                 \
00139   } while (0)
00140 
00141 #define FP_UNPACK_E(X,val)         \
00142   do {                             \
00143     FP_UNPACK_RAW_E(X,val);        \
00144     _FP_UNPACK_CANONICAL(E,4,X);   \
00145   } while (0)
00146 
00147 #define FP_UNPACK_EP(X,val)        \
00148   do {                             \
00149     FP_UNPACK_RAW_EP(X,val);              \
00150     _FP_UNPACK_CANONICAL(E,4,X);   \
00151   } while (0)
00152 
00153 #define FP_UNPACK_SEMIRAW_E(X,val) \
00154   do {                             \
00155     FP_UNPACK_RAW_E(X,val);        \
00156     _FP_UNPACK_SEMIRAW(E,4,X);            \
00157   } while (0)
00158 
00159 #define FP_UNPACK_SEMIRAW_EP(X,val)       \
00160   do {                             \
00161     FP_UNPACK_RAW_EP(X,val);              \
00162     _FP_UNPACK_SEMIRAW(E,4,X);            \
00163   } while (0)
00164 
00165 #define FP_PACK_E(val,X)           \
00166   do {                             \
00167     _FP_PACK_CANONICAL(E,4,X);            \
00168     FP_PACK_RAW_E(val,X);          \
00169   } while (0)
00170 
00171 #define FP_PACK_EP(val,X)          \
00172   do {                             \
00173     _FP_PACK_CANONICAL(E,4,X);            \
00174     FP_PACK_RAW_EP(val,X);         \
00175   } while (0)
00176 
00177 #define FP_PACK_SEMIRAW_E(val,X)   \
00178   do {                             \
00179     _FP_PACK_SEMIRAW(E,4,X);              \
00180     FP_PACK_RAW_E(val,X);          \
00181   } while (0)
00182 
00183 #define FP_PACK_SEMIRAW_EP(val,X)  \
00184   do {                             \
00185     _FP_PACK_SEMIRAW(E,4,X);              \
00186     FP_PACK_RAW_EP(val,X);         \
00187   } while (0)
00188 
00189 #define FP_ISSIGNAN_E(X)    _FP_ISSIGNAN(E,4,X)
00190 #define FP_NEG_E(R,X)              _FP_NEG(E,4,R,X)
00191 #define FP_ADD_E(R,X,Y)            _FP_ADD(E,4,R,X,Y)
00192 #define FP_SUB_E(R,X,Y)            _FP_SUB(E,4,R,X,Y)
00193 #define FP_MUL_E(R,X,Y)            _FP_MUL(E,4,R,X,Y)
00194 #define FP_DIV_E(R,X,Y)            _FP_DIV(E,4,R,X,Y)
00195 #define FP_SQRT_E(R,X)             _FP_SQRT(E,4,R,X)
00196 
00197 /*
00198  * Square root algorithms:
00199  * We have just one right now, maybe Newton approximation
00200  * should be added for those machines where division is fast.
00201  * This has special _E version because standard _4 square
00202  * root would not work (it has to start normally with the
00203  * second word and not the first), but as we have to do it
00204  * anyway, we optimize it by doing most of the calculations
00205  * in two UWtype registers instead of four.
00206  */
00207  
00208 #define _FP_SQRT_MEAT_E(R, S, T, X, q)                  \
00209   do {                                           \
00210     q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);         \
00211     _FP_FRAC_SRL_4(X, (_FP_WORKBITS));                  \
00212     while (q)                                    \
00213       {                                                 \
00214        T##_f[1] = S##_f[1] + q;                  \
00215        if (T##_f[1] <= X##_f[1])                 \
00216          {                                       \
00217            S##_f[1] = T##_f[1] + q;                     \
00218            X##_f[1] -= T##_f[1];                 \
00219            R##_f[1] += q;                        \
00220          }                                       \
00221        _FP_FRAC_SLL_2(X, 1);                            \
00222        q >>= 1;                                  \
00223       }                                                 \
00224     q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);         \
00225     while (q)                                    \
00226       {                                                 \
00227        T##_f[0] = S##_f[0] + q;                  \
00228        T##_f[1] = S##_f[1];                      \
00229        if (T##_f[1] < X##_f[1] ||                \
00230            (T##_f[1] == X##_f[1] &&                     \
00231             T##_f[0] <= X##_f[0]))               \
00232          {                                       \
00233            S##_f[0] = T##_f[0] + q;                     \
00234            S##_f[1] += (T##_f[0] > S##_f[0]);           \
00235            _FP_FRAC_DEC_2(X, T);                 \
00236            R##_f[0] += q;                        \
00237          }                                       \
00238        _FP_FRAC_SLL_2(X, 1);                            \
00239        q >>= 1;                                  \
00240       }                                                 \
00241     _FP_FRAC_SLL_4(R, (_FP_WORKBITS));                  \
00242     if (X##_f[0] | X##_f[1])                            \
00243       {                                                 \
00244        if (S##_f[1] < X##_f[1] ||                \
00245            (S##_f[1] == X##_f[1] &&                     \
00246             S##_f[0] < X##_f[0]))                \
00247          R##_f[0] |= _FP_WORK_ROUND;                    \
00248        R##_f[0] |= _FP_WORK_STICKY;                     \
00249       }                                                 \
00250   } while (0)
00251 
00252 #define FP_CMP_E(r,X,Y,un)  _FP_CMP(E,4,r,X,Y,un)
00253 #define FP_CMP_EQ_E(r,X,Y)  _FP_CMP_EQ(E,4,r,X,Y)
00254 #define FP_CMP_UNORD_E(r,X,Y)      _FP_CMP_UNORD(E,4,r,X,Y)
00255 
00256 #define FP_TO_INT_E(r,X,rsz,rsg)   _FP_TO_INT(E,4,r,X,rsz,rsg)
00257 #define FP_FROM_INT_E(X,r,rs,rt)   _FP_FROM_INT(E,4,X,r,rs,rt)
00258 
00259 #define _FP_FRAC_HIGH_E(X)  (X##_f[2])
00260 #define _FP_FRAC_HIGH_RAW_E(X)     (X##_f[1])
00261 
00262 #else   /* not _FP_W_TYPE_SIZE < 64 */
00263 union _FP_UNION_E
00264 {
00265   XFtype flt;
00266   struct {
00267 #if __BYTE_ORDER == __BIG_ENDIAN
00268     _FP_W_TYPE pad  : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
00269     unsigned sign   : 1;
00270     unsigned exp    : _FP_EXPBITS_E;
00271     _FP_W_TYPE frac : _FP_W_TYPE_SIZE;
00272 #else
00273     _FP_W_TYPE frac : _FP_W_TYPE_SIZE;
00274     unsigned exp    : _FP_EXPBITS_E;
00275     unsigned sign   : 1;
00276 #endif
00277   } bits;
00278 };
00279 
00280 #define FP_DECL_E(X)        _FP_DECL(2,X)
00281 
00282 #define FP_UNPACK_RAW_E(X, val)                                \
00283   do {                                                  \
00284     union _FP_UNION_E _flo; _flo.flt = (val);                  \
00285                                                         \
00286     X##_f0 = _flo.bits.frac;                                   \
00287     X##_f1 = 0;                                                \
00288     X##_e = _flo.bits.exp;                              \
00289     X##_s = _flo.bits.sign;                             \
00290   } while (0)
00291 
00292 #define FP_UNPACK_RAW_EP(X, val)                        \
00293   do {                                                  \
00294     union _FP_UNION_E *_flo =                                  \
00295       (union _FP_UNION_E *)(val);                       \
00296                                                         \
00297     X##_f0 = _flo->bits.frac;                                  \
00298     X##_f1 = 0;                                                \
00299     X##_e = _flo->bits.exp;                             \
00300     X##_s = _flo->bits.sign;                                   \
00301   } while (0)
00302 
00303 #define FP_PACK_RAW_E(val, X)                                  \
00304   do {                                                  \
00305     union _FP_UNION_E _flo;                             \
00306                                                         \
00307     if (X##_e) X##_f0 |= _FP_IMPLBIT_E;                        \
00308     else X##_f0 &= ~(_FP_IMPLBIT_E);                           \
00309     _flo.bits.frac = X##_f0;                                   \
00310     _flo.bits.exp  = X##_e;                             \
00311     _flo.bits.sign = X##_s;                             \
00312                                                         \
00313     (val) = _flo.flt;                                          \
00314   } while (0)
00315 
00316 #define FP_PACK_RAW_EP(fs, val, X)                      \
00317   do {                                                  \
00318     if (!FP_INHIBIT_RESULTS)                                   \
00319       {                                                        \
00320        union _FP_UNION_E *_flo =                        \
00321          (union _FP_UNION_E *)(val);                           \
00322                                                         \
00323        if (X##_e) X##_f0 |= _FP_IMPLBIT_E;                     \
00324        else X##_f0 &= ~(_FP_IMPLBIT_E);                 \
00325        _flo->bits.frac = X##_f0;                        \
00326        _flo->bits.exp  = X##_e;                         \
00327        _flo->bits.sign = X##_s;                         \
00328       }                                                        \
00329   } while (0)
00330 
00331 
00332 #define FP_UNPACK_E(X,val)         \
00333   do {                             \
00334     FP_UNPACK_RAW_E(X,val);        \
00335     _FP_UNPACK_CANONICAL(E,2,X);   \
00336   } while (0)
00337 
00338 #define FP_UNPACK_EP(X,val)        \
00339   do {                             \
00340     FP_UNPACK_RAW_EP(X,val);              \
00341     _FP_UNPACK_CANONICAL(E,2,X);   \
00342   } while (0)
00343 
00344 #define FP_UNPACK_SEMIRAW_E(X,val) \
00345   do {                             \
00346     FP_UNPACK_RAW_E(X,val);        \
00347     _FP_UNPACK_SEMIRAW(E,2,X);            \
00348   } while (0)
00349 
00350 #define FP_UNPACK_SEMIRAW_EP(X,val)       \
00351   do {                             \
00352     FP_UNPACK_RAW_EP(X,val);              \
00353     _FP_UNPACK_SEMIRAW(E,2,X);            \
00354   } while (0)
00355 
00356 #define FP_PACK_E(val,X)           \
00357   do {                             \
00358     _FP_PACK_CANONICAL(E,2,X);            \
00359     FP_PACK_RAW_E(val,X);          \
00360   } while (0)
00361 
00362 #define FP_PACK_EP(val,X)          \
00363   do {                             \
00364     _FP_PACK_CANONICAL(E,2,X);            \
00365     FP_PACK_RAW_EP(val,X);         \
00366   } while (0)
00367 
00368 #define FP_PACK_SEMIRAW_E(val,X)   \
00369   do {                             \
00370     _FP_PACK_SEMIRAW(E,2,X);              \
00371     FP_PACK_RAW_E(val,X);          \
00372   } while (0)
00373 
00374 #define FP_PACK_SEMIRAW_EP(val,X)  \
00375   do {                             \
00376     _FP_PACK_SEMIRAW(E,2,X);              \
00377     FP_PACK_RAW_EP(val,X);         \
00378   } while (0)
00379 
00380 #define FP_ISSIGNAN_E(X)    _FP_ISSIGNAN(E,2,X)
00381 #define FP_NEG_E(R,X)              _FP_NEG(E,2,R,X)
00382 #define FP_ADD_E(R,X,Y)            _FP_ADD(E,2,R,X,Y)
00383 #define FP_SUB_E(R,X,Y)            _FP_SUB(E,2,R,X,Y)
00384 #define FP_MUL_E(R,X,Y)            _FP_MUL(E,2,R,X,Y)
00385 #define FP_DIV_E(R,X,Y)            _FP_DIV(E,2,R,X,Y)
00386 #define FP_SQRT_E(R,X)             _FP_SQRT(E,2,R,X)
00387 
00388 /*
00389  * Square root algorithms:
00390  * We have just one right now, maybe Newton approximation
00391  * should be added for those machines where division is fast.
00392  * We optimize it by doing most of the calculations
00393  * in one UWtype registers instead of two, although we don't
00394  * have to.
00395  */
00396 #define _FP_SQRT_MEAT_E(R, S, T, X, q)                  \
00397   do {                                           \
00398     q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1);         \
00399     _FP_FRAC_SRL_2(X, (_FP_WORKBITS));                  \
00400     while (q)                                    \
00401       {                                                 \
00402         T##_f0 = S##_f0 + q;                            \
00403         if (T##_f0 <= X##_f0)                           \
00404           {                                      \
00405             S##_f0 = T##_f0 + q;                 \
00406             X##_f0 -= T##_f0;                           \
00407             R##_f0 += q;                         \
00408           }                                      \
00409         _FP_FRAC_SLL_1(X, 1);                           \
00410         q >>= 1;                                 \
00411       }                                                 \
00412     _FP_FRAC_SLL_2(R, (_FP_WORKBITS));                  \
00413     if (X##_f0)                                         \
00414       {                                                 \
00415        if (S##_f0 < X##_f0)                      \
00416          R##_f0 |= _FP_WORK_ROUND;               \
00417        R##_f0 |= _FP_WORK_STICKY;                \
00418       }                                                 \
00419   } while (0)
00420  
00421 #define FP_CMP_E(r,X,Y,un)  _FP_CMP(E,2,r,X,Y,un)
00422 #define FP_CMP_EQ_E(r,X,Y)  _FP_CMP_EQ(E,2,r,X,Y)
00423 #define FP_CMP_UNORD_E(r,X,Y)      _FP_CMP_UNORD(E,2,r,X,Y)
00424 
00425 #define FP_TO_INT_E(r,X,rsz,rsg)   _FP_TO_INT(E,2,r,X,rsz,rsg)
00426 #define FP_FROM_INT_E(X,r,rs,rt)   _FP_FROM_INT(E,2,X,r,rs,rt)
00427 
00428 #define _FP_FRAC_HIGH_E(X)  (X##_f1)
00429 #define _FP_FRAC_HIGH_RAW_E(X)     (X##_f0)
00430 
00431 #endif /* not _FP_W_TYPE_SIZE < 64 */