~ [ 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-6.0.19)


  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;                              311         fallthrough;                                                         \
312   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMA    312   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):                            \
313   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):    313   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):                               \
314   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO)    314   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):                              \
315     _FP_FRAC_COPY_##wc(R, X);                     315     _FP_FRAC_COPY_##wc(R, X);                                                \
316     R##_s = X##_s;                                316     R##_s = X##_s;                                                           \
317     R##_c = X##_c;                                317     R##_c = X##_c;                                                           \
318     break;                                        318     break;                                                                   \
319                                                   319                                                                              \
320   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORM    320   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):                           \
321     R##_e = Y##_e;                                321     R##_e = Y##_e;                                                           \
322         fallthrough;                              322         fallthrough;                                                         \
323   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NA    323   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):                            \
324   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):    324   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):                               \
325   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN)    325   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):                              \
326     _FP_FRAC_COPY_##wc(R, Y);                     326     _FP_FRAC_COPY_##wc(R, Y);                                                \
327     R##_s = Y##_s;                                327     R##_s = Y##_s;                                                           \
328     R##_c = Y##_c;                                328     R##_c = Y##_c;                                                           \
329     break;                                        329     break;                                                                   \
330                                                   330                                                                              \
331   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):    331   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):                               \
332     if (X##_s != Y##_s)                           332     if (X##_s != Y##_s)                                                      \
333       {                                           333       {                                                                      \
334         /* +INF + -INF => NAN */                  334         /* +INF + -INF => NAN */                                             \
335         _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs)    335         _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);                              \
336         R##_s = _FP_NANSIGN_##fs;                 336         R##_s = _FP_NANSIGN_##fs;                                            \
337         R##_c = FP_CLS_NAN;                       337         R##_c = FP_CLS_NAN;                                                  \
338         FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX    338         FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_ISI);                 \
339         break;                                    339         break;                                                               \
340       }                                           340       }                                                                      \
341     fallthrough;                                  341     fallthrough;                                                             \
342                                                   342                                                                              \
343   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMA    343   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):                            \
344   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO)    344   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):                              \
345     R##_s = X##_s;                                345     R##_s = X##_s;                                                           \
346     R##_c = FP_CLS_INF;                           346     R##_c = FP_CLS_INF;                                                      \
347     break;                                        347     break;                                                                   \
348                                                   348                                                                              \
349   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_IN    349   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):                            \
350   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF)    350   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):                              \
351     R##_s = Y##_s;                                351     R##_s = Y##_s;                                                           \
352     R##_c = FP_CLS_INF;                           352     R##_c = FP_CLS_INF;                                                      \
353     break;                                        353     break;                                                                   \
354                                                   354                                                                              \
355   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO    355   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):                             \
356     /* make sure the sign is correct */           356     /* make sure the sign is correct */                                      \
357     if (FP_ROUNDMODE == FP_RND_MINF)              357     if (FP_ROUNDMODE == FP_RND_MINF)                                         \
358       R##_s = X##_s | Y##_s;                      358       R##_s = X##_s | Y##_s;                                                 \
359     else                                          359     else                                                                     \
360       R##_s = X##_s & Y##_s;                      360       R##_s = X##_s & Y##_s;                                                 \
361     R##_c = FP_CLS_ZERO;                          361     R##_c = FP_CLS_ZERO;                                                     \
362     break;                                        362     break;                                                                   \
363                                                   363                                                                              \
364   default:                                        364   default:                                                                   \
365     abort();                                      365     abort();                                                                 \
366   }                                               366   }                                                                          \
367 } while (0)                                       367 } while (0)
368                                                   368 
369 #define _FP_ADD(fs, wc, R, X, Y) _FP_ADD_INTER    369 #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)                  370 #define _FP_SUB(fs, wc, R, X, Y)                                             \
371   do {                                            371   do {                                                                       \
372     if (Y##_c != FP_CLS_NAN) Y##_s ^= 1;          372     if (Y##_c != FP_CLS_NAN) Y##_s ^= 1;                                     \
373     _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-');       373     _FP_ADD_INTERNAL(fs, wc, R, X, Y, '-');                                  \
374   } while (0)                                     374   } while (0)
375                                                   375 
376                                                   376 
377 /*                                                377 /*
378  * Main negation routine.  FIXME -- when we ca    378  * Main negation routine.  FIXME -- when we care about setting exception
379  * bits reliably, this will not do.  We should    379  * bits reliably, this will not do.  We should examine all of the fp classes.
380  */                                               380  */
381                                                   381 
382 #define _FP_NEG(fs, wc, R, X)           \         382 #define _FP_NEG(fs, wc, R, X)           \
383   do {                                  \         383   do {                                  \
384     _FP_FRAC_COPY_##wc(R, X);           \         384     _FP_FRAC_COPY_##wc(R, X);           \
385     R##_c = X##_c;                      \         385     R##_c = X##_c;                      \
386     R##_e = X##_e;                      \         386     R##_e = X##_e;                      \
387     R##_s = 1 ^ X##_s;                  \         387     R##_s = 1 ^ X##_s;                  \
388   } while (0)                                     388   } while (0)
389                                                   389 
390                                                   390 
391 /*                                                391 /*
392  * Main multiplication routine.  The input val    392  * Main multiplication routine.  The input values should be cooked.
393  */                                               393  */
394                                                   394 
395 #define _FP_MUL(fs, wc, R, X, Y)                  395 #define _FP_MUL(fs, wc, R, X, Y)                        \
396 do {                                              396 do {                                                    \
397   R##_s = X##_s ^ Y##_s;                          397   R##_s = X##_s ^ Y##_s;                                \
398   switch (_FP_CLS_COMBINE(X##_c, Y##_c))          398   switch (_FP_CLS_COMBINE(X##_c, Y##_c))                \
399   {                                               399   {                                                     \
400   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NO    400   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):    \
401     R##_c = FP_CLS_NORMAL;                        401     R##_c = FP_CLS_NORMAL;                              \
402     R##_e = X##_e + Y##_e + 1;                    402     R##_e = X##_e + Y##_e + 1;                          \
403                                                   403                                                         \
404     _FP_MUL_MEAT_##fs(R,X,Y);                     404     _FP_MUL_MEAT_##fs(R,X,Y);                           \
405                                                   405                                                         \
406     if (_FP_FRAC_OVERP_##wc(fs, R))               406     if (_FP_FRAC_OVERP_##wc(fs, R))                     \
407       _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##    407       _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs);      \
408     else                                          408     else                                                \
409       R##_e--;                                    409       R##_e--;                                          \
410     break;                                        410     break;                                              \
411                                                   411                                                         \
412   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):    412   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):          \
413     _FP_CHOOSENAN(fs, wc, R, X, Y, '*');          413     _FP_CHOOSENAN(fs, wc, R, X, Y, '*');                \
414     break;                                        414     break;                                              \
415                                                   415                                                         \
416   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMA    416   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):       \
417   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):    417   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):          \
418   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO)    418   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):         \
419     R##_s = X##_s;                                419     R##_s = X##_s;                                      \
420           fallthrough;                            420           fallthrough;                                  \
421                                                   421                                                         \
422   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):    422   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):          \
423   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMA    423   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):       \
424   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORM    424   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):      \
425   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO    425   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):        \
426     _FP_FRAC_COPY_##wc(R, X);                     426     _FP_FRAC_COPY_##wc(R, X);                           \
427     R##_c = X##_c;                                427     R##_c = X##_c;                                      \
428     break;                                        428     break;                                              \
429                                                   429                                                         \
430   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NA    430   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):       \
431   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):    431   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):          \
432   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN)    432   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):         \
433     R##_s = Y##_s;                                433     R##_s = Y##_s;                                      \
434           fallthrough;                            434           fallthrough;                                  \
435                                                   435                                                         \
436   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_IN    436   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):       \
437   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZE    437   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):      \
438     _FP_FRAC_COPY_##wc(R, Y);                     438     _FP_FRAC_COPY_##wc(R, Y);                           \
439     R##_c = Y##_c;                                439     R##_c = Y##_c;                                      \
440     break;                                        440     break;                                              \
441                                                   441                                                         \
442   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO)    442   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):         \
443   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF)    443   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):         \
444     R##_s = _FP_NANSIGN_##fs;                     444     R##_s = _FP_NANSIGN_##fs;                           \
445     R##_c = FP_CLS_NAN;                           445     R##_c = FP_CLS_NAN;                                 \
446     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);       446     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);             \
447     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INV    447     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_IMZ);\
448     break;                                        448     break;                                              \
449                                                   449                                                         \
450   default:                                        450   default:                                              \
451     abort();                                      451     abort();                                            \
452   }                                               452   }                                                     \
453 } while (0)                                       453 } while (0)
454                                                   454 
455                                                   455 
456 /*                                                456 /*
457  * Main division routine.  The input values sh    457  * Main division routine.  The input values should be cooked.
458  */                                               458  */
459                                                   459 
460 #define _FP_DIV(fs, wc, R, X, Y)                  460 #define _FP_DIV(fs, wc, R, X, Y)                        \
461 do {                                              461 do {                                                    \
462   R##_s = X##_s ^ Y##_s;                          462   R##_s = X##_s ^ Y##_s;                                \
463   switch (_FP_CLS_COMBINE(X##_c, Y##_c))          463   switch (_FP_CLS_COMBINE(X##_c, Y##_c))                \
464   {                                               464   {                                                     \
465   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NO    465   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL):    \
466     R##_c = FP_CLS_NORMAL;                        466     R##_c = FP_CLS_NORMAL;                              \
467     R##_e = X##_e - Y##_e;                        467     R##_e = X##_e - Y##_e;                              \
468                                                   468                                                         \
469     _FP_DIV_MEAT_##fs(R,X,Y);                     469     _FP_DIV_MEAT_##fs(R,X,Y);                           \
470     break;                                        470     break;                                              \
471                                                   471                                                         \
472   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):    472   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN):          \
473     _FP_CHOOSENAN(fs, wc, R, X, Y, '/');          473     _FP_CHOOSENAN(fs, wc, R, X, Y, '/');                \
474     break;                                        474     break;                                              \
475                                                   475                                                         \
476   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMA    476   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):       \
477   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):    477   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):          \
478   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO)    478   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):         \
479     R##_s = X##_s;                                479     R##_s = X##_s;                                      \
480     _FP_FRAC_COPY_##wc(R, X);                     480     _FP_FRAC_COPY_##wc(R, X);                           \
481     R##_c = X##_c;                                481     R##_c = X##_c;                                      \
482     break;                                        482     break;                                              \
483                                                   483                                                         \
484   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NA    484   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):       \
485   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):    485   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):          \
486   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN)    486   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):         \
487     R##_s = Y##_s;                                487     R##_s = Y##_s;                                      \
488     _FP_FRAC_COPY_##wc(R, Y);                     488     _FP_FRAC_COPY_##wc(R, Y);                           \
489     R##_c = Y##_c;                                489     R##_c = Y##_c;                                      \
490     break;                                        490     break;                                              \
491                                                   491                                                         \
492   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_IN    492   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):       \
493   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF)    493   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF):         \
494   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORM    494   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):      \
495     R##_c = FP_CLS_ZERO;                          495     R##_c = FP_CLS_ZERO;                                \
496     break;                                        496     break;                                              \
497                                                   497                                                         \
498   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZE    498   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):      \
499     FP_SET_EXCEPTION(FP_EX_DIVZERO);              499     FP_SET_EXCEPTION(FP_EX_DIVZERO);                    \
500         fallthrough;                              500         fallthrough;                                    \
501   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO)    501   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):         \
502   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMA    502   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):       \
503     R##_c = FP_CLS_INF;                           503     R##_c = FP_CLS_INF;                                 \
504     break;                                        504     break;                                              \
505                                                   505                                                         \
506   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):    506   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):          \
507     R##_s = _FP_NANSIGN_##fs;                     507     R##_s = _FP_NANSIGN_##fs;                           \
508     R##_c = FP_CLS_NAN;                           508     R##_c = FP_CLS_NAN;                                 \
509     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);       509     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);             \
510     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INV    510     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_IDI);\
511     break;                                        511     break;                                              \
512                                                   512                                                         \
513   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO    513   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO):        \
514     R##_s = _FP_NANSIGN_##fs;                     514     R##_s = _FP_NANSIGN_##fs;                           \
515     R##_c = FP_CLS_NAN;                           515     R##_c = FP_CLS_NAN;                                 \
516     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);       516     _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);             \
517     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INV    517     FP_SET_EXCEPTION(FP_EX_INVALID | FP_EX_INVALID_ZDZ);\
518     break;                                        518     break;                                              \
519                                                   519                                                         \
520   default:                                        520   default:                                              \
521     abort();                                      521     abort();                                            \
522   }                                               522   }                                                     \
523 } while (0)                                       523 } while (0)
524                                                   524 
525                                                   525 
526 /*                                                526 /*
527  * Main differential comparison routine.  The     527  * Main differential comparison routine.  The inputs should be raw not
528  * cooked.  The return is -1,0,1 for normal va    528  * cooked.  The return is -1,0,1 for normal values, 2 otherwise.
529  */                                               529  */
530                                                   530 
531 #define _FP_CMP(fs, wc, ret, X, Y, un)            531 #define _FP_CMP(fs, wc, ret, X, Y, un)                                  \
532   do {                                            532   do {                                                                  \
533     /* NANs are unordered */                      533     /* NANs are unordered */                                            \
534     if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC    534     if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))           \
535         || (Y##_e == _FP_EXPMAX_##fs && !_FP_F    535         || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))       \
536       {                                           536       {                                                                 \
537         ret = un;                                 537         ret = un;                                                       \
538       }                                           538       }                                                                 \
539     else                                          539     else                                                                \
540       {                                           540       {                                                                 \
541         int __is_zero_x;                          541         int __is_zero_x;                                                \
542         int __is_zero_y;                          542         int __is_zero_y;                                                \
543                                                   543                                                                         \
544         __is_zero_x = (!X##_e && _FP_FRAC_ZERO    544         __is_zero_x = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0;       \
545         __is_zero_y = (!Y##_e && _FP_FRAC_ZERO    545         __is_zero_y = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0;       \
546                                                   546                                                                         \
547         if (__is_zero_x && __is_zero_y)           547         if (__is_zero_x && __is_zero_y)                                 \
548                 ret = 0;                          548                 ret = 0;                                                \
549         else if (__is_zero_x)                     549         else if (__is_zero_x)                                           \
550                 ret = Y##_s ? 1 : -1;             550                 ret = Y##_s ? 1 : -1;                                   \
551         else if (__is_zero_y)                     551         else if (__is_zero_y)                                           \
552                 ret = X##_s ? -1 : 1;             552                 ret = X##_s ? -1 : 1;                                   \
553         else if (X##_s != Y##_s)                  553         else if (X##_s != Y##_s)                                        \
554           ret = X##_s ? -1 : 1;                   554           ret = X##_s ? -1 : 1;                                         \
555         else if (X##_e > Y##_e)                   555         else if (X##_e > Y##_e)                                         \
556           ret = X##_s ? -1 : 1;                   556           ret = X##_s ? -1 : 1;                                         \
557         else if (X##_e < Y##_e)                   557         else if (X##_e < Y##_e)                                         \
558           ret = X##_s ? 1 : -1;                   558           ret = X##_s ? 1 : -1;                                         \
559         else if (_FP_FRAC_GT_##wc(X, Y))          559         else if (_FP_FRAC_GT_##wc(X, Y))                                \
560           ret = X##_s ? -1 : 1;                   560           ret = X##_s ? -1 : 1;                                         \
561         else if (_FP_FRAC_GT_##wc(Y, X))          561         else if (_FP_FRAC_GT_##wc(Y, X))                                \
562           ret = X##_s ? 1 : -1;                   562           ret = X##_s ? 1 : -1;                                         \
563         else                                      563         else                                                            \
564           ret = 0;                                564           ret = 0;                                                      \
565       }                                           565       }                                                                 \
566   } while (0)                                     566   } while (0)
567                                                   567 
568                                                   568 
569 /* Simplification for strict equality.  */        569 /* Simplification for strict equality.  */
570                                                   570 
571 #define _FP_CMP_EQ(fs, wc, ret, X, Y)             571 #define _FP_CMP_EQ(fs, wc, ret, X, Y)                                     \
572   do {                                            572   do {                                                                    \
573     /* NANs are unordered */                      573     /* NANs are unordered */                                              \
574     if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC    574     if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))             \
575         || (Y##_e == _FP_EXPMAX_##fs && !_FP_F    575         || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y)))         \
576       {                                           576       {                                                                   \
577         ret = 1;                                  577         ret = 1;                                                          \
578       }                                           578       }                                                                   \
579     else                                          579     else                                                                  \
580       {                                           580       {                                                                   \
581         ret = !(X##_e == Y##_e                    581         ret = !(X##_e == Y##_e                                            \
582                 && _FP_FRAC_EQ_##wc(X, Y)         582                 && _FP_FRAC_EQ_##wc(X, Y)                                 \
583                 && (X##_s == Y##_s || !X##_e &    583                 && (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
584       }                                           584       }                                                                   \
585   } while (0)                                     585   } while (0)
586                                                   586 
587 /*                                                587 /*
588  * Main square root routine.  The input value     588  * Main square root routine.  The input value should be cooked.
589  */                                               589  */
590                                                   590 
591 #define _FP_SQRT(fs, wc, R, X)                    591 #define _FP_SQRT(fs, wc, R, X)                                          \
592 do {                                              592 do {                                                                    \
593     _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(    593     _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S);                       \
594     _FP_W_TYPE q;                                 594     _FP_W_TYPE q;                                                       \
595     switch (X##_c)                                595     switch (X##_c)                                                      \
596     {                                             596     {                                                                   \
597     case FP_CLS_NAN:                              597     case FP_CLS_NAN:                                                    \
598         _FP_FRAC_COPY_##wc(R, X);                 598         _FP_FRAC_COPY_##wc(R, X);                                       \
599         R##_s = X##_s;                            599         R##_s = X##_s;                                                  \
600         R##_c = FP_CLS_NAN;                       600         R##_c = FP_CLS_NAN;                                             \
601         break;                                    601         break;                                                          \
602     case FP_CLS_INF:                              602     case FP_CLS_INF:                                                    \
603         if (X##_s)                                603         if (X##_s)                                                      \
604           {                                       604           {                                                             \
605             R##_s = _FP_NANSIGN_##fs;             605             R##_s = _FP_NANSIGN_##fs;                                   \
606             R##_c = FP_CLS_NAN; /* NAN */         606             R##_c = FP_CLS_NAN; /* NAN */                               \
607             _FP_FRAC_SET_##wc(R, _FP_NANFRAC_#    607             _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);                     \
608             FP_SET_EXCEPTION(FP_EX_INVALID);      608             FP_SET_EXCEPTION(FP_EX_INVALID);                            \
609           }                                       609           }                                                             \
610         else                                      610         else                                                            \
611           {                                       611           {                                                             \
612             R##_s = 0;                            612             R##_s = 0;                                                  \
613             R##_c = FP_CLS_INF; /* sqrt(+inf)     613             R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */                 \
614           }                                       614           }                                                             \
615         break;                                    615         break;                                                          \
616     case FP_CLS_ZERO:                             616     case FP_CLS_ZERO:                                                   \
617         R##_s = X##_s;                            617         R##_s = X##_s;                                                  \
618         R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-    618         R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */                      \
619         break;                                    619         break;                                                          \
620     case FP_CLS_NORMAL:                           620     case FP_CLS_NORMAL:                                                 \
621         R##_s = 0;                                621         R##_s = 0;                                                      \
622         if (X##_s)                                622         if (X##_s)                                                      \
623           {                                       623           {                                                             \
624             R##_c = FP_CLS_NAN; /* sNAN */        624             R##_c = FP_CLS_NAN; /* sNAN */                              \
625             R##_s = _FP_NANSIGN_##fs;             625             R##_s = _FP_NANSIGN_##fs;                                   \
626             _FP_FRAC_SET_##wc(R, _FP_NANFRAC_#    626             _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs);                     \
627             FP_SET_EXCEPTION(FP_EX_INVALID);      627             FP_SET_EXCEPTION(FP_EX_INVALID);                            \
628             break;                                628             break;                                                      \
629           }                                       629           }                                                             \
630         R##_c = FP_CLS_NORMAL;                    630         R##_c = FP_CLS_NORMAL;                                          \
631         if (X##_e & 1)                            631         if (X##_e & 1)                                                  \
632           _FP_FRAC_SLL_##wc(X, 1);                632           _FP_FRAC_SLL_##wc(X, 1);                                      \
633         R##_e = X##_e >> 1;                       633         R##_e = X##_e >> 1;                                             \
634         _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc    634         _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc);                        \
635         _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc    635         _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc);                        \
636         q = _FP_OVERFLOW_##fs >> 1;               636         q = _FP_OVERFLOW_##fs >> 1;                                     \
637         _FP_SQRT_MEAT_##wc(R, S, T, X, q);        637         _FP_SQRT_MEAT_##wc(R, S, T, X, q);                              \
638     }                                             638     }                                                                   \
639   } while (0)                                     639   } while (0)
640                                                   640 
641 /*                                                641 /*
642  * Convert from FP to integer                     642  * Convert from FP to integer
643  */                                               643  */
644                                                   644 
645 /* RSIGNED can have following values:             645 /* RSIGNED can have following values:
646  * 0:  the number is required to be 0..(2^rsiz    646  * 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    647  *     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    648  * 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    649  *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
650  *     on the sign in such case.                  650  *     on the sign in such case.
651  * 2:  the number is required to be -(2^(rsize    651  * 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    652  *     set plus the result is truncated to fit into destination.
653  * -1: the number is required to be -(2^(rsize    653  * -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    654  *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
655  *     on the sign in such case.                  655  *     on the sign in such case.
656  */                                               656  */
657 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigne    657 #define _FP_TO_INT(fs, wc, r, X, rsize, rsigned)                                \
658   do {                                            658   do {                                                                          \
659     switch (X##_c)                                659     switch (X##_c)                                                              \
660       {                                           660       {                                                                         \
661       case FP_CLS_NORMAL:                         661       case FP_CLS_NORMAL:                                                       \
662         if (X##_e < 0)                            662         if (X##_e < 0)                                                          \
663           {                                       663           {                                                                     \
664             FP_SET_EXCEPTION(FP_EX_INEXACT);      664             FP_SET_EXCEPTION(FP_EX_INEXACT);                                    \
665             fallthrough;                       << 
666           case FP_CLS_ZERO:                       665           case FP_CLS_ZERO:                                                     \
667             r = 0;                                666             r = 0;                                                              \
668           }                                       667           }                                                                     \
669         else if (X##_e >= rsize - (rsigned > 0    668         else if (X##_e >= rsize - (rsigned > 0 || X##_s)                        \
670                  || (!rsigned && X##_s))          669                  || (!rsigned && X##_s))                                        \
671           {     /* overflow */                    670           {     /* overflow */                                                  \
672             fallthrough;                       << 
673           case FP_CLS_NAN:                        671           case FP_CLS_NAN:                                                      \
674           case FP_CLS_INF:                        672           case FP_CLS_INF:                                                      \
675             if (rsigned == 2)                     673             if (rsigned == 2)                                                   \
676               {                                   674               {                                                                 \
677                 if (X##_c != FP_CLS_NORMAL        675                 if (X##_c != FP_CLS_NORMAL                                      \
678                     || X##_e >= rsize - 1 + _F    676                     || X##_e >= rsize - 1 + _FP_WFRACBITS_##fs)                 \
679                   r = 0;                          677                   r = 0;                                                        \
680                 else                              678                 else                                                            \
681                   {                               679                   {                                                             \
682                     _FP_FRAC_SLL_##wc(X, (X##_    680                     _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));     \
683                     _FP_FRAC_ASSEMBLE_##wc(r,     681                     _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                        \
684                   }                               682                   }                                                             \
685               }                                   683               }                                                                 \
686             else if (rsigned)                     684             else if (rsigned)                                                   \
687               {                                   685               {                                                                 \
688                 r = 1;                            686                 r = 1;                                                          \
689                 r <<= rsize - 1;                  687                 r <<= rsize - 1;                                                \
690                 r -= 1 - X##_s;                   688                 r -= 1 - X##_s;                                                 \
691               }                                   689               }                                                                 \
692             else                                  690             else                                                                \
693               {                                   691               {                                                                 \
694                 r = 0;                            692                 r = 0;                                                          \
695                 if (!X##_s)                       693                 if (!X##_s)                                                     \
696                   r = ~r;                         694                   r = ~r;                                                       \
697               }                                   695               }                                                                 \
698             FP_SET_EXCEPTION(FP_EX_INVALID);      696             FP_SET_EXCEPTION(FP_EX_INVALID);                                    \
699           }                                       697           }                                                                     \
700         else                                      698         else                                                                    \
701           {                                       699           {                                                                     \
702             if (_FP_W_TYPE_SIZE*wc < rsize)       700             if (_FP_W_TYPE_SIZE*wc < rsize)                                     \
703               {                                   701               {                                                                 \
704                 _FP_FRAC_ASSEMBLE_##wc(r, X, r    702                 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                            \
705                 r <<= X##_e - _FP_WFRACBITS_##    703                 r <<= X##_e - _FP_WFRACBITS_##fs;                               \
706               }                                   704               }                                                                 \
707             else                                  705             else                                                                \
708               {                                   706               {                                                                 \
709                 if (X##_e >= _FP_WFRACBITS_##f    707                 if (X##_e >= _FP_WFRACBITS_##fs)                                \
710                   _FP_FRAC_SLL_##wc(X, (X##_e     708                   _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));       \
711                 else if (X##_e < _FP_WFRACBITS    709                 else if (X##_e < _FP_WFRACBITS_##fs - 1)                        \
712                   {                               710                   {                                                             \
713                     _FP_FRAC_SRS_##wc(X, (_FP_    711                     _FP_FRAC_SRS_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 2),      \
714                                       _FP_WFRA    712                                       _FP_WFRACBITS_##fs);                      \
715                     if (_FP_FRAC_LOW_##wc(X) &    713                     if (_FP_FRAC_LOW_##wc(X) & 1)                               \
716                       FP_SET_EXCEPTION(FP_EX_I    714                       FP_SET_EXCEPTION(FP_EX_INEXACT);                          \
717                     _FP_FRAC_SRL_##wc(X, 1);      715                     _FP_FRAC_SRL_##wc(X, 1);                                    \
718                   }                               716                   }                                                             \
719                 _FP_FRAC_ASSEMBLE_##wc(r, X, r    717                 _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                            \
720               }                                   718               }                                                                 \
721             if (rsigned && X##_s)                 719             if (rsigned && X##_s)                                               \
722               r = -r;                             720               r = -r;                                                           \
723           }                                       721           }                                                                     \
724         break;                                    722         break;                                                                  \
725       }                                           723       }                                                                         \
726   } while (0)                                     724   } while (0)
727                                                   725 
728 #define _FP_TO_INT_ROUND(fs, wc, r, X, rsize,     726 #define _FP_TO_INT_ROUND(fs, wc, r, X, rsize, rsigned)                          \
729   do {                                            727   do {                                                                          \
730     r = 0;                                        728     r = 0;                                                                      \
731     switch (X##_c)                                729     switch (X##_c)                                                              \
732       {                                           730       {                                                                         \
733       case FP_CLS_NORMAL:                         731       case FP_CLS_NORMAL:                                                       \
734         if (X##_e >= _FP_FRACBITS_##fs - 1)       732         if (X##_e >= _FP_FRACBITS_##fs - 1)                                     \
735           {                                       733           {                                                                     \
736             if (X##_e < rsize - 1 + _FP_WFRACB    734             if (X##_e < rsize - 1 + _FP_WFRACBITS_##fs)                         \
737               {                                   735               {                                                                 \
738                 if (X##_e >= _FP_WFRACBITS_##f    736                 if (X##_e >= _FP_WFRACBITS_##fs - 1)                            \
739                   {                               737                   {                                                             \
740                     _FP_FRAC_ASSEMBLE_##wc(r,     738                     _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                        \
741                     r <<= X##_e - _FP_WFRACBIT    739                     r <<= X##_e - _FP_WFRACBITS_##fs + 1;                       \
742                   }                               740                   }                                                             \
743                 else                              741                 else                                                            \
744                   {                               742                   {                                                             \
745                     _FP_FRAC_SRL_##wc(X, _FP_W    743                     _FP_FRAC_SRL_##wc(X, _FP_WORKBITS - X##_e                   \
746                                       + _FP_FR    744                                       + _FP_FRACBITS_##fs - 1);                 \
747                     _FP_FRAC_ASSEMBLE_##wc(r,     745                     _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                        \
748                   }                               746                   }                                                             \
749               }                                   747               }                                                                 \
750           }                                       748           }                                                                     \
751         else                                      749         else                                                                    \
752           {                                       750           {                                                                     \
753             int _lz0, _lz1;                       751             int _lz0, _lz1;                                                     \
754             if (X##_e <= -_FP_WORKBITS - 1)       752             if (X##_e <= -_FP_WORKBITS - 1)                                     \
755               _FP_FRAC_SET_##wc(X, _FP_MINFRAC    753               _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);                           \
756             else                                  754             else                                                                \
757               _FP_FRAC_SRS_##wc(X, _FP_FRACBIT    755               _FP_FRAC_SRS_##wc(X, _FP_FRACBITS_##fs - 1 - X##_e,               \
758                                 _FP_WFRACBITS_    756                                 _FP_WFRACBITS_##fs);                            \
759             _FP_FRAC_CLZ_##wc(_lz0, X);           757             _FP_FRAC_CLZ_##wc(_lz0, X);                                         \
760             _FP_ROUND(wc, X);                     758             _FP_ROUND(wc, X);                                                   \
761             _FP_FRAC_CLZ_##wc(_lz1, X);           759             _FP_FRAC_CLZ_##wc(_lz1, X);                                         \
762             if (_lz1 < _lz0)                      760             if (_lz1 < _lz0)                                                    \
763               X##_e++; /* For overflow detecti    761               X##_e++; /* For overflow detection.  */                           \
764             _FP_FRAC_SRL_##wc(X, _FP_WORKBITS)    762             _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);                                 \
765             _FP_FRAC_ASSEMBLE_##wc(r, X, rsize    763             _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);                                \
766           }                                       764           }                                                                     \
767         if (rsigned && X##_s)                     765         if (rsigned && X##_s)                                                   \
768           r = -r;                                 766           r = -r;                                                               \
769         if (X##_e >= rsize - (rsigned > 0 || X    767         if (X##_e >= rsize - (rsigned > 0 || X##_s)                             \
770             || (!rsigned && X##_s))               768             || (!rsigned && X##_s))                                             \
771           {     /* overflow */                    769           {     /* overflow */                                                  \
772             fallthrough;                       << 
773           case FP_CLS_NAN:                        770           case FP_CLS_NAN:                                                      \
774           case FP_CLS_INF:                        771           case FP_CLS_INF:                                                      \
775             if (!rsigned)                         772             if (!rsigned)                                                       \
776               {                                   773               {                                                                 \
777                 r = 0;                            774                 r = 0;                                                          \
778                 if (!X##_s)                       775                 if (!X##_s)                                                     \
779                   r = ~r;                         776                   r = ~r;                                                       \
780               }                                   777               }                                                                 \
781             else if (rsigned != 2)                778             else if (rsigned != 2)                                              \
782               {                                   779               {                                                                 \
783                 r = 1;                            780                 r = 1;                                                          \
784                 r <<= rsize - 1;                  781                 r <<= rsize - 1;                                                \
785                 r -= 1 - X##_s;                   782                 r -= 1 - X##_s;                                                 \
786               }                                   783               }                                                                 \
787             FP_SET_EXCEPTION(FP_EX_INVALID);      784             FP_SET_EXCEPTION(FP_EX_INVALID);                                    \
788           }                                       785           }                                                                     \
789         break;                                    786         break;                                                                  \
790       case FP_CLS_ZERO:                           787       case FP_CLS_ZERO:                                                         \
791         break;                                    788         break;                                                                  \
792       }                                           789       }                                                                         \
793   } while (0)                                     790   } while (0)
794                                                   791 
795 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtyp    792 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)                        \
796   do {                                            793   do {                                                                  \
797     if (r)                                        794     if (r)                                                              \
798       {                                           795       {                                                                 \
799         unsigned rtype ur_;                       796         unsigned rtype ur_;                                             \
800         X##_c = FP_CLS_NORMAL;                    797         X##_c = FP_CLS_NORMAL;                                          \
801                                                   798                                                                         \
802         if ((X##_s = (r < 0)))                    799         if ((X##_s = (r < 0)))                                          \
803           ur_ = (unsigned rtype) -r;              800           ur_ = (unsigned rtype) -r;                                    \
804         else                                      801         else                                                            \
805           ur_ = (unsigned rtype) r;               802           ur_ = (unsigned rtype) r;                                     \
806         (void) (((rsize) <= _FP_W_TYPE_SIZE)      803         (void) (((rsize) <= _FP_W_TYPE_SIZE)                            \
807                 ? ({ __FP_CLZ(X##_e, ur_); })     804                 ? ({ __FP_CLZ(X##_e, ur_); })                           \
808                 : ({                              805                 : ({                                                    \
809                      __FP_CLZ_2(X##_e, (_FP_W_    806                      __FP_CLZ_2(X##_e, (_FP_W_TYPE)(ur_ >> _FP_W_TYPE_SIZE),  \
810                                                   807                                                             (_FP_W_TYPE)ur_); \
811                   }));                            808                   }));                                                  \
812         if (rsize < _FP_W_TYPE_SIZE)              809         if (rsize < _FP_W_TYPE_SIZE)                                    \
813                 X##_e -= (_FP_W_TYPE_SIZE - rs    810                 X##_e -= (_FP_W_TYPE_SIZE - rsize);                     \
814         X##_e = rsize - X##_e - 1;                811         X##_e = rsize - X##_e - 1;                                      \
815                                                   812                                                                         \
816         if (_FP_FRACBITS_##fs < rsize && _FP_W    813         if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs <= X##_e)   \
817           __FP_FRAC_SRS_1(ur_, (X##_e - _FP_WF    814           __FP_FRAC_SRS_1(ur_, (X##_e - _FP_WFRACBITS_##fs + 1), rsize);\
818         _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsiz    815         _FP_FRAC_DISASSEMBLE_##wc(X, ur_, rsize);                       \
819         if ((_FP_WFRACBITS_##fs - X##_e - 1) >    816         if ((_FP_WFRACBITS_##fs - X##_e - 1) > 0)                       \
820           _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_    817           _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));       \
821       }                                           818       }                                                                 \
822     else                                          819     else                                                                \
823       {                                           820       {                                                                 \
824         X##_c = FP_CLS_ZERO, X##_s = 0;           821         X##_c = FP_CLS_ZERO, X##_s = 0;                                 \
825       }                                           822       }                                                                 \
826   } while (0)                                     823   } while (0)
827                                                   824 
828                                                   825 
829 #define FP_CONV(dfs,sfs,dwc,swc,D,S)              826 #define FP_CONV(dfs,sfs,dwc,swc,D,S)                    \
830   do {                                            827   do {                                                  \
831     _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S    828     _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S);        \
832     D##_e = S##_e;                                829     D##_e = S##_e;                                      \
833     D##_c = S##_c;                                830     D##_c = S##_c;                                      \
834     D##_s = S##_s;                                831     D##_s = S##_s;                                      \
835   } while (0)                                     832   } while (0)
836                                                   833 
837 /*                                                834 /*
838  * Helper primitives.                             835  * Helper primitives.
839  */                                               836  */
840                                                   837 
841 /* Count leading zeros in a word.  */             838 /* Count leading zeros in a word.  */
842                                                   839 
843 #ifndef __FP_CLZ                                  840 #ifndef __FP_CLZ
844 #if _FP_W_TYPE_SIZE < 64                          841 #if _FP_W_TYPE_SIZE < 64
845 /* this is just to shut the compiler up about     842 /* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
846 #define __FP_CLZ(r, x)                            843 #define __FP_CLZ(r, x)                          \
847   do {                                            844   do {                                          \
848     _FP_W_TYPE _t = (x);                          845     _FP_W_TYPE _t = (x);                        \
849     r = _FP_W_TYPE_SIZE - 1;                      846     r = _FP_W_TYPE_SIZE - 1;                    \
850     if (_t > 0xffff) r -= 16;                     847     if (_t > 0xffff) r -= 16;                   \
851     if (_t > 0xffff) _t >>= 16;                   848     if (_t > 0xffff) _t >>= 16;                 \
852     if (_t > 0xff) r -= 8;                        849     if (_t > 0xff) r -= 8;                      \
853     if (_t > 0xff) _t >>= 8;                      850     if (_t > 0xff) _t >>= 8;                    \
854     if (_t & 0xf0) r -= 4;                        851     if (_t & 0xf0) r -= 4;                      \
855     if (_t & 0xf0) _t >>= 4;                      852     if (_t & 0xf0) _t >>= 4;                    \
856     if (_t & 0xc) r -= 2;                         853     if (_t & 0xc) r -= 2;                       \
857     if (_t & 0xc) _t >>= 2;                       854     if (_t & 0xc) _t >>= 2;                     \
858     if (_t & 0x2) r -= 1;                         855     if (_t & 0x2) r -= 1;                       \
859   } while (0)                                     856   } while (0)
860 #else /* not _FP_W_TYPE_SIZE < 64 */              857 #else /* not _FP_W_TYPE_SIZE < 64 */
861 #define __FP_CLZ(r, x)                            858 #define __FP_CLZ(r, x)                          \
862   do {                                            859   do {                                          \
863     _FP_W_TYPE _t = (x);                          860     _FP_W_TYPE _t = (x);                        \
864     r = _FP_W_TYPE_SIZE - 1;                      861     r = _FP_W_TYPE_SIZE - 1;                    \
865     if (_t > 0xffffffff) r -= 32;                 862     if (_t > 0xffffffff) r -= 32;               \
866     if (_t > 0xffffffff) _t >>= 32;               863     if (_t > 0xffffffff) _t >>= 32;             \
867     if (_t > 0xffff) r -= 16;                     864     if (_t > 0xffff) r -= 16;                   \
868     if (_t > 0xffff) _t >>= 16;                   865     if (_t > 0xffff) _t >>= 16;                 \
869     if (_t > 0xff) r -= 8;                        866     if (_t > 0xff) r -= 8;                      \
870     if (_t > 0xff) _t >>= 8;                      867     if (_t > 0xff) _t >>= 8;                    \
871     if (_t & 0xf0) r -= 4;                        868     if (_t & 0xf0) r -= 4;                      \
872     if (_t & 0xf0) _t >>= 4;                      869     if (_t & 0xf0) _t >>= 4;                    \
873     if (_t & 0xc) r -= 2;                         870     if (_t & 0xc) r -= 2;                       \
874     if (_t & 0xc) _t >>= 2;                       871     if (_t & 0xc) _t >>= 2;                     \
875     if (_t & 0x2) r -= 1;                         872     if (_t & 0x2) r -= 1;                       \
876   } while (0)                                     873   } while (0)
877 #endif /* not _FP_W_TYPE_SIZE < 64 */             874 #endif /* not _FP_W_TYPE_SIZE < 64 */
878 #endif /* ndef __FP_CLZ */                        875 #endif /* ndef __FP_CLZ */
879                                                   876 
880 #define _FP_DIV_HELP_imm(q, r, n, d)              877 #define _FP_DIV_HELP_imm(q, r, n, d)            \
881   do {                                            878   do {                                          \
882     q = n / d, r = n % d;                         879     q = n / d, r = n % d;                       \
883   } while (0)                                     880   } while (0)
884                                                   881 
885 #endif /* __MATH_EMU_OP_COMMON_H__ */             882 #endif /* __MATH_EMU_OP_COMMON_H__ */
886                                                   883 

~ [ 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