Home | History | Annotate | Line # | Download | only in soft-fp
      1  1.1  mrg /* Software floating-point emulation.
      2  1.1  mrg    Definitions for IEEE Extended Precision.
      3  1.8  mrg    Copyright (C) 1999-2019 Free Software Foundation, Inc.
      4  1.1  mrg    This file is part of the GNU C Library.
      5  1.1  mrg    Contributed by Jakub Jelinek (jj (at) ultra.linux.cz).
      6  1.1  mrg 
      7  1.1  mrg    The GNU C Library is free software; you can redistribute it and/or
      8  1.1  mrg    modify it under the terms of the GNU Lesser General Public
      9  1.1  mrg    License as published by the Free Software Foundation; either
     10  1.1  mrg    version 2.1 of the License, or (at your option) any later version.
     11  1.1  mrg 
     12  1.1  mrg    In addition to the permissions in the GNU Lesser General Public
     13  1.1  mrg    License, the Free Software Foundation gives you unlimited
     14  1.1  mrg    permission to link the compiled version of this file into
     15  1.1  mrg    combinations with other programs, and to distribute those
     16  1.1  mrg    combinations without any restriction coming from the use of this
     17  1.1  mrg    file.  (The Lesser General Public License restrictions do apply in
     18  1.1  mrg    other respects; for example, they cover modification of the file,
     19  1.1  mrg    and distribution when not linked into a combine executable.)
     20  1.1  mrg 
     21  1.1  mrg    The GNU C Library is distributed in the hope that it will be useful,
     22  1.1  mrg    but WITHOUT ANY WARRANTY; without even the implied warranty of
     23  1.1  mrg    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     24  1.1  mrg    Lesser General Public License for more details.
     25  1.1  mrg 
     26  1.1  mrg    You should have received a copy of the GNU Lesser General Public
     27  1.1  mrg    License along with the GNU C Library; if not, see
     28  1.1  mrg    <http://www.gnu.org/licenses/>.  */
     29  1.1  mrg 
     30  1.4  mrg #ifndef SOFT_FP_EXTENDED_H
     31  1.4  mrg #define SOFT_FP_EXTENDED_H	1
     32  1.4  mrg 
     33  1.1  mrg #if _FP_W_TYPE_SIZE < 32
     34  1.3  mrg # error "Here's a nickel, kid. Go buy yourself a real computer."
     35  1.1  mrg #endif
     36  1.1  mrg 
     37  1.1  mrg #if _FP_W_TYPE_SIZE < 64
     38  1.3  mrg # define _FP_FRACTBITS_E	(4*_FP_W_TYPE_SIZE)
     39  1.3  mrg # define _FP_FRACTBITS_DW_E	(8*_FP_W_TYPE_SIZE)
     40  1.1  mrg #else
     41  1.3  mrg # define _FP_FRACTBITS_E	(2*_FP_W_TYPE_SIZE)
     42  1.3  mrg # define _FP_FRACTBITS_DW_E	(4*_FP_W_TYPE_SIZE)
     43  1.1  mrg #endif
     44  1.1  mrg 
     45  1.1  mrg #define _FP_FRACBITS_E		64
     46  1.1  mrg #define _FP_FRACXBITS_E		(_FP_FRACTBITS_E - _FP_FRACBITS_E)
     47  1.1  mrg #define _FP_WFRACBITS_E		(_FP_WORKBITS + _FP_FRACBITS_E)
     48  1.1  mrg #define _FP_WFRACXBITS_E	(_FP_FRACTBITS_E - _FP_WFRACBITS_E)
     49  1.1  mrg #define _FP_EXPBITS_E		15
     50  1.1  mrg #define _FP_EXPBIAS_E		16383
     51  1.1  mrg #define _FP_EXPMAX_E		32767
     52  1.1  mrg 
     53  1.1  mrg #define _FP_QNANBIT_E		\
     54  1.3  mrg 	((_FP_W_TYPE) 1 << (_FP_FRACBITS_E-2) % _FP_W_TYPE_SIZE)
     55  1.1  mrg #define _FP_QNANBIT_SH_E		\
     56  1.3  mrg 	((_FP_W_TYPE) 1 << (_FP_FRACBITS_E-2+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
     57  1.1  mrg #define _FP_IMPLBIT_E		\
     58  1.3  mrg 	((_FP_W_TYPE) 1 << (_FP_FRACBITS_E-1) % _FP_W_TYPE_SIZE)
     59  1.1  mrg #define _FP_IMPLBIT_SH_E		\
     60  1.3  mrg 	((_FP_W_TYPE) 1 << (_FP_FRACBITS_E-1+_FP_WORKBITS) % _FP_W_TYPE_SIZE)
     61  1.1  mrg #define _FP_OVERFLOW_E		\
     62  1.3  mrg 	((_FP_W_TYPE) 1 << (_FP_WFRACBITS_E % _FP_W_TYPE_SIZE))
     63  1.1  mrg 
     64  1.3  mrg #define _FP_WFRACBITS_DW_E	(2 * _FP_WFRACBITS_E)
     65  1.3  mrg #define _FP_WFRACXBITS_DW_E	(_FP_FRACTBITS_DW_E - _FP_WFRACBITS_DW_E)
     66  1.3  mrg #define _FP_HIGHBIT_DW_E	\
     67  1.3  mrg   ((_FP_W_TYPE) 1 << (_FP_WFRACBITS_DW_E - 1) % _FP_W_TYPE_SIZE)
     68  1.3  mrg 
     69  1.3  mrg typedef float XFtype __attribute__ ((mode (XF)));
     70  1.1  mrg 
     71  1.1  mrg #if _FP_W_TYPE_SIZE < 64
     72  1.1  mrg 
     73  1.1  mrg union _FP_UNION_E
     74  1.1  mrg {
     75  1.3  mrg   XFtype flt;
     76  1.3  mrg   struct _FP_STRUCT_LAYOUT
     77  1.3  mrg   {
     78  1.3  mrg # if __BYTE_ORDER == __BIG_ENDIAN
     79  1.3  mrg     unsigned long pad1 : _FP_W_TYPE_SIZE;
     80  1.3  mrg     unsigned long pad2 : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
     81  1.3  mrg     unsigned long sign : 1;
     82  1.3  mrg     unsigned long exp : _FP_EXPBITS_E;
     83  1.3  mrg     unsigned long frac1 : _FP_W_TYPE_SIZE;
     84  1.3  mrg     unsigned long frac0 : _FP_W_TYPE_SIZE;
     85  1.3  mrg # else
     86  1.3  mrg     unsigned long frac0 : _FP_W_TYPE_SIZE;
     87  1.3  mrg     unsigned long frac1 : _FP_W_TYPE_SIZE;
     88  1.3  mrg     unsigned exp : _FP_EXPBITS_E;
     89  1.3  mrg     unsigned sign : 1;
     90  1.3  mrg # endif /* not bigendian */
     91  1.7  mrg   } bits;
     92  1.1  mrg };
     93  1.1  mrg 
     94  1.1  mrg 
     95  1.3  mrg # define FP_DECL_E(X)		_FP_DECL (4, X)
     96  1.1  mrg 
     97  1.3  mrg # define FP_UNPACK_RAW_E(X, val)			\
     98  1.3  mrg   do							\
     99  1.3  mrg     {							\
    100  1.3  mrg       union _FP_UNION_E FP_UNPACK_RAW_E_flo;		\
    101  1.3  mrg       FP_UNPACK_RAW_E_flo.flt = (val);			\
    102  1.1  mrg 							\
    103  1.3  mrg       X##_f[2] = 0;					\
    104  1.3  mrg       X##_f[3] = 0;					\
    105  1.3  mrg       X##_f[0] = FP_UNPACK_RAW_E_flo.bits.frac0;	\
    106  1.3  mrg       X##_f[1] = FP_UNPACK_RAW_E_flo.bits.frac1;	\
    107  1.6  mrg       X##_f[1] &= ~_FP_IMPLBIT_E;			\
    108  1.3  mrg       X##_e  = FP_UNPACK_RAW_E_flo.bits.exp;		\
    109  1.3  mrg       X##_s  = FP_UNPACK_RAW_E_flo.bits.sign;		\
    110  1.3  mrg     }							\
    111  1.3  mrg   while (0)
    112  1.3  mrg 
    113  1.3  mrg # define FP_UNPACK_RAW_EP(X, val)			\
    114  1.3  mrg   do							\
    115  1.3  mrg     {							\
    116  1.3  mrg       union _FP_UNION_E *FP_UNPACK_RAW_EP_flo		\
    117  1.3  mrg 	= (union _FP_UNION_E *) (val);			\
    118  1.1  mrg 							\
    119  1.3  mrg       X##_f[2] = 0;					\
    120  1.3  mrg       X##_f[3] = 0;					\
    121  1.3  mrg       X##_f[0] = FP_UNPACK_RAW_EP_flo->bits.frac0;	\
    122  1.3  mrg       X##_f[1] = FP_UNPACK_RAW_EP_flo->bits.frac1;	\
    123  1.6  mrg       X##_f[1] &= ~_FP_IMPLBIT_E;			\
    124  1.3  mrg       X##_e  = FP_UNPACK_RAW_EP_flo->bits.exp;		\
    125  1.3  mrg       X##_s  = FP_UNPACK_RAW_EP_flo->bits.sign;		\
    126  1.3  mrg     }							\
    127  1.3  mrg   while (0)
    128  1.3  mrg 
    129  1.3  mrg # define FP_PACK_RAW_E(val, X)			\
    130  1.3  mrg   do						\
    131  1.3  mrg     {						\
    132  1.3  mrg       union _FP_UNION_E FP_PACK_RAW_E_flo;	\
    133  1.3  mrg 						\
    134  1.3  mrg       if (X##_e)				\
    135  1.3  mrg 	X##_f[1] |= _FP_IMPLBIT_E;		\
    136  1.3  mrg       else					\
    137  1.3  mrg 	X##_f[1] &= ~(_FP_IMPLBIT_E);		\
    138  1.3  mrg       FP_PACK_RAW_E_flo.bits.frac0 = X##_f[0];	\
    139  1.3  mrg       FP_PACK_RAW_E_flo.bits.frac1 = X##_f[1];	\
    140  1.3  mrg       FP_PACK_RAW_E_flo.bits.exp   = X##_e;	\
    141  1.3  mrg       FP_PACK_RAW_E_flo.bits.sign  = X##_s;	\
    142  1.3  mrg 						\
    143  1.3  mrg       (val) = FP_PACK_RAW_E_flo.flt;		\
    144  1.3  mrg     }						\
    145  1.3  mrg   while (0)
    146  1.3  mrg 
    147  1.3  mrg # define FP_PACK_RAW_EP(val, X)				\
    148  1.3  mrg   do							\
    149  1.3  mrg     {							\
    150  1.3  mrg       if (!FP_INHIBIT_RESULTS)				\
    151  1.3  mrg 	{						\
    152  1.3  mrg 	  union _FP_UNION_E *FP_PACK_RAW_EP_flo		\
    153  1.3  mrg 	    = (union _FP_UNION_E *) (val);		\
    154  1.1  mrg 							\
    155  1.3  mrg 	  if (X##_e)					\
    156  1.3  mrg 	    X##_f[1] |= _FP_IMPLBIT_E;			\
    157  1.3  mrg 	  else						\
    158  1.3  mrg 	    X##_f[1] &= ~(_FP_IMPLBIT_E);		\
    159  1.3  mrg 	  FP_PACK_RAW_EP_flo->bits.frac0 = X##_f[0];	\
    160  1.3  mrg 	  FP_PACK_RAW_EP_flo->bits.frac1 = X##_f[1];	\
    161  1.3  mrg 	  FP_PACK_RAW_EP_flo->bits.exp   = X##_e;	\
    162  1.3  mrg 	  FP_PACK_RAW_EP_flo->bits.sign  = X##_s;	\
    163  1.3  mrg 	}						\
    164  1.3  mrg     }							\
    165  1.3  mrg   while (0)
    166  1.3  mrg 
    167  1.3  mrg # define FP_UNPACK_E(X, val)			\
    168  1.3  mrg   do						\
    169  1.3  mrg     {						\
    170  1.3  mrg       FP_UNPACK_RAW_E (X, (val));		\
    171  1.3  mrg       _FP_UNPACK_CANONICAL (E, 4, X);		\
    172  1.3  mrg     }						\
    173  1.3  mrg   while (0)
    174  1.3  mrg 
    175  1.3  mrg # define FP_UNPACK_EP(X, val)			\
    176  1.3  mrg   do						\
    177  1.3  mrg     {						\
    178  1.3  mrg       FP_UNPACK_RAW_EP (X, (val));		\
    179  1.3  mrg       _FP_UNPACK_CANONICAL (E, 4, X);		\
    180  1.3  mrg     }						\
    181  1.3  mrg   while (0)
    182  1.3  mrg 
    183  1.3  mrg # define FP_UNPACK_SEMIRAW_E(X, val)		\
    184  1.3  mrg   do						\
    185  1.3  mrg     {						\
    186  1.3  mrg       FP_UNPACK_RAW_E (X, (val));		\
    187  1.3  mrg       _FP_UNPACK_SEMIRAW (E, 4, X);		\
    188  1.3  mrg     }						\
    189  1.3  mrg   while (0)
    190  1.3  mrg 
    191  1.3  mrg # define FP_UNPACK_SEMIRAW_EP(X, val)		\
    192  1.3  mrg   do						\
    193  1.3  mrg     {						\
    194  1.3  mrg       FP_UNPACK_RAW_EP (X, (val));		\
    195  1.3  mrg       _FP_UNPACK_SEMIRAW (E, 4, X);		\
    196  1.3  mrg     }						\
    197  1.3  mrg   while (0)
    198  1.3  mrg 
    199  1.3  mrg # define FP_PACK_E(val, X)			\
    200  1.3  mrg   do						\
    201  1.3  mrg     {						\
    202  1.3  mrg       _FP_PACK_CANONICAL (E, 4, X);		\
    203  1.3  mrg       FP_PACK_RAW_E ((val), X);			\
    204  1.3  mrg     }						\
    205  1.3  mrg   while (0)
    206  1.3  mrg 
    207  1.3  mrg # define FP_PACK_EP(val, X)			\
    208  1.3  mrg   do						\
    209  1.3  mrg     {						\
    210  1.3  mrg       _FP_PACK_CANONICAL (E, 4, X);		\
    211  1.3  mrg       FP_PACK_RAW_EP ((val), X);		\
    212  1.3  mrg     }						\
    213  1.3  mrg   while (0)
    214  1.3  mrg 
    215  1.3  mrg # define FP_PACK_SEMIRAW_E(val, X)		\
    216  1.3  mrg   do						\
    217  1.3  mrg     {						\
    218  1.3  mrg       _FP_PACK_SEMIRAW (E, 4, X);		\
    219  1.3  mrg       FP_PACK_RAW_E ((val), X);			\
    220  1.3  mrg     }						\
    221  1.3  mrg   while (0)
    222  1.3  mrg 
    223  1.3  mrg # define FP_PACK_SEMIRAW_EP(val, X)		\
    224  1.3  mrg   do						\
    225  1.3  mrg     {						\
    226  1.3  mrg       _FP_PACK_SEMIRAW (E, 4, X);		\
    227  1.3  mrg       FP_PACK_RAW_EP ((val), X);		\
    228  1.3  mrg     }						\
    229  1.3  mrg   while (0)
    230  1.3  mrg 
    231  1.3  mrg # define FP_ISSIGNAN_E(X)	_FP_ISSIGNAN (E, 4, X)
    232  1.3  mrg # define FP_NEG_E(R, X)		_FP_NEG (E, 4, R, X)
    233  1.3  mrg # define FP_ADD_E(R, X, Y)	_FP_ADD (E, 4, R, X, Y)
    234  1.3  mrg # define FP_SUB_E(R, X, Y)	_FP_SUB (E, 4, R, X, Y)
    235  1.3  mrg # define FP_MUL_E(R, X, Y)	_FP_MUL (E, 4, R, X, Y)
    236  1.3  mrg # define FP_DIV_E(R, X, Y)	_FP_DIV (E, 4, R, X, Y)
    237  1.3  mrg # define FP_SQRT_E(R, X)	_FP_SQRT (E, 4, R, X)
    238  1.3  mrg # define FP_FMA_E(R, X, Y, Z)	_FP_FMA (E, 4, 8, R, X, Y, Z)
    239  1.3  mrg 
    240  1.3  mrg /* Square root algorithms:
    241  1.3  mrg    We have just one right now, maybe Newton approximation
    242  1.3  mrg    should be added for those machines where division is fast.
    243  1.3  mrg    This has special _E version because standard _4 square
    244  1.3  mrg    root would not work (it has to start normally with the
    245  1.3  mrg    second word and not the first), but as we have to do it
    246  1.3  mrg    anyway, we optimize it by doing most of the calculations
    247  1.3  mrg    in two UWtype registers instead of four.  */
    248  1.3  mrg 
    249  1.3  mrg # define _FP_SQRT_MEAT_E(R, S, T, X, q)			\
    250  1.3  mrg   do							\
    251  1.3  mrg     {							\
    252  1.3  mrg       (q) = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1);	\
    253  1.3  mrg       _FP_FRAC_SRL_4 (X, (_FP_WORKBITS));		\
    254  1.3  mrg       while (q)						\
    255  1.3  mrg 	{						\
    256  1.3  mrg 	  T##_f[1] = S##_f[1] + (q);			\
    257  1.3  mrg 	  if (T##_f[1] <= X##_f[1])			\
    258  1.3  mrg 	    {						\
    259  1.3  mrg 	      S##_f[1] = T##_f[1] + (q);		\
    260  1.3  mrg 	      X##_f[1] -= T##_f[1];			\
    261  1.3  mrg 	      R##_f[1] += (q);				\
    262  1.3  mrg 	    }						\
    263  1.3  mrg 	  _FP_FRAC_SLL_2 (X, 1);			\
    264  1.3  mrg 	  (q) >>= 1;					\
    265  1.3  mrg 	}						\
    266  1.3  mrg       (q) = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1);	\
    267  1.3  mrg       while (q)						\
    268  1.3  mrg 	{						\
    269  1.3  mrg 	  T##_f[0] = S##_f[0] + (q);			\
    270  1.3  mrg 	  T##_f[1] = S##_f[1];				\
    271  1.3  mrg 	  if (T##_f[1] < X##_f[1]			\
    272  1.3  mrg 	      || (T##_f[1] == X##_f[1]			\
    273  1.3  mrg 		  && T##_f[0] <= X##_f[0]))		\
    274  1.3  mrg 	    {						\
    275  1.3  mrg 	      S##_f[0] = T##_f[0] + (q);		\
    276  1.3  mrg 	      S##_f[1] += (T##_f[0] > S##_f[0]);	\
    277  1.3  mrg 	      _FP_FRAC_DEC_2 (X, T);			\
    278  1.3  mrg 	      R##_f[0] += (q);				\
    279  1.3  mrg 	    }						\
    280  1.3  mrg 	  _FP_FRAC_SLL_2 (X, 1);			\
    281  1.3  mrg 	  (q) >>= 1;					\
    282  1.3  mrg 	}						\
    283  1.3  mrg       _FP_FRAC_SLL_4 (R, (_FP_WORKBITS));		\
    284  1.3  mrg       if (X##_f[0] | X##_f[1])				\
    285  1.3  mrg 	{						\
    286  1.3  mrg 	  if (S##_f[1] < X##_f[1]			\
    287  1.3  mrg 	      || (S##_f[1] == X##_f[1]			\
    288  1.3  mrg 		  && S##_f[0] < X##_f[0]))		\
    289  1.3  mrg 	    R##_f[0] |= _FP_WORK_ROUND;			\
    290  1.3  mrg 	  R##_f[0] |= _FP_WORK_STICKY;			\
    291  1.3  mrg 	}						\
    292  1.3  mrg     }							\
    293  1.3  mrg   while (0)
    294  1.3  mrg 
    295  1.3  mrg # define FP_CMP_E(r, X, Y, un, ex)	_FP_CMP (E, 4, (r), X, Y, (un), (ex))
    296  1.3  mrg # define FP_CMP_EQ_E(r, X, Y, ex)	_FP_CMP_EQ (E, 4, (r), X, Y, (ex))
    297  1.3  mrg # define FP_CMP_UNORD_E(r, X, Y, ex)	_FP_CMP_UNORD (E, 4, (r), X, Y, (ex))
    298  1.1  mrg 
    299  1.3  mrg # define FP_TO_INT_E(r, X, rsz, rsg)	_FP_TO_INT (E, 4, (r), X, (rsz), (rsg))
    300  1.4  mrg # define FP_TO_INT_ROUND_E(r, X, rsz, rsg)	\
    301  1.4  mrg   _FP_TO_INT_ROUND (E, 4, (r), X, (rsz), (rsg))
    302  1.3  mrg # define FP_FROM_INT_E(X, r, rs, rt)	_FP_FROM_INT (E, 4, X, (r), (rs), rt)
    303  1.1  mrg 
    304  1.3  mrg # define _FP_FRAC_HIGH_E(X)	(X##_f[2])
    305  1.3  mrg # define _FP_FRAC_HIGH_RAW_E(X)	(X##_f[1])
    306  1.1  mrg 
    307  1.3  mrg # define _FP_FRAC_HIGH_DW_E(X)	(X##_f[4])
    308  1.1  mrg 
    309  1.1  mrg #else   /* not _FP_W_TYPE_SIZE < 64 */
    310  1.1  mrg union _FP_UNION_E
    311  1.1  mrg {
    312  1.1  mrg   XFtype flt;
    313  1.3  mrg   struct _FP_STRUCT_LAYOUT
    314  1.3  mrg   {
    315  1.3  mrg # if __BYTE_ORDER == __BIG_ENDIAN
    316  1.1  mrg     _FP_W_TYPE pad  : (_FP_W_TYPE_SIZE - 1 - _FP_EXPBITS_E);
    317  1.1  mrg     unsigned sign   : 1;
    318  1.1  mrg     unsigned exp    : _FP_EXPBITS_E;
    319  1.1  mrg     _FP_W_TYPE frac : _FP_W_TYPE_SIZE;
    320  1.3  mrg # else
    321  1.1  mrg     _FP_W_TYPE frac : _FP_W_TYPE_SIZE;
    322  1.1  mrg     unsigned exp    : _FP_EXPBITS_E;
    323  1.1  mrg     unsigned sign   : 1;
    324  1.3  mrg # endif
    325  1.1  mrg   } bits;
    326  1.1  mrg };
    327  1.1  mrg 
    328  1.3  mrg # define FP_DECL_E(X)		_FP_DECL (2, X)
    329  1.3  mrg 
    330  1.3  mrg # define FP_UNPACK_RAW_E(X, val)		\
    331  1.3  mrg   do						\
    332  1.3  mrg     {						\
    333  1.3  mrg       union _FP_UNION_E FP_UNPACK_RAW_E_flo;	\
    334  1.3  mrg       FP_UNPACK_RAW_E_flo.flt = (val);		\
    335  1.3  mrg 						\
    336  1.3  mrg       X##_f0 = FP_UNPACK_RAW_E_flo.bits.frac;	\
    337  1.6  mrg       X##_f0 &= ~_FP_IMPLBIT_E;			\
    338  1.3  mrg       X##_f1 = 0;				\
    339  1.3  mrg       X##_e = FP_UNPACK_RAW_E_flo.bits.exp;	\
    340  1.3  mrg       X##_s = FP_UNPACK_RAW_E_flo.bits.sign;	\
    341  1.3  mrg     }						\
    342  1.3  mrg   while (0)
    343  1.3  mrg 
    344  1.3  mrg # define FP_UNPACK_RAW_EP(X, val)		\
    345  1.3  mrg   do						\
    346  1.3  mrg     {						\
    347  1.3  mrg       union _FP_UNION_E *FP_UNPACK_RAW_EP_flo	\
    348  1.3  mrg 	= (union _FP_UNION_E *) (val);		\
    349  1.3  mrg 						\
    350  1.3  mrg       X##_f0 = FP_UNPACK_RAW_EP_flo->bits.frac;	\
    351  1.6  mrg       X##_f0 &= ~_FP_IMPLBIT_E;			\
    352  1.3  mrg       X##_f1 = 0;				\
    353  1.3  mrg       X##_e = FP_UNPACK_RAW_EP_flo->bits.exp;	\
    354  1.3  mrg       X##_s = FP_UNPACK_RAW_EP_flo->bits.sign;	\
    355  1.3  mrg     }						\
    356  1.3  mrg   while (0)
    357  1.3  mrg 
    358  1.3  mrg # define FP_PACK_RAW_E(val, X)			\
    359  1.3  mrg   do						\
    360  1.3  mrg     {						\
    361  1.3  mrg       union _FP_UNION_E FP_PACK_RAW_E_flo;	\
    362  1.3  mrg 						\
    363  1.3  mrg       if (X##_e)				\
    364  1.3  mrg 	X##_f0 |= _FP_IMPLBIT_E;		\
    365  1.3  mrg       else					\
    366  1.3  mrg 	X##_f0 &= ~(_FP_IMPLBIT_E);		\
    367  1.3  mrg       FP_PACK_RAW_E_flo.bits.frac = X##_f0;	\
    368  1.3  mrg       FP_PACK_RAW_E_flo.bits.exp  = X##_e;	\
    369  1.3  mrg       FP_PACK_RAW_E_flo.bits.sign = X##_s;	\
    370  1.3  mrg 						\
    371  1.3  mrg       (val) = FP_PACK_RAW_E_flo.flt;		\
    372  1.3  mrg     }						\
    373  1.3  mrg   while (0)
    374  1.3  mrg 
    375  1.3  mrg # define FP_PACK_RAW_EP(fs, val, X)			\
    376  1.3  mrg   do							\
    377  1.3  mrg     {							\
    378  1.3  mrg       if (!FP_INHIBIT_RESULTS)				\
    379  1.3  mrg 	{						\
    380  1.3  mrg 	  union _FP_UNION_E *FP_PACK_RAW_EP_flo		\
    381  1.3  mrg 	    = (union _FP_UNION_E *) (val);		\
    382  1.3  mrg 							\
    383  1.3  mrg 	  if (X##_e)					\
    384  1.3  mrg 	    X##_f0 |= _FP_IMPLBIT_E;			\
    385  1.3  mrg 	  else						\
    386  1.3  mrg 	    X##_f0 &= ~(_FP_IMPLBIT_E);			\
    387  1.3  mrg 	  FP_PACK_RAW_EP_flo->bits.frac = X##_f0;	\
    388  1.3  mrg 	  FP_PACK_RAW_EP_flo->bits.exp  = X##_e;	\
    389  1.3  mrg 	  FP_PACK_RAW_EP_flo->bits.sign = X##_s;	\
    390  1.3  mrg 	}						\
    391  1.3  mrg     }							\
    392  1.3  mrg   while (0)
    393  1.3  mrg 
    394  1.3  mrg 
    395  1.3  mrg # define FP_UNPACK_E(X, val)			\
    396  1.3  mrg   do						\
    397  1.3  mrg     {						\
    398  1.3  mrg       FP_UNPACK_RAW_E (X, (val));		\
    399  1.3  mrg       _FP_UNPACK_CANONICAL (E, 2, X);		\
    400  1.3  mrg     }						\
    401  1.3  mrg   while (0)
    402  1.3  mrg 
    403  1.3  mrg # define FP_UNPACK_EP(X, val)			\
    404  1.3  mrg   do						\
    405  1.3  mrg     {						\
    406  1.3  mrg       FP_UNPACK_RAW_EP (X, (val));		\
    407  1.3  mrg       _FP_UNPACK_CANONICAL (E, 2, X);		\
    408  1.3  mrg     }						\
    409  1.3  mrg   while (0)
    410  1.3  mrg 
    411  1.3  mrg # define FP_UNPACK_SEMIRAW_E(X, val)		\
    412  1.3  mrg   do						\
    413  1.3  mrg     {						\
    414  1.3  mrg       FP_UNPACK_RAW_E (X, (val));		\
    415  1.3  mrg       _FP_UNPACK_SEMIRAW (E, 2, X);		\
    416  1.3  mrg     }						\
    417  1.3  mrg   while (0)
    418  1.3  mrg 
    419  1.3  mrg # define FP_UNPACK_SEMIRAW_EP(X, val)		\
    420  1.3  mrg   do						\
    421  1.3  mrg     {						\
    422  1.3  mrg       FP_UNPACK_RAW_EP (X, (val));		\
    423  1.3  mrg       _FP_UNPACK_SEMIRAW (E, 2, X);		\
    424  1.3  mrg     }						\
    425  1.3  mrg   while (0)
    426  1.3  mrg 
    427  1.3  mrg # define FP_PACK_E(val, X)			\
    428  1.3  mrg   do						\
    429  1.3  mrg     {						\
    430  1.3  mrg       _FP_PACK_CANONICAL (E, 2, X);		\
    431  1.3  mrg       FP_PACK_RAW_E ((val), X);			\
    432  1.3  mrg     }						\
    433  1.3  mrg   while (0)
    434  1.3  mrg 
    435  1.3  mrg # define FP_PACK_EP(val, X)			\
    436  1.3  mrg   do						\
    437  1.3  mrg     {						\
    438  1.3  mrg       _FP_PACK_CANONICAL (E, 2, X);		\
    439  1.3  mrg       FP_PACK_RAW_EP ((val), X);		\
    440  1.3  mrg     }						\
    441  1.3  mrg   while (0)
    442  1.3  mrg 
    443  1.3  mrg # define FP_PACK_SEMIRAW_E(val, X)		\
    444  1.3  mrg   do						\
    445  1.3  mrg     {						\
    446  1.3  mrg       _FP_PACK_SEMIRAW (E, 2, X);		\
    447  1.3  mrg       FP_PACK_RAW_E ((val), X);			\
    448  1.3  mrg     }						\
    449  1.3  mrg   while (0)
    450  1.3  mrg 
    451  1.3  mrg # define FP_PACK_SEMIRAW_EP(val, X)		\
    452  1.3  mrg   do						\
    453  1.3  mrg     {						\
    454  1.3  mrg       _FP_PACK_SEMIRAW (E, 2, X);		\
    455  1.3  mrg       FP_PACK_RAW_EP ((val), X);		\
    456  1.3  mrg     }						\
    457  1.3  mrg   while (0)
    458  1.3  mrg 
    459  1.3  mrg # define FP_ISSIGNAN_E(X)	_FP_ISSIGNAN (E, 2, X)
    460  1.3  mrg # define FP_NEG_E(R, X)		_FP_NEG (E, 2, R, X)
    461  1.3  mrg # define FP_ADD_E(R, X, Y)	_FP_ADD (E, 2, R, X, Y)
    462  1.3  mrg # define FP_SUB_E(R, X, Y)	_FP_SUB (E, 2, R, X, Y)
    463  1.3  mrg # define FP_MUL_E(R, X, Y)	_FP_MUL (E, 2, R, X, Y)
    464  1.3  mrg # define FP_DIV_E(R, X, Y)	_FP_DIV (E, 2, R, X, Y)
    465  1.3  mrg # define FP_SQRT_E(R, X)	_FP_SQRT (E, 2, R, X)
    466  1.3  mrg # define FP_FMA_E(R, X, Y, Z)	_FP_FMA (E, 2, 4, R, X, Y, Z)
    467  1.3  mrg 
    468  1.3  mrg /* Square root algorithms:
    469  1.3  mrg    We have just one right now, maybe Newton approximation
    470  1.3  mrg    should be added for those machines where division is fast.
    471  1.3  mrg    We optimize it by doing most of the calculations
    472  1.3  mrg    in one UWtype registers instead of two, although we don't
    473  1.3  mrg    have to.  */
    474  1.3  mrg # define _FP_SQRT_MEAT_E(R, S, T, X, q)			\
    475  1.3  mrg   do							\
    476  1.3  mrg     {							\
    477  1.3  mrg       (q) = (_FP_W_TYPE) 1 << (_FP_W_TYPE_SIZE - 1);	\
    478  1.3  mrg       _FP_FRAC_SRL_2 (X, (_FP_WORKBITS));		\
    479  1.3  mrg       while (q)						\
    480  1.3  mrg 	{						\
    481  1.3  mrg 	  T##_f0 = S##_f0 + (q);			\
    482  1.3  mrg 	  if (T##_f0 <= X##_f0)				\
    483  1.3  mrg 	    {						\
    484  1.3  mrg 	      S##_f0 = T##_f0 + (q);			\
    485  1.3  mrg 	      X##_f0 -= T##_f0;				\
    486  1.3  mrg 	      R##_f0 += (q);				\
    487  1.3  mrg 	    }						\
    488  1.3  mrg 	  _FP_FRAC_SLL_1 (X, 1);			\
    489  1.3  mrg 	  (q) >>= 1;					\
    490  1.3  mrg 	}						\
    491  1.3  mrg       _FP_FRAC_SLL_2 (R, (_FP_WORKBITS));		\
    492  1.3  mrg       if (X##_f0)					\
    493  1.3  mrg 	{						\
    494  1.3  mrg 	  if (S##_f0 < X##_f0)				\
    495  1.3  mrg 	    R##_f0 |= _FP_WORK_ROUND;			\
    496  1.3  mrg 	  R##_f0 |= _FP_WORK_STICKY;			\
    497  1.3  mrg 	}						\
    498  1.3  mrg     }							\
    499  1.3  mrg   while (0)
    500  1.3  mrg 
    501  1.3  mrg # define FP_CMP_E(r, X, Y, un, ex)	_FP_CMP (E, 2, (r), X, Y, (un), (ex))
    502  1.3  mrg # define FP_CMP_EQ_E(r, X, Y, ex)	_FP_CMP_EQ (E, 2, (r), X, Y, (ex))
    503  1.3  mrg # define FP_CMP_UNORD_E(r, X, Y, ex)	_FP_CMP_UNORD (E, 2, (r), X, Y, (ex))
    504  1.1  mrg 
    505  1.3  mrg # define FP_TO_INT_E(r, X, rsz, rsg)	_FP_TO_INT (E, 2, (r), X, (rsz), (rsg))
    506  1.4  mrg # define FP_TO_INT_ROUND_E(r, X, rsz, rsg)	\
    507  1.4  mrg   _FP_TO_INT_ROUND (E, 2, (r), X, (rsz), (rsg))
    508  1.3  mrg # define FP_FROM_INT_E(X, r, rs, rt)	_FP_FROM_INT (E, 2, X, (r), (rs), rt)
    509  1.1  mrg 
    510  1.3  mrg # define _FP_FRAC_HIGH_E(X)	(X##_f1)
    511  1.3  mrg # define _FP_FRAC_HIGH_RAW_E(X)	(X##_f0)
    512  1.1  mrg 
    513  1.3  mrg # define _FP_FRAC_HIGH_DW_E(X)	(X##_f[2])
    514  1.1  mrg 
    515  1.1  mrg #endif /* not _FP_W_TYPE_SIZE < 64 */
    516  1.4  mrg 
    517  1.4  mrg #endif /* !SOFT_FP_EXTENDED_H */
    518