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

TOMOYO Linux Cross Reference
Linux/arch/parisc/math-emu/sfadd.c

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 /arch/parisc/math-emu/sfadd.c (Version linux-6.12-rc7) and /arch/ppc/math-emu/sfadd.c (Version linux-4.14.336)


  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 
  2 /*                                                
  3  * Linux/PA-RISC Project (http://www.parisc-li    
  4  *                                                
  5  * Floating-point emulation code                  
  6  *  Copyright (C) 2001 Hewlett-Packard (Paul B    
  7  */                                               
  8 /*                                                
  9  * BEGIN_DESC                                     
 10  *                                                
 11  *  File:                                         
 12  *      @(#)    pa/spmath/sfadd.c                 
 13  *                                                
 14  *  Purpose:                                      
 15  *      Single_add: add two single precision v    
 16  *                                                
 17  *  External Interfaces:                          
 18  *      sgl_fadd(leftptr, rightptr, dstptr, st    
 19  *                                                
 20  *  Internal Interfaces:                          
 21  *                                                
 22  *  Theory:                                       
 23  *      <<please update with a overview of the    
 24  *                                                
 25  * END_DESC                                       
 26 */                                                
 27                                                   
 28                                                   
 29 #include "float.h"                                
 30 #include "sgl_float.h"                            
 31                                                   
 32 /*                                                
 33  * Single_add: add two single precision values    
 34  */                                               
 35 int                                               
 36 sgl_fadd(                                         
 37     sgl_floating_point *leftptr,                  
 38     sgl_floating_point *rightptr,                 
 39     sgl_floating_point *dstptr,                   
 40     unsigned int *status)                         
 41     {                                             
 42     register unsigned int left, right, result,    
 43     register unsigned int signless_upper_left,    
 44                                                   
 45                                                   
 46     register int result_exponent, right_expone    
 47     register int sign_save, jumpsize;             
 48     register boolean inexact = FALSE;             
 49     register boolean underflowtrap;               
 50                                                   
 51     /* Create local copies of the numbers */      
 52     left = *leftptr;                              
 53     right = *rightptr;                            
 54                                                   
 55     /* A zero "save" helps discover equal oper    
 56      * and is used in swapping operands (if ne    
 57     Sgl_xortointp1(left,right,/*to*/save);        
 58                                                   
 59     /*                                            
 60      * check first operand for NaN's or infini    
 61      */                                           
 62     if ((result_exponent = Sgl_exponent(left))    
 63         {                                         
 64         if (Sgl_iszero_mantissa(left))            
 65             {                                     
 66             if (Sgl_isnotnan(right))              
 67                 {                                 
 68                 if (Sgl_isinfinity(right) && s    
 69                     {                             
 70                     /*                            
 71                      * invalid since operands     
 72                      */                           
 73                     if (Is_invalidtrap_enabled    
 74                     Set_invalidflag();            
 75                     Sgl_makequietnan(result);     
 76                     *dstptr = result;             
 77                     return(NOEXCEPTION);          
 78                     }                             
 79                 /*                                
 80                  * return infinity                
 81                  */                               
 82                 *dstptr = left;                   
 83                 return(NOEXCEPTION);              
 84                 }                                 
 85             }                                     
 86         else                                      
 87             {                                     
 88             /*                                    
 89              * is NaN; signaling or quiet?        
 90              */                                   
 91             if (Sgl_isone_signaling(left))        
 92                 {                                 
 93                 /* trap if INVALIDTRAP enabled    
 94                 if (Is_invalidtrap_enabled())     
 95                 /* make NaN quiet */              
 96                 Set_invalidflag();                
 97                 Sgl_set_quiet(left);              
 98                 }                                 
 99             /*                                    
100              * is second operand a signaling N    
101              */                                   
102             else if (Sgl_is_signalingnan(right    
103                 {                                 
104                 /* trap if INVALIDTRAP enabled    
105                 if (Is_invalidtrap_enabled())     
106                 /* make NaN quiet */              
107                 Set_invalidflag();                
108                 Sgl_set_quiet(right);             
109                 *dstptr = right;                  
110                 return(NOEXCEPTION);              
111                 }                                 
112             /*                                    
113              * return quiet NaN                   
114              */                                   
115             *dstptr = left;                       
116             return(NOEXCEPTION);                  
117             }                                     
118         } /* End left NaN or Infinity processi    
119     /*                                            
120      * check second operand for NaN's or infin    
121      */                                           
122     if (Sgl_isinfinity_exponent(right))           
123         {                                         
124         if (Sgl_iszero_mantissa(right))           
125             {                                     
126             /* return infinity */                 
127             *dstptr = right;                      
128             return(NOEXCEPTION);                  
129             }                                     
130         /*                                        
131          * is NaN; signaling or quiet?            
132          */                                       
133         if (Sgl_isone_signaling(right))           
134             {                                     
135             /* trap if INVALIDTRAP enabled */     
136             if (Is_invalidtrap_enabled()) retu    
137             /* make NaN quiet */                  
138             Set_invalidflag();                    
139             Sgl_set_quiet(right);                 
140             }                                     
141         /*                                        
142          * return quiet NaN                       
143          */                                       
144         *dstptr = right;                          
145         return(NOEXCEPTION);                      
146         } /* End right NaN or Infinity process    
147                                                   
148     /* Invariant: Must be dealing with finite     
149                                                   
150     /* Compare operands by removing the sign *    
151     Sgl_copytoint_exponentmantissa(left,signle    
152     Sgl_copytoint_exponentmantissa(right,signl    
153                                                   
154     /* sign difference selects add or sub oper    
155     if(Sgl_ismagnitudeless(signless_upper_left    
156         {                                         
157         /* Set the left operand to the larger     
158          *  First finish the first word using     
159         Sgl_xorfromintp1(save,right,/*to*/righ    
160         Sgl_xorfromintp1(save,left,/*to*/left)    
161         result_exponent = Sgl_exponent(left);     
162         }                                         
163     /* Invariant:  left is not smaller than ri    
164                                                   
165     if((right_exponent = Sgl_exponent(right))     
166         {                                         
167         /* Denormalized operands.  First look     
168         if(Sgl_iszero_mantissa(right))            
169             {                                     
170             /* right is zero */                   
171             if(Sgl_iszero_exponentmantissa(lef    
172                 {                                 
173                 /* Both operands are zeros */     
174                 if(Is_rounding_mode(ROUNDMINUS    
175                     {                             
176                     Sgl_or_signs(left,/*with*/    
177                     }                             
178                 else                              
179                     {                             
180                     Sgl_and_signs(left,/*with*    
181                     }                             
182                 }                                 
183             else                                  
184                 {                                 
185                 /* Left is not a zero and must    
186                  * underflows are signaled if     
187                  * is always exact. */            
188                 if( (result_exponent == 0) &&     
189                     {                             
190                     /* need to normalize resul    
191                     sign_save = Sgl_signextend    
192                     Sgl_leftshiftby1(left);       
193                     Sgl_normalize(left,result_    
194                     Sgl_set_sign(left,/*using*    
195                     Sgl_setwrapped_exponent(le    
196                     *dstptr = left;               
197                     return(UNDERFLOWEXCEPTION)    
198                     }                             
199                 }                                 
200             *dstptr = left;                       
201             return(NOEXCEPTION);                  
202             }                                     
203                                                   
204         /* Neither are zeroes */                  
205         Sgl_clear_sign(right);  /* Exponent is    
206         if(result_exponent == 0 )                 
207             {                                     
208             /* Both operands are denormalized.    
209              * and is simply calculated.  A su    
210              * difference could cancel to a tr    
211             if( (/*signed*/int) save < 0 )        
212                 {                                 
213                 Sgl_subtract(left,/*minus*/rig    
214                 if(Sgl_iszero_mantissa(result)    
215                     {                             
216                     if(Is_rounding_mode(ROUNDM    
217                         {                         
218                         Sgl_setone_sign(result    
219                         }                         
220                     else                          
221                         {                         
222                         Sgl_setzero_sign(resul    
223                         }                         
224                     *dstptr = result;             
225                     return(NOEXCEPTION);          
226                     }                             
227                 }                                 
228             else                                  
229                 {                                 
230                 Sgl_addition(left,right,/*into    
231                 if(Sgl_isone_hidden(result))      
232                     {                             
233                     *dstptr = result;             
234                     return(NOEXCEPTION);          
235                     }                             
236                 }                                 
237             if(Is_underflowtrap_enabled())        
238                 {                                 
239                 /* need to normalize result */    
240                 sign_save = Sgl_signextendedsi    
241                 Sgl_leftshiftby1(result);         
242                 Sgl_normalize(result,result_ex    
243                 Sgl_set_sign(result,/*using*/s    
244                 Sgl_setwrapped_exponent(result    
245                 *dstptr = result;                 
246                 return(UNDERFLOWEXCEPTION);       
247                 }                                 
248             *dstptr = result;                     
249             return(NOEXCEPTION);                  
250             }                                     
251         right_exponent = 1;     /* Set exponen    
252                                  * with denorm    
253         }                                         
254     else                                          
255         {                                         
256         Sgl_clear_signexponent_set_hidden(righ    
257         }                                         
258     Sgl_clear_exponent_set_hidden(left);          
259     diff_exponent = result_exponent - right_ex    
260                                                   
261     /*                                            
262      * Special case alignment of operands that    
263      * beyond the extent of the extension.  A     
264      * could special case this but only reduce    
265      * infrequent case.                           
266      */                                           
267     if(diff_exponent > SGL_THRESHOLD)             
268         {                                         
269         diff_exponent = SGL_THRESHOLD;            
270         }                                         
271                                                   
272     /* Align right operand by shifting to righ    
273     Sgl_right_align(/*operand*/right,/*shifted    
274      /*and lower to*/extent);                     
275                                                   
276     /* Treat sum and difference of the operand    
277     if( (/*signed*/int) save < 0 )                
278         {                                         
279         /*                                        
280          * Difference of the two operands.  Th    
281          * borrow can occur out of the hidden     
282          * normalization phase.                   
283          */                                       
284         Sgl_subtract_withextension(left,/*minu    
285         if(Sgl_iszero_hidden(result))             
286             {                                     
287             /* Handle normalization */            
288             /* A straightforward algorithm wou    
289              * and extension left until the hi    
290              * all of the extension bits need     
291              * Only the two most significant b    
292              * needed.  If only a single shift    
293              * bit becomes a significant low o    
294              * must participate in the roundin    
295              * shift is needed, then all bits     
296              * bit are zeros, and the guard bi    
297             sign_save = Sgl_signextendedsign(r    
298             Sgl_leftshiftby1_withextent(result    
299                                                   
300             /* Need to check for a zero result    
301              * fields have already been zeroed    
302              * of the full object can be used.    
303              */                                   
304             if(Sgl_iszero(result))                
305                 /* Must have been "x-x" or "x+    
306                 {                                 
307                 if(Is_rounding_mode(ROUNDMINUS    
308                 *dstptr = result;                 
309                 return(NOEXCEPTION);              
310                 }                                 
311             result_exponent--;                    
312             /* Look to see if normalization is    
313             if(Sgl_isone_hidden(result))          
314                 {                                 
315                 if(result_exponent==0)            
316                     {                             
317                     /* Denormalized, exponent     
318                      * was normalized, so exte    
319                     goto underflow;               
320                     }                             
321                 else                              
322                     {                             
323                     /* No further normalizatio    
324                     Sgl_set_sign(result,/*usin    
325                     Ext_leftshiftby1(extent);     
326                     goto round;                   
327                     }                             
328                 }                                 
329                                                   
330             /* Check for denormalized, exponen    
331              * operand was normalized, so exte    
332             if(!(underflowtrap = Is_underflowt    
333                result_exponent==0) goto underf    
334                                                   
335             /* Shift extension to complete one    
336              * update exponent. */                
337             Ext_leftshiftby1(extent);             
338                                                   
339             /* Discover first one bit to deter    
340              * modified binary search.  We hav    
341              * one position right and still no    
342              * of the extension must be zero a    
343             /* Scan bytes */                      
344             while(Sgl_iszero_hiddenhigh7mantis    
345                 {                                 
346                 Sgl_leftshiftby8(result);         
347                 if((result_exponent -= 8) <= 0    
348                     goto underflow;               
349                 }                                 
350             /* Now narrow it down to the nibbl    
351             if(Sgl_iszero_hiddenhigh3mantissa(    
352                 {                                 
353                 /* The lower nibble contains t    
354                 Sgl_leftshiftby4(result);         
355                 if((result_exponent -= 4) <= 0    
356                     goto underflow;               
357                 }                                 
358             /* Select case were first bit is s    
359              * otherwise select the proper shi    
360             if((jumpsize = Sgl_hiddenhigh3mant    
361                 {                                 
362                 /* Already normalized */          
363                 if(result_exponent <= 0) goto     
364                 Sgl_set_sign(result,/*using*/s    
365                 Sgl_set_exponent(result,/*usin    
366                 *dstptr = result;                 
367                 return(NOEXCEPTION);              
368                 }                                 
369             Sgl_sethigh4bits(result,/*using*/s    
370             switch(jumpsize)                      
371                 {                                 
372                 case 1:                           
373                     {                             
374                     Sgl_leftshiftby3(result);     
375                     result_exponent -= 3;         
376                     break;                        
377                     }                             
378                 case 2:                           
379                 case 3:                           
380                     {                             
381                     Sgl_leftshiftby2(result);     
382                     result_exponent -= 2;         
383                     break;                        
384                     }                             
385                 case 4:                           
386                 case 5:                           
387                 case 6:                           
388                 case 7:                           
389                     {                             
390                     Sgl_leftshiftby1(result);     
391                     result_exponent -= 1;         
392                     break;                        
393                     }                             
394                 }                                 
395             if(result_exponent > 0)               
396                 {                                 
397                 Sgl_set_exponent(result,/*usin    
398                 *dstptr = result;                 
399                 return(NOEXCEPTION); /* Sign b    
400                 }                                 
401             /* Fixup potential underflows */      
402           underflow:                              
403             if(Is_underflowtrap_enabled())        
404                 {                                 
405                 Sgl_set_sign(result,sign_save)    
406                 Sgl_setwrapped_exponent(result    
407                 *dstptr = result;                 
408                 /* inexact = FALSE; */            
409                 return(UNDERFLOWEXCEPTION);       
410                 }                                 
411             /*                                    
412              * Since we cannot get an inexact     
413              * we can now return.                 
414              */                                   
415             Sgl_right_align(result,/*by*/(1-re    
416             Sgl_clear_signexponent(result);       
417             Sgl_set_sign(result,sign_save);       
418             *dstptr = result;                     
419             return(NOEXCEPTION);                  
420             } /* end if(hidden...)... */          
421         /* Fall through and round */              
422         } /* end if(save < 0)... */               
423     else                                          
424         {                                         
425         /* Add magnitudes */                      
426         Sgl_addition(left,right,/*to*/result);    
427         if(Sgl_isone_hiddenoverflow(result))      
428             {                                     
429             /* Prenormalization required. */      
430             Sgl_rightshiftby1_withextent(resul    
431             Sgl_arithrightshiftby1(result);       
432             result_exponent++;                    
433             } /* end if hiddenoverflow... */      
434         } /* end else ...add magnitudes... */     
435                                                   
436     /* Round the result.  If the extension is     
437      * exact.  Otherwise round in the correct     
438      * possible. If a postnormalization is nec    
439      * all zeros so no shift is needed. */        
440   round:                                          
441     if(Ext_isnotzero(extent))                     
442         {                                         
443         inexact = TRUE;                           
444         switch(Rounding_mode())                   
445             {                                     
446             case ROUNDNEAREST: /* The default.    
447             if(Ext_isone_sign(extent))            
448                 {                                 
449                 /* at least 1/2 ulp */            
450                 if(Ext_isnotzero_lower(extent)    
451                   Sgl_isone_lowmantissa(result    
452                     {                             
453                     /* either exactly half way    
454                     Sgl_increment(result);        
455                     }                             
456                 }                                 
457             break;                                
458                                                   
459             case ROUNDPLUS:                       
460             if(Sgl_iszero_sign(result))           
461                 {                                 
462                 /* Round up positive results *    
463                 Sgl_increment(result);            
464                 }                                 
465             break;                                
466                                                   
467             case ROUNDMINUS:                      
468             if(Sgl_isone_sign(result))            
469                 {                                 
470                 /* Round down negative results    
471                 Sgl_increment(result);            
472                 }                                 
473                                                   
474             case ROUNDZERO:;                      
475             /* truncate is simple */              
476             } /* end switch... */                 
477         if(Sgl_isone_hiddenoverflow(result)) r    
478         }                                         
479     if(result_exponent == SGL_INFINITY_EXPONEN    
480         {                                         
481         /* Overflow */                            
482         if(Is_overflowtrap_enabled())             
483             {                                     
484             Sgl_setwrapped_exponent(result,res    
485             *dstptr = result;                     
486             if (inexact)                          
487                 if (Is_inexacttrap_enabled())     
488                     return(OVERFLOWEXCEPTION |    
489                 else Set_inexactflag();           
490             return(OVERFLOWEXCEPTION);            
491             }                                     
492         else                                      
493             {                                     
494             Set_overflowflag();                   
495             inexact = TRUE;                       
496             Sgl_setoverflow(result);              
497             }                                     
498         }                                         
499     else Sgl_set_exponent(result,result_expone    
500     *dstptr = result;                             
501     if(inexact)                                   
502         if(Is_inexacttrap_enabled()) return(IN    
503         else Set_inexactflag();                   
504     return(NOEXCEPTION);                          
505     }                                             
506                                                   

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