Back to index

glibc  2.9
op-8.h
Go to the documentation of this file.
00001 /* Software floating-point emulation.
00002    Basic eight-word fraction declaration and manipulation.
00003    Copyright (C) 1997,1998,1999,2006 Free Software Foundation, Inc.
00004    This file is part of the GNU C Library.
00005    Contributed by Richard Henderson (rth@cygnus.com),
00006                 Jakub Jelinek (jj@ultra.linux.cz) and
00007                 Peter Maydell (pmaydell@chiark.greenend.org.uk).
00008 
00009    The GNU C Library is free software; you can redistribute it and/or
00010    modify it under the terms of the GNU Lesser General Public
00011    License as published by the Free Software Foundation; either
00012    version 2.1 of the License, or (at your option) any later version.
00013 
00014    In addition to the permissions in the GNU Lesser General Public
00015    License, the Free Software Foundation gives you unlimited
00016    permission to link the compiled version of this file into
00017    combinations with other programs, and to distribute those
00018    combinations without any restriction coming from the use of this
00019    file.  (The Lesser General Public License restrictions do apply in
00020    other respects; for example, they cover modification of the file,
00021    and distribution when not linked into a combine executable.)
00022 
00023    The GNU C Library is distributed in the hope that it will be useful,
00024    but WITHOUT ANY WARRANTY; without even the implied warranty of
00025    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026    Lesser General Public License for more details.
00027 
00028    You should have received a copy of the GNU Lesser General Public
00029    License along with the GNU C Library; if not, write to the Free
00030    Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
00031    MA 02110-1301, USA.  */
00032 
00033 /* We need just a few things from here for op-4, if we ever need some
00034    other macros, they can be added. */
00035 #define _FP_FRAC_DECL_8(X)  _FP_W_TYPE X##_f[8]
00036 #define _FP_FRAC_HIGH_8(X)  (X##_f[7])
00037 #define _FP_FRAC_LOW_8(X)   (X##_f[0])
00038 #define _FP_FRAC_WORD_8(X,w)       (X##_f[w])
00039 
00040 #define _FP_FRAC_SLL_8(X,N)                                    \
00041   do {                                                         \
00042     _FP_I_TYPE _up, _down, _skip, _i;                                 \
00043     _skip = (N) / _FP_W_TYPE_SIZE;                             \
00044     _up = (N) % _FP_W_TYPE_SIZE;                               \
00045     _down = _FP_W_TYPE_SIZE - _up;                             \
00046     if (!_up)                                                  \
00047       for (_i = 7; _i >= _skip; --_i)                                 \
00048        X##_f[_i] = X##_f[_i-_skip];                                   \
00049     else                                                       \
00050       {                                                               \
00051        for (_i = 7; _i > _skip; --_i)                                 \
00052          X##_f[_i] = X##_f[_i-_skip] << _up                           \
00053                     | X##_f[_i-_skip-1] >> _down;                     \
00054        X##_f[_i--] = X##_f[0] << _up;                                 \
00055       }                                                               \
00056     for (; _i >= 0; --_i)                                      \
00057       X##_f[_i] = 0;                                           \
00058   } while (0)
00059 
00060 #define _FP_FRAC_SRL_8(X,N)                                    \
00061   do {                                                         \
00062     _FP_I_TYPE _up, _down, _skip, _i;                                 \
00063     _skip = (N) / _FP_W_TYPE_SIZE;                             \
00064     _down = (N) % _FP_W_TYPE_SIZE;                             \
00065     _up = _FP_W_TYPE_SIZE - _down;                             \
00066     if (!_down)                                                       \
00067       for (_i = 0; _i <= 7-_skip; ++_i)                               \
00068        X##_f[_i] = X##_f[_i+_skip];                                   \
00069     else                                                       \
00070       {                                                               \
00071        for (_i = 0; _i < 7-_skip; ++_i)                        \
00072          X##_f[_i] = X##_f[_i+_skip] >> _down                         \
00073                     | X##_f[_i+_skip+1] << _up;                \
00074        X##_f[_i++] = X##_f[7] >> _down;                        \
00075       }                                                               \
00076     for (; _i < 8; ++_i)                                       \
00077       X##_f[_i] = 0;                                           \
00078   } while (0)
00079 
00080 
00081 /* Right shift with sticky-lsb. 
00082  * What this actually means is that we do a standard right-shift,
00083  * but that if any of the bits that fall off the right hand side
00084  * were one then we always set the LSbit.
00085  */
00086 #define _FP_FRAC_SRS_8(X,N,size)                               \
00087   do {                                                         \
00088     _FP_I_TYPE _up, _down, _skip, _i;                                 \
00089     _FP_W_TYPE _s;                                             \
00090     _skip = (N) / _FP_W_TYPE_SIZE;                             \
00091     _down = (N) % _FP_W_TYPE_SIZE;                             \
00092     _up = _FP_W_TYPE_SIZE - _down;                             \
00093     for (_s = _i = 0; _i < _skip; ++_i)                               \
00094       _s |= X##_f[_i];                                                \
00095     if (!_down)                                                       \
00096       for (_i = 0; _i <= 7-_skip; ++_i)                               \
00097        X##_f[_i] = X##_f[_i+_skip];                                   \
00098     else                                                       \
00099       {                                                               \
00100        _s |= X##_f[_i] << _up;                                        \
00101        for (_i = 0; _i < 7-_skip; ++_i)                        \
00102          X##_f[_i] = X##_f[_i+_skip] >> _down                         \
00103                     | X##_f[_i+_skip+1] << _up;                \
00104        X##_f[_i++] = X##_f[7] >> _down;                        \
00105       }                                                               \
00106     for (; _i < 8; ++_i)                                       \
00107       X##_f[_i] = 0;                                           \
00108     /* don't fix the LSB until the very end when we're sure f[0] is stable */       \
00109     X##_f[0] |= (_s != 0);                                     \
00110   } while (0)
00111