~ [ 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.1.114)


** Warning: Cannot open xref database.

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

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