~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/include/math-emu/op-common.h

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /include/math-emu/op-common.h (Version linux-6.12-rc7) and /include/math-emu/op-common.h (Version linux-5.2.21)


  1 /* Software floating-point emulation. Common o      1 /* Software floating-point emulation. Common operations.
  2    Copyright (C) 1997,1998,1999 Free Software       2    Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
  3    This file is part of the GNU C Library.          3    This file is part of the GNU C Library.
  4    Contributed by Richard Henderson (rth@cygnu      4    Contributed by Richard Henderson (rth@cygnus.com),
  5                   Jakub Jelinek (jj@ultra.linu      5                   Jakub Jelinek (jj@ultra.linux.cz),
  6                   David S. Miller (davem@redha      6                   David S. Miller (davem@redhat.com) and
  7                   Peter Maydell (pmaydell@chia      7                   Peter Maydell (pmaydell@chiark.greenend.org.uk).
  8                                                     8 
  9    The GNU C Library is free software; you can      9    The GNU C Library is free software; you can redistribute it and/or
 10    modify it under the terms of the GNU Librar     10    modify it under the terms of the GNU Library General Public License as
 11    published by the Free Software Foundation;      11    published by the Free Software Foundation; either version 2 of the
 12    License, or (at your option) any later vers     12    License, or (at your option) any later version.
 13                                                    13 
 14    The GNU C Library is distributed in the hop     14    The GNU C Library is distributed in the hope that it will be useful,
 15    but WITHOUT ANY WARRANTY; without even the      15    but WITHOUT ANY WARRANTY; without even the implied warranty of
 16    MERCHANTABILITY or FITNESS FOR A PARTICULAR     16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17    Library General Public License for more det     17    Library General Public License for more details.
 18                                                    18 
 19    You should have received a copy of the GNU      19    You should have received a copy of the GNU Library General Public
 20    License along with the GNU C Library; see t     20    License along with the GNU C Library; see the file COPYING.LIB.  If
 21    not, write to the Free Software Foundation,     21    not, write to the Free Software Foundation, Inc.,
 22    59 Temple Place - Suite 330, Boston, MA 021     22    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 23                                                    23 
 24 #ifndef __MATH_EMU_OP_COMMON_H__                   24 #ifndef __MATH_EMU_OP_COMMON_H__
 25 #define __MATH_EMU_OP_COMMON_H__                   25 #define __MATH_EMU_OP_COMMON_H__
 26                                                    26 
 27 #define _FP_DECL(wc, X)                 \          27 #define _FP_DECL(wc, X)                 \
 28   _FP_I_TYPE X##_c=0, X##_s=0, X##_e=0; \          28   _FP_I_TYPE X##_c=0, X##_s=0, X##_e=0; \
 29   _FP_FRAC_DECL_##wc(X)                            29   _FP_FRAC_DECL_##wc(X)
 30                                                    30 
 31 /*                                                 31 /*
 32  * Finish truly unpacking a native fp value by     32  * Finish truly unpacking a native fp value by classifying the kind
 33  * of fp value and normalizing both the expone     33  * of fp value and normalizing both the exponent and the fraction.
 34  */                                                34  */
 35                                                    35 
 36 #define _FP_UNPACK_CANONICAL(fs, wc, X)            36 #define _FP_UNPACK_CANONICAL(fs, wc, X)                                 \
 37 do {                                               37 do {                                                                    \
 38   switch (X##_e)                                   38   switch (X##_e)                                                        \
 39   {                                                39   {                                                                     \
 40   default:                                         40   default:                                                              \
 41     _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_#     41     _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_IMPLBIT_##fs;                      \
 42     _FP_FRAC_SLL_##wc(X, _FP_WORKBITS);            42     _FP_FRAC_SLL_##wc(X, _FP_WORKBITS);                                 \
 43     X##_e -= _FP_EXPBIAS_##fs;                     43     X##_e -= _FP_EXPBIAS_##fs;                                          \
 44     X##_c = FP_CLS_NORMAL;                         44     X##_c = FP_CLS_NORMAL;                                              \
 45     break;                                         45     break;                                                              \
 46                                                    46                                                                         \
 47   case 0:                                          47   case 0:                                                               \
 48     if (_FP_FRAC_ZEROP_##wc(X))                    48     if (_FP_FRAC_ZEROP_##wc(X))                                         \
 49       X##_c = FP_CLS_ZERO;                         49       X##_c = FP_CLS_ZERO;                                              \
 50     else                                           50     else                                                                \
 51       {                                            51       {                                                                 \
 52         /* a denormalized number */                52         /* a denormalized number */                                     \
 53         _FP_I_TYPE _shift;                         53         _FP_I_TYPE _shift;                                              \
 54         _FP_FRAC_CLZ_##wc(_shift, X);              54         _FP_FRAC_CLZ_##wc(_shift, X);                                   \
 55         _shift -= _FP_FRACXBITS_##fs;              55         _shift -= _FP_FRACXBITS_##fs;                                   \
 56         _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKB     56         _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS));                    \
 57         X##_e -= _FP_EXPBIAS_##fs - 1 + _shift     57         X##_e -= _FP_EXPBIAS_##fs - 1 + _shift;                         \
 58         X##_c = FP_CLS_NORMAL;                     58         X##_c = FP_CLS_NORMAL;                                          \
 59         FP_SET_EXCEPTION(FP_EX_DENORM);            59         FP_SET_EXCEPTION(FP_EX_DENORM);                                 \
 60         if (FP_DENORM_ZERO)                        60         if (FP_DENORM_ZERO)                                             \
 61           {                                        61           {                                                             \
 62             FP_SET_EXCEPTION(FP_EX_INEXACT);       62             FP_SET_EXCEPTION(FP_EX_INEXACT);                            \
 63             X##_c = FP_CLS_ZERO;                   63             X##_c = FP_CLS_ZERO;                                        \
 64           }                                        64           }                                                             \
 65       }                                            65       }                                                                 \
 66     break;                                         66     break;                                                              \
 67                                                    67                                                                         \
 68   case _FP_EXPMAX_##fs:                            68   case _FP_EXPMAX_##fs:                                                 \
 69     if (_FP_FRAC_ZEROP_##wc(X))                    69     if (_FP_FRAC_ZEROP_##wc(X))                                         \
 70       X##_c = FP_CLS_INF;                          70       X##_c = FP_CLS_INF;                                               \
 71     else                                           71     else                                                                \
 72       {                                            72       {                                                                 \
 73         X##_c = FP_CLS_NAN;                        73         X##_c = FP_CLS_NAN;                                             \
 74         /* Check for signaling NaN */              74         /* Check for signaling NaN */                                   \
 75         if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_     75         if (!(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))            \
 76           FP_SET_EXCEPTION(FP_EX_INVALID | FP_     76           FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_SNAN);         \
 77       }                                            77       }                                                                 \
 78     break;                                         78     break;                                                              \
 79   }                                                79   }                                                                     \
 80 } while (0)                                        80 } while (0)
 81                                                    81 
 82 /*                                                 82 /*
 83  * Before packing the bits back into the nativ     83  * Before packing the bits back into the native fp result, take care
 84  * of such mundane things as rounding and over     84  * of such mundane things as rounding and overflow.  Also, for some
 85  * kinds of fp values, the original parts may      85  * kinds of fp values, the original parts may not have been fully
 86  * extracted -- but that is ok, we can regener     86  * extracted -- but that is ok, we can regenerate them now.
 87  */                                                87  */
 88                                                    88 
 89 #define _FP_PACK_CANONICAL(fs, wc, X)              89 #define _FP_PACK_CANONICAL(fs, wc, X)                           \
 90 do {                                               90 do {                                                            \
 91   switch (X##_c)                                   91   switch (X##_c)                                                \
 92   {                                                92   {                                                             \
 93   case FP_CLS_NORMAL:                              93   case FP_CLS_NORMAL:                                           \
 94     X##_e += _FP_EXPBIAS_##fs;                     94     X##_e += _FP_EXPBIAS_##fs;                                  \
 95     if (X##_e > 0)                                 95     if (X##_e > 0)                                              \
 96       {                                            96       {                                                         \
 97         _FP_ROUND(wc, X);                          97         _FP_ROUND(wc, X);                                       \
 98         if (_FP_FRAC_OVERP_##wc(fs, X))            98         if (_FP_FRAC_OVERP_##wc(fs, X))                         \
 99           {                                        99           {                                                     \
100             _FP_FRAC_CLEAR_OVERP_##wc(fs, X);     100             _FP_FRAC_CLEAR_OVERP_##wc(fs, X);                   \
101             X##_e++;                              101             X##_e++;                                            \
102           }                                       102           }                                                     \
103         _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);       103         _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);                     \
104         if (X##_e >= _FP_EXPMAX_##fs)             104         if (X##_e >= _FP_EXPMAX_##fs)                           \
105           {                                       105           {                                                     \
106             /* overflow */                        106             /* overflow */                                      \
107             switch (FP_ROUNDMODE)                 107             switch (FP_ROUNDMODE)                               \
108               {                                   108               {                                                 \
109               case FP_RND_NEAREST:                109               case FP_RND_NEAREST:                              \
110                 X##_c = FP_CLS_INF;               110                 X##_c = FP_CLS_INF;                             \
111                 break;                            111                 break;                                          \
112               case FP_RND_PINF:                   112               case FP_RND_PINF:                                 \
113                 if (!X##_s) X##_c = FP_CLS_INF    113                 if (!X##_s) X##_c = FP_CLS_INF;                 \
114                 break;                            114                 break;                                          \
115               case FP_RND_MINF:                   115               case FP_RND_MINF:                                 \
116                 if (X##_s) X##_c = FP_CLS_INF;    116                 if (X##_s) X##_c = FP_CLS_INF;                  \
117                 break;                            117                 break;                                          \
118               }                                   118               }                                                 \
119             if (X##_c == FP_CLS_INF)              119             if (X##_c == FP_CLS_INF)                            \
120               {                                   120               {                                                 \
121                 /* Overflow to infinity */        121                 /* Overflow to infinity */                      \
122                 X##_e = _FP_EXPMAX_##fs;          122                 X##_e = _FP_EXPMAX_##fs;                        \
123                 _FP_FRAC_SET_##wc(X, _FP_ZEROF    123                 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);        \
124               }                                   124               }                                                 \
125             else                                  125             else                                                \
126               {                                   126               {                                                 \
127                 /* Overflow to maximum normal     127                 /* Overflow to maximum normal */                \
128                 X##_e = _FP_EXPMAX_##fs - 1;      128                 X##_e = _FP_EXPMAX_##fs - 1;                    \
129                 _FP_FRAC_SET_##wc(X, _FP_MAXFR    129                 _FP_FRAC_SET_##wc(X, _FP_MAXFRAC_##wc);         \
130               }                                   130               }                                                 \
131             FP_SET_EXCEPTION(FP_EX_OVERFLOW);     131             FP_SET_EXCEPTION(FP_EX_OVERFLOW);                   \
132             FP_SET_EXCEPTION(FP_EX_INEXACT);      132             FP_SET_EXCEPTION(FP_EX_INEXACT);                    \
133           }                                       133           }                                                     \
134       }                                           134       }                                                         \
135     else                                          135     else                                                        \
136       {                                           136       {                                                         \
137         /* we've got a denormalized number */     137         /* we've got a denormalized number */                   \
138         X##_e = -X##_e + 1;                       138         X##_e = -X##_e + 1;                                     \
139         if (X##_e <= _FP_WFRACBITS_##fs)          139         if (X##_e <= _FP_WFRACBITS_##fs)                        \
140           {                                       140           {                                                     \
141             _FP_FRAC_SRS_##wc(X, X##_e, _FP_WF    141             _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs);    \
142             if (_FP_FRAC_HIGH_##fs(X)             142             if (_FP_FRAC_HIGH_##fs(X)                           \
143                 & (_FP_OVERFLOW_##fs >> 1))       143                 & (_FP_OVERFLOW_##fs >> 1))                     \
144               {                                   144               {                                                 \
145                 X##_e = 1;                        145                 X##_e = 1;                                      \
146                 _FP_FRAC_SET_##wc(X, _FP_ZEROF    146                 _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);        \
147               }                                   147               }                                                 \
148             else                                  148             else                                                \
149               {                                   149               {                                                 \
150                 _FP_ROUND(wc, X);                 150                 _FP_ROUND(wc, X);                               \
151                 if (_FP_FRAC_HIGH_##fs(X)         151                 if (_FP_FRAC_HIGH_##fs(X)                       \
152                    & (_FP_OVERFLOW_##fs >> 1))    152                    & (_FP_OVERFLOW_##fs >> 1))                  \
153                   {                               153                   {                                             \
154                     X##_e = 1;                    154                     X##_e = 1;                                  \
155                     _FP_FRAC_SET_##wc(X, _FP_Z    155                     _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);    \
156                     FP_SET_EXCEPTION(FP_EX_INE    156                     FP_SET_EXCEPTION(FP_EX_INEXACT);            \
157                   }                               157                   }                                             \
158                 else                              158                 else                                            \
159                   {                               159                   {                                             \
160                     X##_e = 0;                    160                     X##_e = 0;                                  \
161                     _FP_FRAC_SRL_##wc(X, _FP_W    161                     _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);         \
162                   }                               162                   }                                             \
163               }                                   163               }                                                 \
164             if ((FP_CUR_EXCEPTIONS & FP_EX_INE    164             if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) ||          \
165                 (FP_TRAPPING_EXCEPTIONS & FP_E    165                 (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))     \
166                 FP_SET_EXCEPTION(FP_EX_UNDERFL    166                 FP_SET_EXCEPTION(FP_EX_UNDERFLOW);              \
167           }                                       167           }                                                     \
168         else                                      168         else                                                    \
169           {                                       169           {                                                     \
170             /* underflow to zero */               170             /* underflow to zero */                             \
171             X##_e = 0;                            171             X##_e = 0;                                          \
172             if (!_FP_FRAC_ZEROP_##wc(X))          172             if (!_FP_FRAC_ZEROP_##wc(X))                        \
173               {                                   173               {                                                 \
174                 _FP_FRAC_SET_##wc(X, _FP_MINFR    174                 _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);         \
175                 _FP_ROUND(wc, X);                 175                 _FP_ROUND(wc, X);                               \
176                 _FP_FRAC_LOW_##wc(X) >>= (_FP_    176                 _FP_FRAC_LOW_##wc(X) >>= (_FP_WORKBITS);        \
177               }                                   177               }                                                 \
178             FP_SET_EXCEPTION(FP_EX_UNDERFLOW);    178             FP_SET_EXCEPTION(FP_EX_UNDERFLOW);                  \
179           }                                       179           }                                                     \
180       }                                           180       }                                                         \
181     break;                                        181     break;                                                      \
182                                                   182                                                                 \
183   case FP_CLS_ZERO:                               183   case FP_CLS_ZERO:                                             \
184     X##_e = 0;                                    184     X##_e = 0;                                                  \
185     _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);      185     _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);                    \
186     break;                                        186     break;                                                      \
187                                                   187                                                                 \
188   case FP_CLS_INF:                                188   case FP_CLS_INF:                                              \
189     X##_e = _FP_EXPMAX_##fs;                      189     X##_e = _FP_EXPMAX_##fs;                                    \
190     _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);      190     _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);                    \
191     break;                                        191     break;                                                      \
192                                                   192                                                                 \
193   case FP_CLS_NAN:                                193   case FP_CLS_NAN:                                              \
194     X##_e = _FP_EXPMAX_##fs;                      194     X##_e = _FP_EXPMAX_##fs;                                    \
195     if (!_FP_KEEPNANFRACP)                        195     if (!_FP_KEEPNANFRACP)                                      \
196       {                                           196       {                                                         \
197         _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs)    197         _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);                 \
198         X##_s = _FP_NANSIGN_##fs;                 198         X##_s = _FP_NANSIGN_##fs;                               \
199       }                                           199       }                                                         \
200     else                                          200     else                                                        \
201       _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT    201       _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs;            \
202     break;                                        202     break;                                                      \
203   }                                               203   }                                                             \
204 } while (0)                                       204 } while (0)
205                                                   205 
206 /* This one accepts raw argument and not cooke    206 /* This one accepts raw argument and not cooked,  returns
207  * 1 if X is a signaling NaN.                     207  * 1 if X is a signaling NaN.
208  */                                               208  */
209 #define _FP_ISSIGNAN(fs, wc, X)                   209 #define _FP_ISSIGNAN(fs, wc, X)                                 \
210 ({                                                210 ({                                                              \
211   int __ret = 0;                                  211   int __ret = 0;                                                \
212   if (X##_e == _FP_EXPMAX_##fs)                   212   if (X##_e == _FP_EXPMAX_##fs)                                 \
213     {                                             213     {                                                           \
214       if (!_FP_FRAC_ZEROP_##wc(X)                 214       if (!_FP_FRAC_ZEROP_##wc(X)                               \
215           && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP    215           && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))   \
216         __ret = 1;                                216         __ret = 1;                                              \
217     }                                             217     }                                                           \
218   __ret;                                          218   __ret;                                                        \
219 })                                                219 })
220                                                   220 
221                                                   221 
222                                                   222 
223                                                   223 
224                                                   224 
225 /*                                                225 /*
226  * Main addition routine.  The input values sh    226  * Main addition routine.  The input values should be cooked.
227  */                                               227  */
228                                                   228 
229 #define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP)     229 #define _FP_ADD_INTERNAL(fs, wc, R, X, Y, OP)                                \
230 do {                                              230 do {                                                                         \
231   switch (_FP_CLS_COMBINE(X##_c, Y##_c))          231   switch (_FP_CLS_COMBINE(X##_c, Y##_c))                                     \
232   {                                               232   {                                                                          \
233   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NO    233   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):                         \
234     {                                             234     {                                                                        \
235       /* shift the smaller number so that its     235       /* shift the smaller number so that its exponent matches the larger */ \
236       _FP_I_TYPE diff = X##_e - Y##_e;            236       _FP_I_TYPE diff = X##_e - Y##_e;                                       \
237                                                   237                                                                              \
238       if (diff < 0)                               238       if (diff < 0)                                                          \
239         {                                         239         {                                                                    \
240           diff = -diff;                           240           diff = -diff;                                                      \
241           if (diff <= _FP_WFRACBITS_##fs)         241           if (diff <= _FP_WFRACBITS_##fs)                                    \
242             _FP_FRAC_SRS_##wc(X, diff, _FP_WFR    242             _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs);                  \
243           else if (!_FP_FRAC_ZEROP_##wc(X))       243           else if (!_FP_FRAC_ZEROP_##wc(X))                                  \
244             _FP_FRAC_SET_##wc(X, _FP_MINFRAC_#    244             _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);                          \
245           R##_e = Y##_e;                          245           R##_e = Y##_e;                                                     \
246         }                                         246         }                                                                    \
247       else                                        247       else                                                                   \
248         {                                         248         {                                                                    \
249           if (diff > 0)                           249           if (diff > 0)                                                      \
250             {                                     250             {                                                                \
251               if (diff <= _FP_WFRACBITS_##fs)     251               if (diff <= _FP_WFRACBITS_##fs)                                \
252                 _FP_FRAC_SRS_##wc(Y, diff, _FP    252                 _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs);              \
253               else if (!_FP_FRAC_ZEROP_##wc(Y)    253               else if (!_FP_FRAC_ZEROP_##wc(Y))                              \
254                 _FP_FRAC_SET_##wc(Y, _FP_MINFR    254                 _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc);                      \
255             }                                     255             }                                                                \
256           R##_e = X##_e;                          256           R##_e = X##_e;                                                     \
257         }                                         257         }                                                                    \
258                                                   258                                                                              \
259       R##_c = FP_CLS_NORMAL;                      259       R##_c = FP_CLS_NORMAL;                                                 \
260                                                   260                                                                              \
261       if (X##_s == Y##_s)                         261       if (X##_s == Y##_s)                                                    \
262         {                                         262         {                                                                    \
263           R##_s = X##_s;                          263           R##_s = X##_s;                                                     \
264           _FP_FRAC_ADD_##wc(R, X, Y);             264           _FP_FRAC_ADD_##wc(R, X, Y);                                        \
265           if (_FP_FRAC_OVERP_##wc(fs, R))         265           if (_FP_FRAC_OVERP_##wc(fs, R))                                    \
266             {                                     266             {                                                                \
267               _FP_FRAC_SRS_##wc(R, 1, _FP_WFRA    267               _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);                   \
268               R##_e++;                            268               R##_e++;                                                       \
269             }                                     269             }                                                                \
270         }                                         270         }                                                                    \
271       else                                        271       else                                                                   \
272         {                                         272         {                                                                    \
273           R##_s = X##_s;                          273           R##_s = X##_s;                                                     \
274           _FP_FRAC_SUB_##wc(R, X, Y);             274           _FP_FRAC_SUB_##wc(R, X, Y);                                        \
275           if (_FP_FRAC_ZEROP_##wc(R))             275           if (_FP_FRAC_ZEROP_##wc(R))                                        \
276             {                                     276             {                                                                \
277               /* return an exact zero */          277               /* return an exact zero */                                     \
278               if (FP_ROUNDMODE == FP_RND_MINF)    278               if (FP_ROUNDMODE == FP_RND_MINF)                               \
279                 R##_s |= Y##_s;                   279                 R##_s |= Y##_s;                                              \
280               else                                280               else                                                           \
281                 R##_s &= Y##_s;                   281                 R##_s &= Y##_s;                                              \
282               R##_c = FP_CLS_ZERO;                282               R##_c = FP_CLS_ZERO;                                           \
283             }                                     283             }                                                                \
284           else                                    284           else                                                               \
285             {                                     285             {                                                                \
286               if (_FP_FRAC_NEGP_##wc(R))          286               if (_FP_FRAC_NEGP_##wc(R))                                     \
287                 {                                 287                 {                                                            \
288                   _FP_FRAC_SUB_##wc(R, Y, X);     288                   _FP_FRAC_SUB_##wc(R, Y, X);                                \
289                   R##_s = Y##_s;                  289                   R##_s = Y##_s;                                             \
290                 }                                 290                 }                                                            \
291                                                   291                                                                              \
292               /* renormalize after subtraction    292               /* renormalize after subtraction */                            \
293               _FP_FRAC_CLZ_##wc(diff, R);         293               _FP_FRAC_CLZ_##wc(diff, R);                                    \
294               diff -= _FP_WFRACXBITS_##fs;        294               diff -= _FP_WFRACXBITS_##fs;                                   \
295               if (diff)                           295               if (diff)                                                      \
296                 {                                 296                 {                                                            \
297                   R##_e -= diff;                  297                   R##_e -= diff;                                             \
298                   _FP_FRAC_SLL_##wc(R, diff);     298                   _FP_FRAC_SLL_##wc(R, diff);                                \
299                 }                                 299                 }                                                            \
300             }                                     300             }                                                                \
301         }                                         301         }                                                                    \
302       break;                                      302       break;                                                                 \
303     }                                             303     }                                                                        \
304                                                   304                                                                              \
305   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):    305   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):                               \
306     _FP_CHOOSENAN(fs, wc, R, X, Y, OP);           306     _FP_CHOOSENAN(fs, wc, R, X, Y, OP);                                      \
307     break;                                        307     break;                                                                   \
308                                                   308                                                                              \
309   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZE    309   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):                           \
310     R##_e = X##_e;                                310     R##_e = X##_e;                                                           \
311         fallthrough;                           << 
312   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMA    311   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):                            \
313   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):    312   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):                               \
314   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO)    313   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):                              \
315     _FP_FRAC_COPY_##wc(R, X);                     314     _FP_FRAC_COPY_##wc(R, X);                                                \
316     R##_s = X##_s;                                315     R##_s = X##_s;                                                           \
317     R##_c = X##_c;                                316     R##_c = X##_c;                                                           \
318     break;                                        317     break;                                                                   \
319                                                   318                                                                              \
320   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORM    319   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):                           \
321     R##_e = Y##_e;                                320     R##_e = Y##_e;                                                           \
322         fallthrough;                           << 
323   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NA    321   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):                            \
324   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):    322   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):                               \
325   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN)    323   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):                              \
326     _FP_FRAC_COPY_##wc(R, Y);                     324     _FP_FRAC_COPY_##wc(R, Y);                                                \
327     R##_s = Y##_s;                                325     R##_s = Y##_s;                                                           \
328     R##_c = Y##_c;                                326     R##_c = Y##_c;                                                           \
329     break;                                        327     break;                                                                   \
330                                                   328                                                                              \
331   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):    329   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):                               \
332     if (X##_s != Y##_s)                           330     if (X##_s != Y##_s)                                                      \
333       {                                           331       {                                                                      \
334         /* +INF + -INF => NAN */                  332         /* +INF + -INF => NAN */                                             \
335         _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs)    333         _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);                              \
336         R##_s = _FP_NANSIGN_##fs;                 334         R##_s = _FP_NANSIGN_##fs;                                            \
337         R##_c = FP_CLS_NAN;                       335         R##_c = FP_CLS_NAN;                                                  \
338         FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX    336         FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_ISI);                 \
339         break;                                    337         break;                                                               \
340       }                                           338       }                                                                      \
341     fallthrough;                               !! 339     /* FALLTHRU */                                                           \
342                                                   340                                                                              \
343   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMA    341   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):                            \
344   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO)    342   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):                              \
345     R##_s = X##_s;                                343     R##_s = X##_s;                                                           \
346     R##_c = FP_CLS_INF;                           344     R##_c = FP_CLS_INF;                                                      \
347     break;                                        345     break;                                                                   \
348                                                   346                                                                              \
349   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_IN    347   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):                            \
350   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF)    348   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):                              \
351     R##_s = Y##_s;                                349     R##_s = Y##_s;                                                           \
352     R##_c = FP_CLS_INF;                           350     R##_c = FP_CLS_INF;                                                      \
353     break;                                        351     break;                                                                   \
354                                                   352                                                                              \
355   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO    353   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):                             \
356     /* make sure the sign is correct */           354     /* make sure the sign is correct */                                      \
357     if (FP_ROUNDMODE == FP_RND_MINF)              355     if (FP_ROUNDMODE == FP_RND_MINF)                                         \
358       R##_s = X##_s | Y##_s;                      356       R##_s = X##_s | Y##_s;                                                 \
359     else                                          357     else                                                                     \
360       R##_s = X##_s & Y##_s;                      358       R##_s = X##_s & Y##_s;                                                 \
361     R##_c = FP_CLS_ZERO;                          359     R##_c = FP_CLS_ZERO;                                                     \
362     break;                                        360     break;                                                                   \
363                                                   361                                                                              \
364   default:                                        362   default:                                                                   \
365     abort();                                      363     abort();                                                                 \
366   }                                               364   }                                                                          \
367 } while (0)                                       365 } while (0)
368                                                   366 
369 #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTER    367 #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTERNAL(fs, wc, R, X, Y, '+')
370 #define _FP_SUB(fs, wc, R, X, Y)                  368 #define _FP_SUB(fs, wc, R, X, Y)                                             \
371   do {                                            369   do {                                                                       \
372     if (Y##_c != FP_CLS_NAN) Y##_s ^= 1;          370     if (Y##_c != FP_CLS_NAN) Y##_s ^= 1;                                     \
373     _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-');       371     _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-');                                  \
374   } while (0)                                     372   } while (0)
375                                                   373 
376                                                   374 
377 /*                                                375 /*
378  * Main negation routine.  FIXME -- when we ca    376  * Main negation routine.  FIXME -- when we care about setting exception
379  * bits reliably, this will not do.  We should    377  * bits reliably, this will not do.  We should examine all of the fp classes.
380  */                                               378  */
381                                                   379 
382 #define _FP_NEG(fs, wc, R, X)           \         380 #define _FP_NEG(fs, wc, R, X)           \
383   do {                                  \         381   do {                                  \
384     _FP_FRAC_COPY_##wc(R, X);           \         382     _FP_FRAC_COPY_##wc(R, X);           \
385     R##_c = X##_c;                      \         383     R##_c = X##_c;                      \
386     R##_e = X##_e;                      \         384     R##_e = X##_e;                      \
387     R##_s = 1 ^ X##_s;                  \         385     R##_s = 1 ^ X##_s;                  \
388   } while (0)                                     386   } while (0)
389                                                   387 
390                                                   388 
391 /*                                                389 /*
392  * Main multiplication routine.  The input val    390  * Main multiplication routine.  The input values should be cooked.
393  */                                               391  */
394                                                   392 
395 #define _FP_MUL(fs, wc, R, X, Y)                  393 #define _FP_MUL(fs, wc, R, X, Y)                        \
396 do {                                              394 do {                                                    \
397   R##_s = X##_s ^ Y##_s;                          395   R##_s = X##_s ^ Y##_s;                                \
398   switch (_FP_CLS_COMBINE(X##_c, Y##_c))          396   switch (_FP_CLS_COMBINE(X##_c, Y##_c))                \
399   {                                               397   {                                                     \
400   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NO    398   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):    \
401     R##_c = FP_CLS_NORMAL;                        399     R##_c = FP_CLS_NORMAL;                              \
402     R##_e = X##_e + Y##_e + 1;                    400     R##_e = X##_e + Y##_e + 1;                          \
403                                                   401                                                         \
404     _FP_MUL_MEAT_##fs(R,X,Y);                     402     _FP_MUL_MEAT_##fs(R,X,Y);                           \
405                                                   403                                                         \
406     if (_FP_FRAC_OVERP_##wc(fs, R))               404     if (_FP_FRAC_OVERP_##wc(fs, R))                     \
407       _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##    405       _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);      \
408     else                                          406     else                                                \
409       R##_e--;                                    407       R##_e--;                                          \
410     break;                                        408     break;                                              \
411                                                   409                                                         \
412   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):    410   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):          \
413     _FP_CHOOSENAN(fs, wc, R, X, Y, '*');          411     _FP_CHOOSENAN(fs, wc, R, X, Y, '*');                \
414     break;                                        412     break;                                              \
415                                                   413                                                         \
416   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMA    414   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):       \
417   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):    415   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):          \
418   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO)    416   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):         \
419     R##_s = X##_s;                                417     R##_s = X##_s;                                      \
420           fallthrough;                         << 
421                                                   418                                                         \
422   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):    419   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):          \
423   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMA    420   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):       \
424   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORM    421   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):      \
425   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO    422   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):        \
426     _FP_FRAC_COPY_##wc(R, X);                     423     _FP_FRAC_COPY_##wc(R, X);                           \
427     R##_c = X##_c;                                424     R##_c = X##_c;                                      \
428     break;                                        425     break;                                              \
429                                                   426                                                         \
430   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NA    427   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):       \
431   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):    428   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):          \
432   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN)    429   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):         \
433     R##_s = Y##_s;                                430     R##_s = Y##_s;                                      \
434           fallthrough;                         << 
435                                                   431                                                         \
436   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_IN    432   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):       \
437   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZE    433   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):      \
438     _FP_FRAC_COPY_##wc(R, Y);                     434     _FP_FRAC_COPY_##wc(R, Y);                           \
439     R##_c = Y##_c;                                435     R##_c = Y##_c;                                      \
440     break;                                        436     break;                                              \
441                                                   437                                                         \
442   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO)    438   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):         \
443   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF)    439   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):         \
444     R##_s = _FP_NANSIGN_##fs;                     440     R##_s = _FP_NANSIGN_##fs;                           \
445     R##_c = FP_CLS_NAN;                           441     R##_c = FP_CLS_NAN;                                 \
446     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);       442     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);             \
447     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INV    443     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_IMZ);\
448     break;                                        444     break;                                              \
449                                                   445                                                         \
450   default:                                        446   default:                                              \
451     abort();                                      447     abort();                                            \
452   }                                               448   }                                                     \
453 } while (0)                                       449 } while (0)
454                                                   450 
455                                                   451 
456 /*                                                452 /*
457  * Main division routine.  The input values sh    453  * Main division routine.  The input values should be cooked.
458  */                                               454  */
459                                                   455 
460 #define _FP_DIV(fs, wc, R, X, Y)                  456 #define _FP_DIV(fs, wc, R, X, Y)                        \
461 do {                                              457 do {                                                    \
462   R##_s = X##_s ^ Y##_s;                          458   R##_s = X##_s ^ Y##_s;                                \
463   switch (_FP_CLS_COMBINE(X##_c, Y##_c))          459   switch (_FP_CLS_COMBINE(X##_c, Y##_c))                \
464   {                                               460   {                                                     \
465   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NO    461   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):    \
466     R##_c = FP_CLS_NORMAL;                        462     R##_c = FP_CLS_NORMAL;                              \
467     R##_e = X##_e - Y##_e;                        463     R##_e = X##_e - Y##_e;                              \
468                                                   464                                                         \
469     _FP_DIV_MEAT_##fs(R,X,Y);                     465     _FP_DIV_MEAT_##fs(R,X,Y);                           \
470     break;                                        466     break;                                              \
471                                                   467                                                         \
472   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):    468   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):          \
473     _FP_CHOOSENAN(fs, wc, R, X, Y, '/');          469     _FP_CHOOSENAN(fs, wc, R, X, Y, '/');                \
474     break;                                        470     break;                                              \
475                                                   471                                                         \
476   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMA    472   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):       \
477   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):    473   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):          \
478   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO)    474   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):         \
479     R##_s = X##_s;                                475     R##_s = X##_s;                                      \
480     _FP_FRAC_COPY_##wc(R, X);                     476     _FP_FRAC_COPY_##wc(R, X);                           \
481     R##_c = X##_c;                                477     R##_c = X##_c;                                      \
482     break;                                        478     break;                                              \
483                                                   479                                                         \
484   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NA    480   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):       \
485   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):    481   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):          \
486   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN)    482   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):         \
487     R##_s = Y##_s;                                483     R##_s = Y##_s;                                      \
488     _FP_FRAC_COPY_##wc(R, Y);                     484     _FP_FRAC_COPY_##wc(R, Y);                           \
489     R##_c = Y##_c;                                485     R##_c = Y##_c;                                      \
490     break;                                        486     break;                                              \
491                                                   487                                                         \
492   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_IN    488   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):       \
493   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF)    489   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):         \
494   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORM    490   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):      \
495     R##_c = FP_CLS_ZERO;                          491     R##_c = FP_CLS_ZERO;                                \
496     break;                                        492     break;                                              \
497                                                   493                                                         \
498   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZE    494   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):      \
499     FP_SET_EXCEPTION(FP_EX_DIVZERO);              495     FP_SET_EXCEPTION(FP_EX_DIVZERO);                    \
500         fallthrough;                           << 
501   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO)    496   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):         \
502   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMA    497   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):       \
503     R##_c = FP_CLS_INF;                           498     R##_c = FP_CLS_INF;                                 \
504     break;                                        499     break;                                              \
505                                                   500                                                         \
506   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):    501   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):          \
507     R##_s = _FP_NANSIGN_##fs;                     502     R##_s = _FP_NANSIGN_##fs;                           \
508     R##_c = FP_CLS_NAN;                           503     R##_c = FP_CLS_NAN;                                 \
509     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);       504     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);             \
510     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INV    505     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_IDI);\
511     break;                                        506     break;                                              \
512                                                   507                                                         \
513   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO    508   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):        \
514     R##_s = _FP_NANSIGN_##fs;                     509     R##_s = _FP_NANSIGN_##fs;                           \
515     R##_c = FP_CLS_NAN;                           510     R##_c = FP_CLS_NAN;                                 \
516     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);       511     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);             \
517     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INV    512     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_ZDZ);\
518     break;                                        513     break;                                              \
519                                                   514                                                         \
520   default:                                        515   default:                                              \
521     abort();                                      516     abort();                                            \
522   }                                               517   }                                                     \
523 } while (0)                                       518 } while (0)
524                                                   519 
525                                                   520 
526 /*                                                521 /*
527  * Main differential comparison routine.  The     522  * Main differential comparison routine.  The inputs should be raw not
528  * cooked.  The return is -1,0,1 for normal va    523  * cooked.  The return is -1,0,1 for normal values, 2 otherwise.
529  */                                               524  */
530                                                   525 
531 #define _FP_CMP(fs, wc, ret, X, Y, un)            526 #define _FP_CMP(fs, wc, ret, X, Y, un)                                  \
532   do {                                            527   do {                                                                  \
533     /* NANs are unordered */                      528     /* NANs are unordered */                                            \
534     if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC    529     if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))           \
535         || (Y##_e == _FP_EXPMAX_##fs && !_FP_F    530         || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))       \
536       {                                           531       {                                                                 \
537         ret = un;                                 532         ret = un;                                                       \
538       }                                           533       }                                                                 \
539     else                                          534     else                                                                \
540       {                                           535       {                                                                 \
541         int __is_zero_x;                          536         int __is_zero_x;                                                \
542         int __is_zero_y;                          537         int __is_zero_y;                                                \
543                                                   538                                                                         \
544         __is_zero_x = (!X##_e && _FP_FRAC_ZERO    539         __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0;       \
545         __is_zero_y = (!Y##_e && _FP_FRAC_ZERO    540         __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0;       \
546                                                   541                                                                         \
547         if (__is_zero_x && __is_zero_y)           542         if (__is_zero_x && __is_zero_y)                                 \
548                 ret = 0;                          543                 ret = 0;                                                \
549         else if (__is_zero_x)                     544         else if (__is_zero_x)                                           \
550                 ret = Y##_s ? 1 : -1;             545                 ret = Y##_s ? 1 : -1;                                   \
551         else if (__is_zero_y)                     546         else if (__is_zero_y)                                           \
552                 ret = X##_s ? -1 : 1;             547                 ret = X##_s ? -1 : 1;                                   \
553         else if (X##_s != Y##_s)                  548         else if (X##_s != Y##_s)                                        \
554           ret = X##_s ? -1 : 1;                   549           ret = X##_s ? -1 : 1;                                         \
555         else if (X##_e > Y##_e)                   550         else if (X##_e > Y##_e)                                         \
556           ret = X##_s ? -1 : 1;                   551           ret = X##_s ? -1 : 1;                                         \
557         else if (X##_e < Y##_e)                   552         else if (X##_e < Y##_e)                                         \
558           ret = X##_s ? 1 : -1;                   553           ret = X##_s ? 1 : -1;                                         \
559         else if (_FP_FRAC_GT_##wc(X, Y))          554         else if (_FP_FRAC_GT_##wc(X, Y))                                \
560           ret = X##_s ? -1 : 1;                   555           ret = X##_s ? -1 : 1;                                         \
561         else if (_FP_FRAC_GT_##wc(Y, X))          556         else if (_FP_FRAC_GT_##wc(Y, X))                                \
562           ret = X##_s ? 1 : -1;                   557           ret = X##_s ? 1 : -1;                                         \
563         else                                      558         else                                                            \
564           ret = 0;                                559           ret = 0;                                                      \
565       }                                           560       }                                                                 \
566   } while (0)                                     561   } while (0)
567                                                   562 
568                                                   563 
569 /* Simplification for strict equality.  */        564 /* Simplification for strict equality.  */
570                                                   565 
571 #define _FP_CMP_EQ(fs, wc, ret, X, Y)             566 #define _FP_CMP_EQ(fs, wc, ret, X, Y)                                     \
572   do {                                            567   do {                                                                    \
573     /* NANs are unordered */                      568     /* NANs are unordered */                                              \
574     if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC    569     if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))             \
575         || (Y##_e == _FP_EXPMAX_##fs && !_FP_F    570         || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))         \
576       {                                           571       {                                                                   \
577         ret = 1;                                  572         ret = 1;                                                          \
578       }                                           573       }                                                                   \
579     else                                          574     else                                                                  \
580       {                                           575       {                                                                   \
581         ret = !(X##_e == Y##_e                    576         ret = !(X##_e == Y##_e                                            \
582                 && _FP_FRAC_EQ_##wc(X, Y)         577                 && _FP_FRAC_EQ_##wc(X, Y)                                 \
583                 && (X##_s == Y##_s || !X##_e &    578                 && (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
584       }                                           579       }                                                                   \
585   } while (0)                                     580   } while (0)
586                                                   581 
587 /*                                                582 /*
588  * Main square root routine.  The input value     583  * Main square root routine.  The input value should be cooked.
589  */                                               584  */
590                                                   585 
591 #define _FP_SQRT(fs, wc, R, X)                    586 #define _FP_SQRT(fs, wc, R, X)                                          \
592 do {                                              587 do {                                                                    \
593     _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(    588     _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S);                       \
594     _FP_W_TYPE q;                                 589     _FP_W_TYPE q;                                                       \
595     switch (X##_c)                                590     switch (X##_c)                                                      \
596     {                                             591     {                                                                   \
597     case FP_CLS_NAN:                              592     case FP_CLS_NAN:                                                    \
598         _FP_FRAC_COPY_##wc(R, X);                 593         _FP_FRAC_COPY_##wc(R, X);                                       \
599         R##_s = X##_s;                            594         R##_s = X##_s;                                                  \
600         R##_c = FP_CLS_NAN;                       595         R##_c = FP_CLS_NAN;                                             \
601         break;                                    596         break;                                                          \
602     case FP_CLS_INF:                              597     case FP_CLS_INF:                                                    \
603         if (X##_s)                                598         if (X##_s)                                                      \
604           {                                       599           {                                                             \
605             R##_s = _FP_NANSIGN_##fs;             600             R##_s = _FP_NANSIGN_##fs;                                   \
606             R##_c = FP_CLS_NAN; /* NAN */         601             R##_c = FP_CLS_NAN; /* NAN */                               \
607             _FP_FRAC_SET_##wc(R, _FP_NANFRAC_#    602             _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);                     \
608             FP_SET_EXCEPTION(FP_EX_INVALID);      603             FP_SET_EXCEPTION(FP_EX_INVALID);                            \
609           }                                       604           }                                                             \
610         else                                      605         else                                                            \
611           {                                       606           {                                                             \
612             R##_s = 0;                            607             R##_s = 0;                                                  \
613             R##_c = FP_CLS_INF; /* sqrt(+inf)     608             R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */                 \
614           }                                       609           }                                                             \
615         break;                                    610         break;                                                          \
616     case FP_CLS_ZERO:                             611     case FP_CLS_ZERO:                                                   \
617         R##_s = X##_s;                            612         R##_s = X##_s;                                                  \
618         R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-    613         R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */                      \
619         break;                                    614         break;                                                          \
620     case FP_CLS_NORMAL:                           615     case FP_CLS_NORMAL:                                                 \
621         R##_s = 0;                                616         R##_s = 0;                                                      \
622         if (X##_s)                                617         if (X##_s)                                                      \
623           {                                       618           {                                                             \
624             R##_c = FP_CLS_NAN; /* sNAN */        619             R##_c = FP_CLS_NAN; /* sNAN */                              \
625             R##_s = _FP_NANSIGN_##fs;             620             R##_s = _FP_NANSIGN_##fs;                                   \
626             _FP_FRAC_SET_##wc(R, _FP_NANFRAC_#    621             _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);                     \
627             FP_SET_EXCEPTION(FP_EX_INVALID);      622             FP_SET_EXCEPTION(FP_EX_INVALID);                            \
628             break;                                623             break;                                                      \
629           }                                       624           }                                                             \
630         R##_c = FP_CLS_NORMAL;                    625         R##_c = FP_CLS_NORMAL;                                          \
631         if (X##_e & 1)                            626         if (X##_e & 1)                                                  \
632           _FP_FRAC_SLL_##wc(X, 1);                627           _FP_FRAC_SLL_##wc(X, 1);                                      \
633         R##_e = X##_e >> 1;                       628         R##_e = X##_e >> 1;                                             \
634         _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc    629         _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc);                        \
635         _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc    630         _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc);                        \
636         q = _FP_OVERFLOW_##fs >> 1;               631         q = _FP_OVERFLOW_##fs >> 1;                                     \
637         _FP_SQRT_MEAT_##wc(R, S, T, X, q);        632         _FP_SQRT_MEAT_##wc(R, S, T, X, q);                              \
638     }                                             633     }                                                                   \
639   } while (0)                                     634   } while (0)
640                                                   635 
641 /*                                                636 /*
642  * Convert from FP to integer                     637  * Convert from FP to integer
643  */                                               638  */
644                                                   639 
645 /* RSIGNED can have following values:             640 /* RSIGNED can have following values:
646  * 0:  the number is required to be 0..(2^rsiz    641  * 0:  the number is required to be 0..(2^rsize)-1, if not, NV is set plus
647  *     the result is either 0 or (2^rsize)-1 d    642  *     the result is either 0 or (2^rsize)-1 depending on the sign in such case.
648  * 1:  the number is required to be -(2^(rsize    643  * 1:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
649  *     set plus the result is either -(2^(rsiz    644  *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
650  *     on the sign in such case.                  645  *     on the sign in such case.
651  * 2:  the number is required to be -(2^(rsize    646  * 2:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
652  *     set plus the result is truncated to fit    647  *     set plus the result is truncated to fit into destination.
653  * -1: the number is required to be -(2^(rsize    648  * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
654  *     set plus the result is either -(2^(rsiz    649  *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
655  *     on the sign in such case.                  650  *     on the sign in such case.
656  */                                               651  */
657 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigne    652 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)                                \
658   do {                                            653   do {                                                                          \
659     switch (X##_c)                                654     switch (X##_c)                                                              \
660       {                                           655       {                                                                         \
661       case FP_CLS_NORMAL:                         656       case FP_CLS_NORMAL:                                                       \
662         if (X##_e < 0)                            657         if (X##_e < 0)                                                          \
663           {                                       658           {                                                                     \
664             FP_SET_EXCEPTION(FP_EX_INEXACT);      659             FP_SET_EXCEPTION(FP_EX_INEXACT);                                    \
665             fallthrough;                       << 
666           case FP_CLS_ZERO:                       660           case FP_CLS_ZERO:                                                     \
667             r = 0;                                661             r = 0;                                                              \
668           }                                       662           }                                                                     \
669         else if (X##_e >= rsize - (rsigned > 0    663         else if (X##_e >= rsize - (rsigned > 0 || X##_s)                        \
670                  || (!rsigned && X##_s))          664                  || (!rsigned && X##_s))                                        \
671           {     /* overflow */                    665           {     /* overflow */                                                  \
672             fallthrough;                       << 
673           case FP_CLS_NAN:                        666           case FP_CLS_NAN:                                                      \
674           case FP_CLS_INF:                        667           case FP_CLS_INF:                                                      \
675             if (rsigned == 2)                     668             if (rsigned == 2)                                                   \
676               {                                   669               {                                                                 \
677                 if (X##_c != FP_CLS_NORMAL        670                 if (X##_c != FP_CLS_NORMAL                                      \
678                     || X##_e >= rsize - 1 + _F    671                     || X##_e >= rsize - 1 + _FP_WFRACBITS_##fs)                 \
679                   r = 0;                          672                   r = 0;                                                        \
680                 else                              673                 else                                                            \
681                   {                               674                   {                                                             \
682                     _FP_FRAC_SLL_##wc(X, (X##_    675                     _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));     \
683                     _FP_FRAC_ASSEMBLE_##wc(r,     676                     _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                        \
684                   }                               677                   }                                                             \
685               }                                   678               }                                                                 \
686             else if (rsigned)                     679             else if (rsigned)                                                   \
687               {                                   680               {                                                                 \
688                 r = 1;                            681                 r = 1;                                                          \
689                 r <<= rsize - 1;                  682                 r <<= rsize - 1;                                                \
690                 r -= 1 - X##_s;                   683                 r -= 1 - X##_s;                                                 \
691               }                                   684               }                                                                 \
692             else                                  685             else                                                                \
693               {                                   686               {                                                                 \
694                 r = 0;                            687                 r = 0;                                                          \
695                 if (!X##_s)                       688                 if (!X##_s)                                                     \
696                   r = ~r;                         689                   r = ~r;                                                       \
697               }                                   690               }                                                                 \
698             FP_SET_EXCEPTION(FP_EX_INVALID);      691             FP_SET_EXCEPTION(FP_EX_INVALID);                                    \
699           }                                       692           }                                                                     \
700         else                                      693         else                                                                    \
701           {                                       694           {                                                                     \
702             if (_FP_W_TYPE_SIZE*wc < rsize)       695             if (_FP_W_TYPE_SIZE*wc < rsize)                                     \
703               {                                   696               {                                                                 \
704                 _FP_FRAC_ASSEMBLE_##wc(r, X, r    697                 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                            \
705                 r <<= X##_e - _FP_WFRACBITS_##    698                 r <<= X##_e - _FP_WFRACBITS_##fs;                               \
706               }                                   699               }                                                                 \
707             else                                  700             else                                                                \
708               {                                   701               {                                                                 \
709                 if (X##_e >= _FP_WFRACBITS_##f    702                 if (X##_e >= _FP_WFRACBITS_##fs)                                \
710                   _FP_FRAC_SLL_##wc(X, (X##_e     703                   _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));       \
711                 else if (X##_e < _FP_WFRACBITS    704                 else if (X##_e < _FP_WFRACBITS_##fs - 1)                        \
712                   {                               705                   {                                                             \
713                     _FP_FRAC_SRS_##wc(X, (_FP_    706                     _FP_FRAC_SRS_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 2),      \
714                                       _FP_WFRA    707                                       _FP_WFRACBITS_##fs);                      \
715                     if (_FP_FRAC_LOW_##wc(X) &    708                     if (_FP_FRAC_LOW_##wc(X) & 1)                               \
716                       FP_SET_EXCEPTION(FP_EX_I    709                       FP_SET_EXCEPTION(FP_EX_INEXACT);                          \
717                     _FP_FRAC_SRL_##wc(X, 1);      710                     _FP_FRAC_SRL_##wc(X, 1);                                    \
718                   }                               711                   }                                                             \
719                 _FP_FRAC_ASSEMBLE_##wc(r, X, r    712                 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                            \
720               }                                   713               }                                                                 \
721             if (rsigned && X##_s)                 714             if (rsigned && X##_s)                                               \
722               r = -r;                             715               r = -r;                                                           \
723           }                                       716           }                                                                     \
724         break;                                    717         break;                                                                  \
725       }                                           718       }                                                                         \
726   } while (0)                                     719   } while (0)
727                                                   720 
728 #define _FP_TO_INT_ROUND(fs, wc, r, X, rsize,     721 #define _FP_TO_INT_ROUND(fs, wc, r, X, rsize, rsigned)                          \
729   do {                                            722   do {                                                                          \
730     r = 0;                                        723     r = 0;                                                                      \
731     switch (X##_c)                                724     switch (X##_c)                                                              \
732       {                                           725       {                                                                         \
733       case FP_CLS_NORMAL:                         726       case FP_CLS_NORMAL:                                                       \
734         if (X##_e >= _FP_FRACBITS_##fs - 1)       727         if (X##_e >= _FP_FRACBITS_##fs - 1)                                     \
735           {                                       728           {                                                                     \
736             if (X##_e < rsize - 1 + _FP_WFRACB    729             if (X##_e < rsize - 1 + _FP_WFRACBITS_##fs)                         \
737               {                                   730               {                                                                 \
738                 if (X##_e >= _FP_WFRACBITS_##f    731                 if (X##_e >= _FP_WFRACBITS_##fs - 1)                            \
739                   {                               732                   {                                                             \
740                     _FP_FRAC_ASSEMBLE_##wc(r,     733                     _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                        \
741                     r <<= X##_e - _FP_WFRACBIT    734                     r <<= X##_e - _FP_WFRACBITS_##fs + 1;                       \
742                   }                               735                   }                                                             \
743                 else                              736                 else                                                            \
744                   {                               737                   {                                                             \
745                     _FP_FRAC_SRL_##wc(X, _FP_W    738                     _FP_FRAC_SRL_##wc(X, _FP_WORKBITS - X##_e                   \
746                                       + _FP_FR    739                                       + _FP_FRACBITS_##fs - 1);                 \
747                     _FP_FRAC_ASSEMBLE_##wc(r,     740                     _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                        \
748                   }                               741                   }                                                             \
749               }                                   742               }                                                                 \
750           }                                       743           }                                                                     \
751         else                                      744         else                                                                    \
752           {                                       745           {                                                                     \
753             int _lz0, _lz1;                       746             int _lz0, _lz1;                                                     \
754             if (X##_e <= -_FP_WORKBITS - 1)       747             if (X##_e <= -_FP_WORKBITS - 1)                                     \
755               _FP_FRAC_SET_##wc(X, _FP_MINFRAC    748               _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);                           \
756             else                                  749             else                                                                \
757               _FP_FRAC_SRS_##wc(X, _FP_FRACBIT    750               _FP_FRAC_SRS_##wc(X, _FP_FRACBITS_##fs - 1 - X##_e,               \
758                                 _FP_WFRACBITS_    751                                 _FP_WFRACBITS_##fs);                            \
759             _FP_FRAC_CLZ_##wc(_lz0, X);           752             _FP_FRAC_CLZ_##wc(_lz0, X);                                         \
760             _FP_ROUND(wc, X);                     753             _FP_ROUND(wc, X);                                                   \
761             _FP_FRAC_CLZ_##wc(_lz1, X);           754             _FP_FRAC_CLZ_##wc(_lz1, X);                                         \
762             if (_lz1 < _lz0)                      755             if (_lz1 < _lz0)                                                    \
763               X##_e++; /* For overflow detecti    756               X##_e++; /* For overflow detection.  */                           \
764             _FP_FRAC_SRL_##wc(X, _FP_WORKBITS)    757             _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);                                 \
765             _FP_FRAC_ASSEMBLE_##wc(r, X, rsize    758             _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                                \
766           }                                       759           }                                                                     \
767         if (rsigned && X##_s)                     760         if (rsigned && X##_s)                                                   \
768           r = -r;                                 761           r = -r;                                                               \
769         if (X##_e >= rsize - (rsigned > 0 || X    762         if (X##_e >= rsize - (rsigned > 0 || X##_s)                             \
770             || (!rsigned && X##_s))               763             || (!rsigned && X##_s))                                             \
771           {     /* overflow */                    764           {     /* overflow */                                                  \
772             fallthrough;                       << 
773           case FP_CLS_NAN:                        765           case FP_CLS_NAN:                                                      \
774           case FP_CLS_INF:                        766           case FP_CLS_INF:                                                      \
775             if (!rsigned)                         767             if (!rsigned)                                                       \
776               {                                   768               {                                                                 \
777                 r = 0;                            769                 r = 0;                                                          \
778                 if (!X##_s)                       770                 if (!X##_s)                                                     \
779                   r = ~r;                         771                   r = ~r;                                                       \
780               }                                   772               }                                                                 \
781             else if (rsigned != 2)                773             else if (rsigned != 2)                                              \
782               {                                   774               {                                                                 \
783                 r = 1;                            775                 r = 1;                                                          \
784                 r <<= rsize - 1;                  776                 r <<= rsize - 1;                                                \
785                 r -= 1 - X##_s;                   777                 r -= 1 - X##_s;                                                 \
786               }                                   778               }                                                                 \
787             FP_SET_EXCEPTION(FP_EX_INVALID);      779             FP_SET_EXCEPTION(FP_EX_INVALID);                                    \
788           }                                       780           }                                                                     \
789         break;                                    781         break;                                                                  \
790       case FP_CLS_ZERO:                           782       case FP_CLS_ZERO:                                                         \
791         break;                                    783         break;                                                                  \
792       }                                           784       }                                                                         \
793   } while (0)                                     785   } while (0)
794                                                   786 
795 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtyp    787 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)                        \
796   do {                                            788   do {                                                                  \
797     if (r)                                        789     if (r)                                                              \
798       {                                           790       {                                                                 \
799         unsigned rtype ur_;                       791         unsigned rtype ur_;                                             \
800         X##_c = FP_CLS_NORMAL;                    792         X##_c = FP_CLS_NORMAL;                                          \
801                                                   793                                                                         \
802         if ((X##_s = (r < 0)))                    794         if ((X##_s = (r < 0)))                                          \
803           ur_ = (unsigned rtype) -r;              795           ur_ = (unsigned rtype) -r;                                    \
804         else                                      796         else                                                            \
805           ur_ = (unsigned rtype) r;               797           ur_ = (unsigned rtype) r;                                     \
806         (void) (((rsize) <= _FP_W_TYPE_SIZE)      798         (void) (((rsize) <= _FP_W_TYPE_SIZE)                            \
807                 ? ({ __FP_CLZ(X##_e, ur_); })     799                 ? ({ __FP_CLZ(X##_e, ur_); })                           \
808                 : ({                              800                 : ({                                                    \
809                      __FP_CLZ_2(X##_e, (_FP_W_    801                      __FP_CLZ_2(X##_e, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE),  \
810                                                   802                                                             (_FP_W_TYPE)ur_); \
811                   }));                            803                   }));                                                  \
812         if (rsize < _FP_W_TYPE_SIZE)              804         if (rsize < _FP_W_TYPE_SIZE)                                    \
813                 X##_e -= (_FP_W_TYPE_SIZE - rs    805                 X##_e -= (_FP_W_TYPE_SIZE - rsize);                     \
814         X##_e = rsize - X##_e - 1;                806         X##_e = rsize - X##_e - 1;                                      \
815                                                   807                                                                         \
816         if (_FP_FRACBITS_##fs < rsize && _FP_W    808         if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs <= X##_e)   \
817           __FP_FRAC_SRS_1(ur_, (X##_e - _FP_WF    809           __FP_FRAC_SRS_1(ur_, (X##_e - _FP_WFRACBITS_##fs + 1), rsize);\
818         _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsiz    810         _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize);                       \
819         if ((_FP_WFRACBITS_##fs - X##_e - 1) >    811         if ((_FP_WFRACBITS_##fs - X##_e - 1) > 0)                       \
820           _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_    812           _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));       \
821       }                                           813       }                                                                 \
822     else                                          814     else                                                                \
823       {                                           815       {                                                                 \
824         X##_c = FP_CLS_ZERO, X##_s = 0;           816         X##_c = FP_CLS_ZERO, X##_s = 0;                                 \
825       }                                           817       }                                                                 \
826   } while (0)                                     818   } while (0)
827                                                   819 
828                                                   820 
829 #define FP_CONV(dfs,sfs,dwc,swc,D,S)              821 #define FP_CONV(dfs,sfs,dwc,swc,D,S)                    \
830   do {                                            822   do {                                                  \
831     _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S    823     _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S);        \
832     D##_e = S##_e;                                824     D##_e = S##_e;                                      \
833     D##_c = S##_c;                                825     D##_c = S##_c;                                      \
834     D##_s = S##_s;                                826     D##_s = S##_s;                                      \
835   } while (0)                                     827   } while (0)
836                                                   828 
837 /*                                                829 /*
838  * Helper primitives.                             830  * Helper primitives.
839  */                                               831  */
840                                                   832 
841 /* Count leading zeros in a word.  */             833 /* Count leading zeros in a word.  */
842                                                   834 
843 #ifndef __FP_CLZ                                  835 #ifndef __FP_CLZ
844 #if _FP_W_TYPE_SIZE < 64                          836 #if _FP_W_TYPE_SIZE < 64
845 /* this is just to shut the compiler up about     837 /* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
846 #define __FP_CLZ(r, x)                            838 #define __FP_CLZ(r, x)                          \
847   do {                                            839   do {                                          \
848     _FP_W_TYPE _t = (x);                          840     _FP_W_TYPE _t = (x);                        \
849     r = _FP_W_TYPE_SIZE - 1;                      841     r = _FP_W_TYPE_SIZE - 1;                    \
850     if (_t > 0xffff) r -= 16;                     842     if (_t > 0xffff) r -= 16;                   \
851     if (_t > 0xffff) _t >>= 16;                   843     if (_t > 0xffff) _t >>= 16;                 \
852     if (_t > 0xff) r -= 8;                        844     if (_t > 0xff) r -= 8;                      \
853     if (_t > 0xff) _t >>= 8;                      845     if (_t > 0xff) _t >>= 8;                    \
854     if (_t & 0xf0) r -= 4;                        846     if (_t & 0xf0) r -= 4;                      \
855     if (_t & 0xf0) _t >>= 4;                      847     if (_t & 0xf0) _t >>= 4;                    \
856     if (_t & 0xc) r -= 2;                         848     if (_t & 0xc) r -= 2;                       \
857     if (_t & 0xc) _t >>= 2;                       849     if (_t & 0xc) _t >>= 2;                     \
858     if (_t & 0x2) r -= 1;                         850     if (_t & 0x2) r -= 1;                       \
859   } while (0)                                     851   } while (0)
860 #else /* not _FP_W_TYPE_SIZE < 64 */              852 #else /* not _FP_W_TYPE_SIZE < 64 */
861 #define __FP_CLZ(r, x)                            853 #define __FP_CLZ(r, x)                          \
862   do {                                            854   do {                                          \
863     _FP_W_TYPE _t = (x);                          855     _FP_W_TYPE _t = (x);                        \
864     r = _FP_W_TYPE_SIZE - 1;                      856     r = _FP_W_TYPE_SIZE - 1;                    \
865     if (_t > 0xffffffff) r -= 32;                 857     if (_t > 0xffffffff) r -= 32;               \
866     if (_t > 0xffffffff) _t >>= 32;               858     if (_t > 0xffffffff) _t >>= 32;             \
867     if (_t > 0xffff) r -= 16;                     859     if (_t > 0xffff) r -= 16;                   \
868     if (_t > 0xffff) _t >>= 16;                   860     if (_t > 0xffff) _t >>= 16;                 \
869     if (_t > 0xff) r -= 8;                        861     if (_t > 0xff) r -= 8;                      \
870     if (_t > 0xff) _t >>= 8;                      862     if (_t > 0xff) _t >>= 8;                    \
871     if (_t & 0xf0) r -= 4;                        863     if (_t & 0xf0) r -= 4;                      \
872     if (_t & 0xf0) _t >>= 4;                      864     if (_t & 0xf0) _t >>= 4;                    \
873     if (_t & 0xc) r -= 2;                         865     if (_t & 0xc) r -= 2;                       \
874     if (_t & 0xc) _t >>= 2;                       866     if (_t & 0xc) _t >>= 2;                     \
875     if (_t & 0x2) r -= 1;                         867     if (_t & 0x2) r -= 1;                       \
876   } while (0)                                     868   } while (0)
877 #endif /* not _FP_W_TYPE_SIZE < 64 */             869 #endif /* not _FP_W_TYPE_SIZE < 64 */
878 #endif /* ndef __FP_CLZ */                        870 #endif /* ndef __FP_CLZ */
879                                                   871 
880 #define _FP_DIV_HELP_imm(q, r, n, d)              872 #define _FP_DIV_HELP_imm(q, r, n, d)            \
881   do {                                            873   do {                                          \
882     q = n / d, r = n % d;                         874     q = n / d, r = n % d;                       \
883   } while (0)                                     875   } while (0)
884                                                   876 
885 #endif /* __MATH_EMU_OP_COMMON_H__ */             877 #endif /* __MATH_EMU_OP_COMMON_H__ */
886                                                   878 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php