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