| 1 | /* Software floating-point emulation. | 
|---|
| 2 | Basic eight-word fraction declaration and manipulation. | 
|---|
| 3 | Copyright (C) 1997-2020 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 | In addition to the permissions in the GNU Lesser General Public | 
|---|
| 15 | License, the Free Software Foundation gives you unlimited | 
|---|
| 16 | permission to link the compiled version of this file into | 
|---|
| 17 | combinations with other programs, and to distribute those | 
|---|
| 18 | combinations without any restriction coming from the use of this | 
|---|
| 19 | file.  (The Lesser General Public License restrictions do apply in | 
|---|
| 20 | other respects; for example, they cover modification of the file, | 
|---|
| 21 | and distribution when not linked into a combine executable.) | 
|---|
| 22 |  | 
|---|
| 23 | The GNU C Library is distributed in the hope that it will be useful, | 
|---|
| 24 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 25 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|---|
| 26 | Lesser General Public License for more details. | 
|---|
| 27 |  | 
|---|
| 28 | You should have received a copy of the GNU Lesser General Public | 
|---|
| 29 | License along with the GNU C Library; if not, see | 
|---|
| 30 | <https://www.gnu.org/licenses/>.  */ | 
|---|
| 31 |  | 
|---|
| 32 | #ifndef SOFT_FP_OP_8_H | 
|---|
| 33 | #define SOFT_FP_OP_8_H	1 | 
|---|
| 34 |  | 
|---|
| 35 | /* We need just a few things from here for op-4, if we ever need some | 
|---|
| 36 | other macros, they can be added.  */ | 
|---|
| 37 | #define _FP_FRAC_DECL_8(X)	_FP_W_TYPE X##_f[8] | 
|---|
| 38 | #define _FP_FRAC_SET_8(X, I)    __FP_FRAC_SET_8 (X, I) | 
|---|
| 39 | #define _FP_FRAC_HIGH_8(X)	(X##_f[7]) | 
|---|
| 40 | #define _FP_FRAC_LOW_8(X)	(X##_f[0]) | 
|---|
| 41 | #define _FP_FRAC_WORD_8(X, w)	(X##_f[w]) | 
|---|
| 42 |  | 
|---|
| 43 | #define _FP_FRAC_SLL_8(X, N)						\ | 
|---|
| 44 | do									\ | 
|---|
| 45 | {									\ | 
|---|
| 46 | _FP_I_TYPE _FP_FRAC_SLL_8_up, _FP_FRAC_SLL_8_down;		\ | 
|---|
| 47 | _FP_I_TYPE _FP_FRAC_SLL_8_skip, _FP_FRAC_SLL_8_i;			\ | 
|---|
| 48 | _FP_FRAC_SLL_8_skip = (N) / _FP_W_TYPE_SIZE;			\ | 
|---|
| 49 | _FP_FRAC_SLL_8_up = (N) % _FP_W_TYPE_SIZE;			\ | 
|---|
| 50 | _FP_FRAC_SLL_8_down = _FP_W_TYPE_SIZE - _FP_FRAC_SLL_8_up;	\ | 
|---|
| 51 | if (!_FP_FRAC_SLL_8_up)						\ | 
|---|
| 52 | for (_FP_FRAC_SLL_8_i = 7;					\ | 
|---|
| 53 | _FP_FRAC_SLL_8_i >= _FP_FRAC_SLL_8_skip;			\ | 
|---|
| 54 | --_FP_FRAC_SLL_8_i)					\ | 
|---|
| 55 | X##_f[_FP_FRAC_SLL_8_i]					\ | 
|---|
| 56 | = X##_f[_FP_FRAC_SLL_8_i-_FP_FRAC_SLL_8_skip];		\ | 
|---|
| 57 | else								\ | 
|---|
| 58 | {								\ | 
|---|
| 59 | for (_FP_FRAC_SLL_8_i = 7;					\ | 
|---|
| 60 | _FP_FRAC_SLL_8_i > _FP_FRAC_SLL_8_skip;			\ | 
|---|
| 61 | --_FP_FRAC_SLL_8_i)					\ | 
|---|
| 62 | X##_f[_FP_FRAC_SLL_8_i]					\ | 
|---|
| 63 | = ((X##_f[_FP_FRAC_SLL_8_i-_FP_FRAC_SLL_8_skip]		\ | 
|---|
| 64 | << _FP_FRAC_SLL_8_up)					\ | 
|---|
| 65 | | (X##_f[_FP_FRAC_SLL_8_i-_FP_FRAC_SLL_8_skip-1]	\ | 
|---|
| 66 | >> _FP_FRAC_SLL_8_down));				\ | 
|---|
| 67 | X##_f[_FP_FRAC_SLL_8_i--] = X##_f[0] << _FP_FRAC_SLL_8_up;	\ | 
|---|
| 68 | }								\ | 
|---|
| 69 | for (; _FP_FRAC_SLL_8_i >= 0; --_FP_FRAC_SLL_8_i)			\ | 
|---|
| 70 | X##_f[_FP_FRAC_SLL_8_i] = 0;					\ | 
|---|
| 71 | }									\ | 
|---|
| 72 | while (0) | 
|---|
| 73 |  | 
|---|
| 74 | #define _FP_FRAC_SRL_8(X, N)						\ | 
|---|
| 75 | do									\ | 
|---|
| 76 | {									\ | 
|---|
| 77 | _FP_I_TYPE _FP_FRAC_SRL_8_up, _FP_FRAC_SRL_8_down;		\ | 
|---|
| 78 | _FP_I_TYPE _FP_FRAC_SRL_8_skip, _FP_FRAC_SRL_8_i;			\ | 
|---|
| 79 | _FP_FRAC_SRL_8_skip = (N) / _FP_W_TYPE_SIZE;			\ | 
|---|
| 80 | _FP_FRAC_SRL_8_down = (N) % _FP_W_TYPE_SIZE;			\ | 
|---|
| 81 | _FP_FRAC_SRL_8_up = _FP_W_TYPE_SIZE - _FP_FRAC_SRL_8_down;	\ | 
|---|
| 82 | if (!_FP_FRAC_SRL_8_down)						\ | 
|---|
| 83 | for (_FP_FRAC_SRL_8_i = 0;					\ | 
|---|
| 84 | _FP_FRAC_SRL_8_i <= 7-_FP_FRAC_SRL_8_skip;			\ | 
|---|
| 85 | ++_FP_FRAC_SRL_8_i)					\ | 
|---|
| 86 | X##_f[_FP_FRAC_SRL_8_i]					\ | 
|---|
| 87 | = X##_f[_FP_FRAC_SRL_8_i+_FP_FRAC_SRL_8_skip];		\ | 
|---|
| 88 | else								\ | 
|---|
| 89 | {								\ | 
|---|
| 90 | for (_FP_FRAC_SRL_8_i = 0;					\ | 
|---|
| 91 | _FP_FRAC_SRL_8_i < 7-_FP_FRAC_SRL_8_skip;		\ | 
|---|
| 92 | ++_FP_FRAC_SRL_8_i)					\ | 
|---|
| 93 | X##_f[_FP_FRAC_SRL_8_i]					\ | 
|---|
| 94 | = ((X##_f[_FP_FRAC_SRL_8_i+_FP_FRAC_SRL_8_skip]		\ | 
|---|
| 95 | >> _FP_FRAC_SRL_8_down)				\ | 
|---|
| 96 | | (X##_f[_FP_FRAC_SRL_8_i+_FP_FRAC_SRL_8_skip+1]	\ | 
|---|
| 97 | << _FP_FRAC_SRL_8_up));				\ | 
|---|
| 98 | X##_f[_FP_FRAC_SRL_8_i++] = X##_f[7] >> _FP_FRAC_SRL_8_down;	\ | 
|---|
| 99 | }								\ | 
|---|
| 100 | for (; _FP_FRAC_SRL_8_i < 8; ++_FP_FRAC_SRL_8_i)			\ | 
|---|
| 101 | X##_f[_FP_FRAC_SRL_8_i] = 0;					\ | 
|---|
| 102 | }									\ | 
|---|
| 103 | while (0) | 
|---|
| 104 |  | 
|---|
| 105 |  | 
|---|
| 106 | /* Right shift with sticky-lsb. | 
|---|
| 107 | What this actually means is that we do a standard right-shift, | 
|---|
| 108 | but that if any of the bits that fall off the right hand side | 
|---|
| 109 | were one then we always set the LSbit.  */ | 
|---|
| 110 | #define _FP_FRAC_SRS_8(X, N, size)					\ | 
|---|
| 111 | do									\ | 
|---|
| 112 | {									\ | 
|---|
| 113 | _FP_I_TYPE _FP_FRAC_SRS_8_up, _FP_FRAC_SRS_8_down;		\ | 
|---|
| 114 | _FP_I_TYPE _FP_FRAC_SRS_8_skip, _FP_FRAC_SRS_8_i;			\ | 
|---|
| 115 | _FP_W_TYPE _FP_FRAC_SRS_8_s;					\ | 
|---|
| 116 | _FP_FRAC_SRS_8_skip = (N) / _FP_W_TYPE_SIZE;			\ | 
|---|
| 117 | _FP_FRAC_SRS_8_down = (N) % _FP_W_TYPE_SIZE;			\ | 
|---|
| 118 | _FP_FRAC_SRS_8_up = _FP_W_TYPE_SIZE - _FP_FRAC_SRS_8_down;	\ | 
|---|
| 119 | for (_FP_FRAC_SRS_8_s = _FP_FRAC_SRS_8_i = 0;			\ | 
|---|
| 120 | _FP_FRAC_SRS_8_i < _FP_FRAC_SRS_8_skip;			\ | 
|---|
| 121 | ++_FP_FRAC_SRS_8_i)						\ | 
|---|
| 122 | _FP_FRAC_SRS_8_s |= X##_f[_FP_FRAC_SRS_8_i];			\ | 
|---|
| 123 | if (!_FP_FRAC_SRS_8_down)						\ | 
|---|
| 124 | for (_FP_FRAC_SRS_8_i = 0;					\ | 
|---|
| 125 | _FP_FRAC_SRS_8_i <= 7-_FP_FRAC_SRS_8_skip;			\ | 
|---|
| 126 | ++_FP_FRAC_SRS_8_i)					\ | 
|---|
| 127 | X##_f[_FP_FRAC_SRS_8_i]					\ | 
|---|
| 128 | = X##_f[_FP_FRAC_SRS_8_i+_FP_FRAC_SRS_8_skip];		\ | 
|---|
| 129 | else								\ | 
|---|
| 130 | {								\ | 
|---|
| 131 | _FP_FRAC_SRS_8_s						\ | 
|---|
| 132 | |= X##_f[_FP_FRAC_SRS_8_i] << _FP_FRAC_SRS_8_up;		\ | 
|---|
| 133 | for (_FP_FRAC_SRS_8_i = 0;					\ | 
|---|
| 134 | _FP_FRAC_SRS_8_i < 7-_FP_FRAC_SRS_8_skip;		\ | 
|---|
| 135 | ++_FP_FRAC_SRS_8_i)					\ | 
|---|
| 136 | X##_f[_FP_FRAC_SRS_8_i]					\ | 
|---|
| 137 | = ((X##_f[_FP_FRAC_SRS_8_i+_FP_FRAC_SRS_8_skip]		\ | 
|---|
| 138 | >> _FP_FRAC_SRS_8_down)				\ | 
|---|
| 139 | | (X##_f[_FP_FRAC_SRS_8_i+_FP_FRAC_SRS_8_skip+1]	\ | 
|---|
| 140 | << _FP_FRAC_SRS_8_up));				\ | 
|---|
| 141 | X##_f[_FP_FRAC_SRS_8_i++] = X##_f[7] >> _FP_FRAC_SRS_8_down;	\ | 
|---|
| 142 | }								\ | 
|---|
| 143 | for (; _FP_FRAC_SRS_8_i < 8; ++_FP_FRAC_SRS_8_i)			\ | 
|---|
| 144 | X##_f[_FP_FRAC_SRS_8_i] = 0;					\ | 
|---|
| 145 | /* Don't fix the LSB until the very end when we're sure f[0] is	\ | 
|---|
| 146 | stable.  */							\ | 
|---|
| 147 | X##_f[0] |= (_FP_FRAC_SRS_8_s != 0);				\ | 
|---|
| 148 | }									\ | 
|---|
| 149 | while (0) | 
|---|
| 150 |  | 
|---|
| 151 | #define _FP_FRAC_ADD_8(R, X, Y)                                             \ | 
|---|
| 152 | do                                                                        \ | 
|---|
| 153 | {                                                                       \ | 
|---|
| 154 | _FP_W_TYPE _FP_FRAC_ADD_8_c = 0;                                      \ | 
|---|
| 155 | _FP_I_TYPE _FP_FRAC_ADD_8_i;                                          \ | 
|---|
| 156 | for (_FP_FRAC_ADD_8_i = 0; _FP_FRAC_ADD_8_i < 8; ++_FP_FRAC_ADD_8_i)  \ | 
|---|
| 157 | {                                                                   \ | 
|---|
| 158 | R##_f[_FP_FRAC_ADD_8_i]                                           \ | 
|---|
| 159 | = (X##_f[_FP_FRAC_ADD_8_i] + Y##_f[_FP_FRAC_ADD_8_i]            \ | 
|---|
| 160 | + _FP_FRAC_ADD_8_c);                                         \ | 
|---|
| 161 | _FP_FRAC_ADD_8_c                                                  \ | 
|---|
| 162 | = (_FP_FRAC_ADD_8_c                                             \ | 
|---|
| 163 | ? R##_f[_FP_FRAC_ADD_8_i] <= X##_f[_FP_FRAC_ADD_8_i]         \ | 
|---|
| 164 | : R##_f[_FP_FRAC_ADD_8_i] < X##_f[_FP_FRAC_ADD_8_i]);        \ | 
|---|
| 165 | }                                                                   \ | 
|---|
| 166 | }                                                                       \ | 
|---|
| 167 | while (0) | 
|---|
| 168 |  | 
|---|
| 169 | #define _FP_FRAC_SUB_8(R, X, Y)                                             \ | 
|---|
| 170 | do                                                                        \ | 
|---|
| 171 | {                                                                       \ | 
|---|
| 172 | _FP_W_TYPE _FP_FRAC_SUB_8_tmp[8];                                     \ | 
|---|
| 173 | _FP_W_TYPE _FP_FRAC_SUB_8_c = 0;                                      \ | 
|---|
| 174 | _FP_I_TYPE _FP_FRAC_SUB_8_i;                                          \ | 
|---|
| 175 | for (_FP_FRAC_SUB_8_i = 0; _FP_FRAC_SUB_8_i < 8; ++_FP_FRAC_SUB_8_i)  \ | 
|---|
| 176 | {                                                                   \ | 
|---|
| 177 | _FP_FRAC_SUB_8_tmp[_FP_FRAC_SUB_8_i]                              \ | 
|---|
| 178 | = (X##_f[_FP_FRAC_SUB_8_i] - Y##_f[_FP_FRAC_SUB_8_i]            \ | 
|---|
| 179 | - _FP_FRAC_SUB_8_c);                                         \ | 
|---|
| 180 | _FP_FRAC_SUB_8_c                                                  \ | 
|---|
| 181 | = (_FP_FRAC_SUB_8_c                                             \ | 
|---|
| 182 | ? (_FP_FRAC_SUB_8_tmp[_FP_FRAC_SUB_8_i]                      \ | 
|---|
| 183 | >= X##_f[_FP_FRAC_SUB_8_i])                               \ | 
|---|
| 184 | : (_FP_FRAC_SUB_8_tmp[_FP_FRAC_SUB_8_i]                      \ | 
|---|
| 185 | > X##_f[_FP_FRAC_SUB_8_i]));                              \ | 
|---|
| 186 | }                                                                   \ | 
|---|
| 187 | for (_FP_FRAC_SUB_8_i = 0; _FP_FRAC_SUB_8_i < 8; ++_FP_FRAC_SUB_8_i)  \ | 
|---|
| 188 | R##_f[_FP_FRAC_SUB_8_i] = _FP_FRAC_SUB_8_tmp[_FP_FRAC_SUB_8_i];     \ | 
|---|
| 189 | }                                                                       \ | 
|---|
| 190 | while (0) | 
|---|
| 191 |  | 
|---|
| 192 | #define _FP_FRAC_CLZ_8(R, X)                                                \ | 
|---|
| 193 | do                                                                        \ | 
|---|
| 194 | {                                                                       \ | 
|---|
| 195 | _FP_I_TYPE _FP_FRAC_CLZ_8_i;                                          \ | 
|---|
| 196 | for (_FP_FRAC_CLZ_8_i = 7; _FP_FRAC_CLZ_8_i > 0; _FP_FRAC_CLZ_8_i--)  \ | 
|---|
| 197 | if (X##_f[_FP_FRAC_CLZ_8_i])                                        \ | 
|---|
| 198 | break;                                                            \ | 
|---|
| 199 | __FP_CLZ ((R), X##_f[_FP_FRAC_CLZ_8_i]);                              \ | 
|---|
| 200 | (R) += _FP_W_TYPE_SIZE * (7 - _FP_FRAC_CLZ_8_i);                      \ | 
|---|
| 201 | }                                                                       \ | 
|---|
| 202 | while (0) | 
|---|
| 203 |  | 
|---|
| 204 | #define _FP_MINFRAC_8   0, 0, 0, 0, 0, 0, 0, 1 | 
|---|
| 205 |  | 
|---|
| 206 | #define _FP_FRAC_NEGP_8(X)      ((_FP_WS_TYPE) X##_f[7] < 0) | 
|---|
| 207 | #define _FP_FRAC_ZEROP_8(X)                                             \ | 
|---|
| 208 | ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]                           \ | 
|---|
| 209 | | X##_f[4] | X##_f[5] | X##_f[6] | X##_f[7]) == 0) | 
|---|
| 210 | #define _FP_FRAC_HIGHBIT_DW_8(fs, X)                                    \ | 
|---|
| 211 | (_FP_FRAC_HIGH_DW_##fs (X) & _FP_HIGHBIT_DW_##fs) | 
|---|
| 212 |  | 
|---|
| 213 | #define _FP_FRAC_COPY_4_8(D, S)                           \ | 
|---|
| 214 | do                                                      \ | 
|---|
| 215 | {                                                     \ | 
|---|
| 216 | D##_f[0] = S##_f[0];                                \ | 
|---|
| 217 | D##_f[1] = S##_f[1];                                \ | 
|---|
| 218 | D##_f[2] = S##_f[2];                                \ | 
|---|
| 219 | D##_f[3] = S##_f[3];                                \ | 
|---|
| 220 | }                                                     \ | 
|---|
| 221 | while (0) | 
|---|
| 222 |  | 
|---|
| 223 | #define _FP_FRAC_COPY_8_4(D, S)                           \ | 
|---|
| 224 | do                                                      \ | 
|---|
| 225 | {                                                     \ | 
|---|
| 226 | D##_f[0] = S##_f[0];                                \ | 
|---|
| 227 | D##_f[1] = S##_f[1];                                \ | 
|---|
| 228 | D##_f[2] = S##_f[2];                                \ | 
|---|
| 229 | D##_f[3] = S##_f[3];                                \ | 
|---|
| 230 | D##_f[4] = D##_f[5] = D##_f[6] = D##_f[7]= 0;       \ | 
|---|
| 231 | }                                                     \ | 
|---|
| 232 | while (0) | 
|---|
| 233 |  | 
|---|
| 234 | #define __FP_FRAC_SET_8(X, I7, I6, I5, I4, I3, I2, I1, I0)             \ | 
|---|
| 235 | (X##_f[7] = I7, X##_f[6] = I6, X##_f[5] = I5, X##_f[4] = I4,         \ | 
|---|
| 236 | X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0) | 
|---|
| 237 |  | 
|---|
| 238 | #endif /* !SOFT_FP_OP_8_H */ | 
|---|
| 239 |  | 
|---|