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

TOMOYO Linux Cross Reference
Linux/arch/m68k/math-emu/fp_arith.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/m68k/math-emu/fp_arith.c (Architecture alpha) and /arch/sparc/math-emu/fp_arith.c (Architecture sparc)


  1 // SPDX-License-Identifier: GPL-2.0-or-later        1 
  2 /*                                                
  3                                                   
  4    fp_arith.c: floating-point math routines fo    
  5    floating point emulator.                       
  6                                                   
  7    Copyright (c) 1998-1999 David Huggins-Daine    
  8                                                   
  9    Somewhat based on the AlphaLinux floating p    
 10    Mosberger-Tang.                                
 11                                                   
 12  */                                               
 13                                                   
 14 #include "fp_emu.h"                               
 15 #include "multi_arith.h"                          
 16 #include "fp_arith.h"                             
 17                                                   
 18 const struct fp_ext fp_QNaN =                     
 19 {                                                 
 20         .exp = 0x7fff,                            
 21         .mant = { .m64 = ~0 }                     
 22 };                                                
 23                                                   
 24 const struct fp_ext fp_Inf =                      
 25 {                                                 
 26         .exp = 0x7fff,                            
 27 };                                                
 28                                                   
 29 /* let's start with the easy ones */              
 30                                                   
 31 struct fp_ext *fp_fabs(struct fp_ext *dest, st    
 32 {                                                 
 33         dprint(PINSTR, "fabs\n");                 
 34                                                   
 35         fp_monadic_check(dest, src);              
 36                                                   
 37         dest->sign = 0;                           
 38                                                   
 39         return dest;                              
 40 }                                                 
 41                                                   
 42 struct fp_ext *fp_fneg(struct fp_ext *dest, st    
 43 {                                                 
 44         dprint(PINSTR, "fneg\n");                 
 45                                                   
 46         fp_monadic_check(dest, src);              
 47                                                   
 48         dest->sign = !dest->sign;                 
 49                                                   
 50         return dest;                              
 51 }                                                 
 52                                                   
 53 /* Now, the slightly harder ones */               
 54                                                   
 55 /* fp_fadd: Implements the kernel of the FADD,    
 56    FDSUB, and FCMP instructions. */               
 57                                                   
 58 struct fp_ext *fp_fadd(struct fp_ext *dest, st    
 59 {                                                 
 60         int diff;                                 
 61                                                   
 62         dprint(PINSTR, "fadd\n");                 
 63                                                   
 64         fp_dyadic_check(dest, src);               
 65                                                   
 66         if (IS_INF(dest)) {                       
 67                 /* infinity - infinity == NaN     
 68                 if (IS_INF(src) && (src->sign     
 69                         fp_set_nan(dest);         
 70                 return dest;                      
 71         }                                         
 72         if (IS_INF(src)) {                        
 73                 fp_copy_ext(dest, src);           
 74                 return dest;                      
 75         }                                         
 76                                                   
 77         if (IS_ZERO(dest)) {                      
 78                 if (IS_ZERO(src)) {               
 79                         if (src->sign != dest-    
 80                                 if (FPDATA->rn    
 81                                         dest->    
 82                                 else              
 83                                         dest->    
 84                         }                         
 85                 } else                            
 86                         fp_copy_ext(dest, src)    
 87                 return dest;                      
 88         }                                         
 89                                                   
 90         dest->lowmant = src->lowmant = 0;         
 91                                                   
 92         if ((diff = dest->exp - src->exp) > 0)    
 93                 fp_denormalize(src, diff);        
 94         else if ((diff = -diff) > 0)              
 95                 fp_denormalize(dest, diff);       
 96                                                   
 97         if (dest->sign == src->sign) {            
 98                 if (fp_addmant(dest, src))        
 99                         if (!fp_addcarry(dest)    
100                                 return dest;      
101         } else {                                  
102                 if (dest->mant.m64 < src->mant    
103                         fp_submant(dest, src,     
104                         dest->sign = !dest->si    
105                 } else                            
106                         fp_submant(dest, dest,    
107         }                                         
108                                                   
109         return dest;                              
110 }                                                 
111                                                   
112 /* fp_fsub: Implements the kernel of the FSUB,    
113    instructions.                                  
114                                                   
115    Remember that the arguments are in assemble    
116                                                   
117 struct fp_ext *fp_fsub(struct fp_ext *dest, st    
118 {                                                 
119         dprint(PINSTR, "fsub ");                  
120                                                   
121         src->sign = !src->sign;                   
122         return fp_fadd(dest, src);                
123 }                                                 
124                                                   
125                                                   
126 struct fp_ext *fp_fcmp(struct fp_ext *dest, st    
127 {                                                 
128         dprint(PINSTR, "fcmp ");                  
129                                                   
130         FPDATA->temp[1] = *dest;                  
131         src->sign = !src->sign;                   
132         return fp_fadd(&FPDATA->temp[1], src);    
133 }                                                 
134                                                   
135 struct fp_ext *fp_ftst(struct fp_ext *dest, st    
136 {                                                 
137         dprint(PINSTR, "ftst\n");                 
138                                                   
139         (void)dest;                               
140                                                   
141         return src;                               
142 }                                                 
143                                                   
144 struct fp_ext *fp_fmul(struct fp_ext *dest, st    
145 {                                                 
146         union fp_mant128 temp;                    
147         int exp;                                  
148                                                   
149         dprint(PINSTR, "fmul\n");                 
150                                                   
151         fp_dyadic_check(dest, src);               
152                                                   
153         /* calculate the correct sign now, as     
154         dest->sign = src->sign ^ dest->sign;      
155                                                   
156         /* Handle infinities */                   
157         if (IS_INF(dest)) {                       
158                 if (IS_ZERO(src))                 
159                         fp_set_nan(dest);         
160                 return dest;                      
161         }                                         
162         if (IS_INF(src)) {                        
163                 if (IS_ZERO(dest))                
164                         fp_set_nan(dest);         
165                 else                              
166                         fp_copy_ext(dest, src)    
167                 return dest;                      
168         }                                         
169                                                   
170         /* Of course, as we all know, zero * a    
171            not have known that it might be a p    
172            zero... */                             
173         if (IS_ZERO(dest) || IS_ZERO(src)) {      
174                 dest->exp = 0;                    
175                 dest->mant.m64 = 0;               
176                 dest->lowmant = 0;                
177                                                   
178                 return dest;                      
179         }                                         
180                                                   
181         exp = dest->exp + src->exp - 0x3ffe;      
182                                                   
183         /* shift up the mantissa for denormali    
184            so that the highest bit is set, thi    
185            shift of the result below easier */    
186         if ((long)dest->mant.m32[0] >= 0)         
187                 exp -= fp_overnormalize(dest);    
188         if ((long)src->mant.m32[0] >= 0)          
189                 exp -= fp_overnormalize(src);     
190                                                   
191         /* now, do a 64-bit multiply with expa    
192         fp_multiplymant(&temp, dest, src);        
193                                                   
194         /* normalize it back to 64 bits and st    
195            destination struct */                  
196         if ((long)temp.m32[0] > 0) {              
197                 exp--;                            
198                 fp_putmant128(dest, &temp, 1);    
199         } else                                    
200                 fp_putmant128(dest, &temp, 0);    
201                                                   
202         if (exp >= 0x7fff) {                      
203                 fp_set_ovrflw(dest);              
204                 return dest;                      
205         }                                         
206         dest->exp = exp;                          
207         if (exp < 0) {                            
208                 fp_set_sr(FPSR_EXC_UNFL);         
209                 fp_denormalize(dest, -exp);       
210         }                                         
211                                                   
212         return dest;                              
213 }                                                 
214                                                   
215 /* fp_fdiv: Implements the "kernel" of the FDI    
216    FSGLDIV instructions.                          
217                                                   
218    Note that the order of the operands is coun    
219    of src / dest, the result is actually dest     
220                                                   
221 struct fp_ext *fp_fdiv(struct fp_ext *dest, st    
222 {                                                 
223         union fp_mant128 temp;                    
224         int exp;                                  
225                                                   
226         dprint(PINSTR, "fdiv\n");                 
227                                                   
228         fp_dyadic_check(dest, src);               
229                                                   
230         /* calculate the correct sign now, as     
231         dest->sign = src->sign ^ dest->sign;      
232                                                   
233         /* Handle infinities */                   
234         if (IS_INF(dest)) {                       
235                 /* infinity / infinity = NaN (    
236                 if (IS_INF(src))                  
237                         fp_set_nan(dest);         
238                 /* infinity / anything else =     
239                 return dest;                      
240         }                                         
241         if (IS_INF(src)) {                        
242                 /* anything / infinity = zero     
243                 dest->exp = 0;                    
244                 dest->mant.m64 = 0;               
245                 dest->lowmant = 0;                
246                                                   
247                 return dest;                      
248         }                                         
249                                                   
250         /* zeroes */                              
251         if (IS_ZERO(dest)) {                      
252                 /* zero / zero = NaN */           
253                 if (IS_ZERO(src))                 
254                         fp_set_nan(dest);         
255                 /* zero / anything else = zero    
256                 return dest;                      
257         }                                         
258         if (IS_ZERO(src)) {                       
259                 /* anything / zero = infinity     
260                 fp_set_sr(FPSR_EXC_DZ);           
261                 dest->exp = 0x7fff;               
262                 dest->mant.m64 = 0;               
263                                                   
264                 return dest;                      
265         }                                         
266                                                   
267         exp = dest->exp - src->exp + 0x3fff;      
268                                                   
269         /* shift up the mantissa for denormali    
270            so that the highest bit is set, thi    
271            of things below easier */              
272         if ((long)dest->mant.m32[0] >= 0)         
273                 exp -= fp_overnormalize(dest);    
274         if ((long)src->mant.m32[0] >= 0)          
275                 exp -= fp_overnormalize(src);     
276                                                   
277         /* now, do the 64-bit divide */           
278         fp_dividemant(&temp, dest, src);          
279                                                   
280         /* normalize it back to 64 bits and st    
281            destination struct */                  
282         if (!temp.m32[0]) {                       
283                 exp--;                            
284                 fp_putmant128(dest, &temp, 32)    
285         } else                                    
286                 fp_putmant128(dest, &temp, 31)    
287                                                   
288         if (exp >= 0x7fff) {                      
289                 fp_set_ovrflw(dest);              
290                 return dest;                      
291         }                                         
292         dest->exp = exp;                          
293         if (exp < 0) {                            
294                 fp_set_sr(FPSR_EXC_UNFL);         
295                 fp_denormalize(dest, -exp);       
296         }                                         
297                                                   
298         return dest;                              
299 }                                                 
300                                                   
301 struct fp_ext *fp_fsglmul(struct fp_ext *dest,    
302 {                                                 
303         int exp;                                  
304                                                   
305         dprint(PINSTR, "fsglmul\n");              
306                                                   
307         fp_dyadic_check(dest, src);               
308                                                   
309         /* calculate the correct sign now, as     
310         dest->sign = src->sign ^ dest->sign;      
311                                                   
312         /* Handle infinities */                   
313         if (IS_INF(dest)) {                       
314                 if (IS_ZERO(src))                 
315                         fp_set_nan(dest);         
316                 return dest;                      
317         }                                         
318         if (IS_INF(src)) {                        
319                 if (IS_ZERO(dest))                
320                         fp_set_nan(dest);         
321                 else                              
322                         fp_copy_ext(dest, src)    
323                 return dest;                      
324         }                                         
325                                                   
326         /* Of course, as we all know, zero * a    
327            not have known that it might be a p    
328            zero... */                             
329         if (IS_ZERO(dest) || IS_ZERO(src)) {      
330                 dest->exp = 0;                    
331                 dest->mant.m64 = 0;               
332                 dest->lowmant = 0;                
333                                                   
334                 return dest;                      
335         }                                         
336                                                   
337         exp = dest->exp + src->exp - 0x3ffe;      
338                                                   
339         /* do a 32-bit multiply */                
340         fp_mul64(dest->mant.m32[0], dest->mant    
341                  dest->mant.m32[0] & 0xffffff0    
342                  src->mant.m32[0] & 0xffffff00    
343                                                   
344         if (exp >= 0x7fff) {                      
345                 fp_set_ovrflw(dest);              
346                 return dest;                      
347         }                                         
348         dest->exp = exp;                          
349         if (exp < 0) {                            
350                 fp_set_sr(FPSR_EXC_UNFL);         
351                 fp_denormalize(dest, -exp);       
352         }                                         
353                                                   
354         return dest;                              
355 }                                                 
356                                                   
357 struct fp_ext *fp_fsgldiv(struct fp_ext *dest,    
358 {                                                 
359         int exp;                                  
360         unsigned long quot, rem;                  
361                                                   
362         dprint(PINSTR, "fsgldiv\n");              
363                                                   
364         fp_dyadic_check(dest, src);               
365                                                   
366         /* calculate the correct sign now, as     
367         dest->sign = src->sign ^ dest->sign;      
368                                                   
369         /* Handle infinities */                   
370         if (IS_INF(dest)) {                       
371                 /* infinity / infinity = NaN (    
372                 if (IS_INF(src))                  
373                         fp_set_nan(dest);         
374                 /* infinity / anything else =     
375                 return dest;                      
376         }                                         
377         if (IS_INF(src)) {                        
378                 /* anything / infinity = zero     
379                 dest->exp = 0;                    
380                 dest->mant.m64 = 0;               
381                 dest->lowmant = 0;                
382                                                   
383                 return dest;                      
384         }                                         
385                                                   
386         /* zeroes */                              
387         if (IS_ZERO(dest)) {                      
388                 /* zero / zero = NaN */           
389                 if (IS_ZERO(src))                 
390                         fp_set_nan(dest);         
391                 /* zero / anything else = zero    
392                 return dest;                      
393         }                                         
394         if (IS_ZERO(src)) {                       
395                 /* anything / zero = infinity     
396                 fp_set_sr(FPSR_EXC_DZ);           
397                 dest->exp = 0x7fff;               
398                 dest->mant.m64 = 0;               
399                                                   
400                 return dest;                      
401         }                                         
402                                                   
403         exp = dest->exp - src->exp + 0x3fff;      
404                                                   
405         dest->mant.m32[0] &= 0xffffff00;          
406         src->mant.m32[0] &= 0xffffff00;           
407                                                   
408         /* do the 32-bit divide */                
409         if (dest->mant.m32[0] >= src->mant.m32    
410                 fp_sub64(dest->mant, src->mant    
411                 fp_div64(quot, rem, dest->mant    
412                 dest->mant.m32[0] = 0x80000000    
413                 dest->mant.m32[1] = (quot & 1)    
414         } else {                                  
415                 fp_div64(quot, rem, dest->mant    
416                 dest->mant.m32[0] = quot;         
417                 dest->mant.m32[1] = rem;          
418                 exp--;                            
419         }                                         
420                                                   
421         if (exp >= 0x7fff) {                      
422                 fp_set_ovrflw(dest);              
423                 return dest;                      
424         }                                         
425         dest->exp = exp;                          
426         if (exp < 0) {                            
427                 fp_set_sr(FPSR_EXC_UNFL);         
428                 fp_denormalize(dest, -exp);       
429         }                                         
430                                                   
431         return dest;                              
432 }                                                 
433                                                   
434 /* fp_roundint: Internal rounding function for    
435    emulated instructions.                         
436                                                   
437    This one rounds off the fractional part usi    
438    specified. */                                  
439                                                   
440 static void fp_roundint(struct fp_ext *dest, i    
441 {                                                 
442         union fp_mant64 oldmant;                  
443         unsigned long mask;                       
444                                                   
445         if (!fp_normalize_ext(dest))              
446                 return;                           
447                                                   
448         /* infinities and zeroes */               
449         if (IS_INF(dest) || IS_ZERO(dest))        
450                 return;                           
451                                                   
452         /* first truncate the lower bits */       
453         oldmant = dest->mant;                     
454         switch (dest->exp) {                      
455         case 0 ... 0x3ffe:                        
456                 dest->mant.m64 = 0;               
457                 break;                            
458         case 0x3fff ... 0x401e:                   
459                 dest->mant.m32[0] &= 0xfffffff    
460                 dest->mant.m32[1] = 0;            
461                 if (oldmant.m64 == dest->mant.    
462                         return;                   
463                 break;                            
464         case 0x401f ... 0x403e:                   
465                 dest->mant.m32[1] &= 0xfffffff    
466                 if (oldmant.m32[1] == dest->ma    
467                         return;                   
468                 break;                            
469         default:                                  
470                 return;                           
471         }                                         
472         fp_set_sr(FPSR_EXC_INEX2);                
473                                                   
474         /* We might want to normalize upwards     
475            we know that this is only called on    
476            or with the input to fp_fint or fp_    
477            to all these functions are either n    
478            (no subnormals allowed!), there's r    
479                                                   
480            In the case of fp_fdiv, observe tha    
481            0xffff8000, and the same holds for     
482            smallest possible normal dividend a    
483            divisor will still produce a normal    
484            << 64) / normal is normal in all ca    
485                                                   
486         switch (mode) {                           
487         case FPCR_ROUND_RN:                       
488                 switch (dest->exp) {              
489                 case 0 ... 0x3ffd:                
490                         return;                   
491                 case 0x3ffe:                      
492                         /* As noted above, the    
493                            guard bit (bit 63)     
494                            only case in which     
495                            the input is exactl    
496                         if (oldmant.m64 == (1U    
497                                 return;           
498                         break;                    
499                 case 0x3fff ... 0x401d:           
500                         mask = 1 << (0x401d -     
501                         if (!(oldmant.m32[0] &    
502                                 return;           
503                         if (oldmant.m32[0] & (    
504                                 break;            
505                         if (!(oldmant.m32[0] <    
506                                         !oldma    
507                                 return;           
508                         break;                    
509                 case 0x401e:                      
510                         if (oldmant.m32[1] & 0    
511                                 return;           
512                         if (oldmant.m32[0] & 1    
513                                 break;            
514                         if (!(oldmant.m32[1] <    
515                                 return;           
516                         break;                    
517                 case 0x401f ... 0x403d:           
518                         mask = 1 << (0x403d -     
519                         if (!(oldmant.m32[1] &    
520                                 return;           
521                         if (oldmant.m32[1] & (    
522                                 break;            
523                         if (!(oldmant.m32[1] <    
524                                 return;           
525                         break;                    
526                 default:                          
527                         return;                   
528                 }                                 
529                 break;                            
530         case FPCR_ROUND_RZ:                       
531                 return;                           
532         default:                                  
533                 if (dest->sign ^ (mode - FPCR_    
534                         break;                    
535                 return;                           
536         }                                         
537                                                   
538         switch (dest->exp) {                      
539         case 0 ... 0x3ffe:                        
540                 dest->exp = 0x3fff;               
541                 dest->mant.m64 = 1ULL << 63;      
542                 break;                            
543         case 0x3fff ... 0x401e:                   
544                 mask = 1 << (0x401e - dest->ex    
545                 if (dest->mant.m32[0] += mask)    
546                         break;                    
547                 dest->mant.m32[0] = 0x80000000    
548                 dest->exp++;                      
549                 break;                            
550         case 0x401f ... 0x403e:                   
551                 mask = 1 << (0x403e - dest->ex    
552                 if (dest->mant.m32[1] += mask)    
553                         break;                    
554                 if (dest->mant.m32[0] += 1)       
555                         break;                    
556                 dest->mant.m32[0] = 0x80000000    
557                 dest->exp++;                      
558                 break;                            
559         }                                         
560 }                                                 
561                                                   
562 /* modrem_kernel: Implementation of the FREM a    
563    (which are exactly the same, except for the    
564    intermediate value) */                         
565                                                   
566 static struct fp_ext *modrem_kernel(struct fp_    
567                                     int mode)     
568 {                                                 
569         struct fp_ext tmp;                        
570                                                   
571         fp_dyadic_check(dest, src);               
572                                                   
573         /* Infinities and zeros */                
574         if (IS_INF(dest) || IS_ZERO(src)) {       
575                 fp_set_nan(dest);                 
576                 return dest;                      
577         }                                         
578         if (IS_ZERO(dest) || IS_INF(src))         
579                 return dest;                      
580                                                   
581         /* FIXME: there is almost certainly a     
582         fp_copy_ext(&tmp, dest);                  
583         fp_fdiv(&tmp, src);             /* NOT    
584         fp_roundint(&tmp, mode);                  
585         fp_fmul(&tmp, src);                       
586         fp_fsub(dest, &tmp);                      
587                                                   
588         /* set the quotient byte */               
589         fp_set_quotient((dest->mant.m64 & 0x7f    
590         return dest;                              
591 }                                                 
592                                                   
593 /* fp_fmod: Implements the kernel of the FMOD     
594                                                   
595    Again, the argument order is backwards.  Th    
596    the Motorola manuals, is:                      
597                                                   
598    fmod(src,dest) = (dest - (src * floor(dest     
599                                                   
600 struct fp_ext *fp_fmod(struct fp_ext *dest, st    
601 {                                                 
602         dprint(PINSTR, "fmod\n");                 
603         return modrem_kernel(dest, src, FPCR_R    
604 }                                                 
605                                                   
606 /* fp_frem: Implements the kernel of the FREM     
607                                                   
608    frem(src,dest) = (dest - (src * round(dest     
609  */                                               
610                                                   
611 struct fp_ext *fp_frem(struct fp_ext *dest, st    
612 {                                                 
613         dprint(PINSTR, "frem\n");                 
614         return modrem_kernel(dest, src, FPCR_R    
615 }                                                 
616                                                   
617 struct fp_ext *fp_fint(struct fp_ext *dest, st    
618 {                                                 
619         dprint(PINSTR, "fint\n");                 
620                                                   
621         fp_copy_ext(dest, src);                   
622                                                   
623         fp_roundint(dest, FPDATA->rnd);           
624                                                   
625         return dest;                              
626 }                                                 
627                                                   
628 struct fp_ext *fp_fintrz(struct fp_ext *dest,     
629 {                                                 
630         dprint(PINSTR, "fintrz\n");               
631                                                   
632         fp_copy_ext(dest, src);                   
633                                                   
634         fp_roundint(dest, FPCR_ROUND_RZ);         
635                                                   
636         return dest;                              
637 }                                                 
638                                                   
639 struct fp_ext *fp_fscale(struct fp_ext *dest,     
640 {                                                 
641         int scale, oldround;                      
642                                                   
643         dprint(PINSTR, "fscale\n");               
644                                                   
645         fp_dyadic_check(dest, src);               
646                                                   
647         /* Infinities */                          
648         if (IS_INF(src)) {                        
649                 fp_set_nan(dest);                 
650                 return dest;                      
651         }                                         
652         if (IS_INF(dest))                         
653                 return dest;                      
654                                                   
655         /* zeroes */                              
656         if (IS_ZERO(src) || IS_ZERO(dest))        
657                 return dest;                      
658                                                   
659         /* Source exponent out of range */        
660         if (src->exp >= 0x400c) {                 
661                 fp_set_ovrflw(dest);              
662                 return dest;                      
663         }                                         
664                                                   
665         /* src must be rounded with round to z    
666         oldround = FPDATA->rnd;                   
667         FPDATA->rnd = FPCR_ROUND_RZ;              
668         scale = fp_conv_ext2long(src);            
669         FPDATA->rnd = oldround;                   
670                                                   
671         /* new exponent */                        
672         scale += dest->exp;                       
673                                                   
674         if (scale >= 0x7fff) {                    
675                 fp_set_ovrflw(dest);              
676         } else if (scale <= 0) {                  
677                 fp_set_sr(FPSR_EXC_UNFL);         
678                 fp_denormalize(dest, -scale);     
679         } else                                    
680                 dest->exp = scale;                
681                                                   
682         return dest;                              
683 }                                                 
684                                                   
685                                                   

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