789d383da78c70eb1957b8111eff491f49a0a7b6
[jlayton/glibc.git] / soft-fp / op-8.h
1 /* Software floating-point emulation.
2    Basic eight-word fraction declaration and manipulation.
3    Copyright (C) 1997,1998,1999 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) and
7                   Peter Maydell (pmaydell@chiark.greenend.org.uk).
8
9    The GNU C Library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Lesser General Public
11    License as published by the Free Software Foundation; either
12    version 2.1 of the License, or (at your option) any later version.
13
14    The GNU C Library is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Lesser General Public License for more details.
18
19    You should have received a copy of the GNU Lesser General Public
20    License along with the GNU C Library; if not, write to the Free
21    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22    02111-1307 USA.  */
23
24 /* We need just a few things from here for op-4, if we ever need some
25    other macros, they can be added. */
26 #define _FP_FRAC_DECL_8(X)      _FP_W_TYPE X##_f[8]
27 #define _FP_FRAC_HIGH_8(X)      (X##_f[7])
28 #define _FP_FRAC_LOW_8(X)       (X##_f[0])
29 #define _FP_FRAC_WORD_8(X,w)    (X##_f[w])
30
31 #define _FP_FRAC_SLL_8(X,N)                                             \
32   do {                                                                  \
33     _FP_I_TYPE _up, _down, _skip, _i;                                   \
34     _skip = (N) / _FP_W_TYPE_SIZE;                                      \
35     _up = (N) % _FP_W_TYPE_SIZE;                                        \
36     _down = _FP_W_TYPE_SIZE - _up;                                      \
37     if (!_up)                                                           \
38       for (_i = 7; _i >= _skip; --_i)                                   \
39         X##_f[_i] = X##_f[_i-_skip];                                    \
40     else                                                                \
41       {                                                                 \
42         for (_i = 7; _i > _skip; --_i)                                  \
43           X##_f[_i] = X##_f[_i-_skip] << _up                            \
44                       | X##_f[_i-_skip-1] >> _down;                     \
45         X##_f[_i--] = X##_f[0] << _up;                                  \
46       }                                                                 \
47     for (; _i >= 0; --_i)                                               \
48       X##_f[_i] = 0;                                                    \
49   } while (0)
50
51 #define _FP_FRAC_SRL_8(X,N)                                             \
52   do {                                                                  \
53     _FP_I_TYPE _up, _down, _skip, _i;                                   \
54     _skip = (N) / _FP_W_TYPE_SIZE;                                      \
55     _down = (N) % _FP_W_TYPE_SIZE;                                      \
56     _up = _FP_W_TYPE_SIZE - _down;                                      \
57     if (!_down)                                                         \
58       for (_i = 0; _i <= 7-_skip; ++_i)                                 \
59         X##_f[_i] = X##_f[_i+_skip];                                    \
60     else                                                                \
61       {                                                                 \
62         for (_i = 0; _i < 7-_skip; ++_i)                                \
63           X##_f[_i] = X##_f[_i+_skip] >> _down                          \
64                       | X##_f[_i+_skip+1] << _up;                       \
65         X##_f[_i++] = X##_f[7] >> _down;                                \
66       }                                                                 \
67     for (; _i < 8; ++_i)                                                \
68       X##_f[_i] = 0;                                                    \
69   } while (0)
70
71
72 /* Right shift with sticky-lsb. 
73  * What this actually means is that we do a standard right-shift,
74  * but that if any of the bits that fall off the right hand side
75  * were one then we always set the LSbit.
76  */
77 #define _FP_FRAC_SRS_8(X,N,size)                                        \
78   do {                                                                  \
79     _FP_I_TYPE _up, _down, _skip, _i;                                   \
80     _FP_W_TYPE _s;                                                      \
81     _skip = (N) / _FP_W_TYPE_SIZE;                                      \
82     _down = (N) % _FP_W_TYPE_SIZE;                                      \
83     _up = _FP_W_TYPE_SIZE - _down;                                      \
84     for (_s = _i = 0; _i < _skip; ++_i)                                 \
85       _s |= X##_f[_i];                                                  \
86     _s |= X##_f[_i] << _up;                                             \
87 /* s is now != 0 if we want to set the LSbit */                         \
88     if (!_down)                                                         \
89       for (_i = 0; _i <= 7-_skip; ++_i)                                 \
90         X##_f[_i] = X##_f[_i+_skip];                                    \
91     else                                                                \
92       {                                                                 \
93         for (_i = 0; _i < 7-_skip; ++_i)                                \
94           X##_f[_i] = X##_f[_i+_skip] >> _down                          \
95                       | X##_f[_i+_skip+1] << _up;                       \
96         X##_f[_i++] = X##_f[7] >> _down;                                \
97       }                                                                 \
98     for (; _i < 8; ++_i)                                                \
99       X##_f[_i] = 0;                                                    \
100     /* don't fix the LSB until the very end when we're sure f[0] is stable */   \
101     X##_f[0] |= (_s != 0);                                              \
102   } while (0)
103