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

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

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ 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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * Linux/PA-RISC Project (http://www.parisc-linux.org/)
  4  *
  5  * Floating-point emulation code
  6  *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
  7  */
  8 /*
  9  * BEGIN_DESC
 10  *
 11  *  File:
 12  *      @(#)    pa/spmath/fcnvfu.c              $Revision: 1.1 $
 13  *
 14  *  Purpose:
 15  *      Floating-point to Unsigned Fixed-point Converts
 16  *
 17  *  External Interfaces:
 18  *      dbl_to_dbl_fcnvfu(srcptr,_nullptr,dstptr,status)
 19  *      dbl_to_sgl_fcnvfu(srcptr,_nullptr,dstptr,status)
 20  *      sgl_to_dbl_fcnvfu(srcptr,_nullptr,dstptr,status)
 21  *      sgl_to_sgl_fcnvfu(srcptr,_nullptr,dstptr,status)
 22  *
 23  *  Internal Interfaces:
 24  *
 25  *  Theory:
 26  *      <<please update with a overview of the operation of this file>>
 27  *
 28  * END_DESC
 29 */
 30 
 31 
 32 #include "float.h"
 33 #include "sgl_float.h"
 34 #include "dbl_float.h"
 35 #include "cnv_float.h"
 36 
 37 /************************************************************************
 38  *  Floating-point to Unsigned Fixed-point Converts                     *
 39  ************************************************************************/
 40 
 41 /*
 42  *  Single Floating-point to Single Unsigned Fixed 
 43  */
 44 /*ARGSUSED*/
 45 int
 46 sgl_to_sgl_fcnvfu(
 47                         sgl_floating_point *srcptr,
 48                         unsigned int *_nullptr,
 49                         unsigned int *dstptr,
 50                         unsigned int *status)
 51 {
 52         register unsigned int src, result;
 53         register int src_exponent;
 54         register boolean inexact = FALSE;
 55 
 56         src = *srcptr;
 57         src_exponent = Sgl_exponent(src) - SGL_BIAS;
 58 
 59         /* 
 60          * Test for overflow
 61          */
 62         if (src_exponent > SGL_FX_MAX_EXP + 1) {
 63                 if (Sgl_isone_sign(src)) {
 64                         result = 0;
 65                 } else {
 66                         result = 0xffffffff;
 67                 }
 68                 if (Is_invalidtrap_enabled()) {
 69                         return(INVALIDEXCEPTION);
 70                 }
 71                 Set_invalidflag();
 72                 *dstptr = result;
 73                 return(NOEXCEPTION);
 74         }
 75         /*
 76          * Generate result
 77          */
 78         if (src_exponent >= 0) {
 79                 /* 
 80                  * Check sign.
 81                  * If negative, trap unimplemented.
 82                  */
 83                 if (Sgl_isone_sign(src)) {
 84                         result = 0;
 85                         if (Is_invalidtrap_enabled()) {
 86                                 return(INVALIDEXCEPTION);
 87                         }
 88                         Set_invalidflag();
 89                         *dstptr = result;
 90                         return(NOEXCEPTION);
 91                 }
 92                 Sgl_clear_signexponent_set_hidden(src);
 93                 Suint_from_sgl_mantissa(src,src_exponent,result);
 94 
 95                 /* check for inexact */
 96                 if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
 97                         inexact = TRUE;
 98                         /*  round result  */
 99                         switch (Rounding_mode()) {
100                         case ROUNDPLUS:
101                                 result++;
102                                 break;
103                         case ROUNDMINUS: /* never negative */
104                                 break;
105                         case ROUNDNEAREST:
106                                 if (Sgl_isone_roundbit(src,src_exponent) &&
107                                     (Sgl_isone_stickybit(src,src_exponent) ||
108                                      (result & 1))) {
109                                         result++;
110                                 }
111                                 break;
112                         }
113                 }
114         } else {
115                 result = 0;
116 
117                 /* check for inexact */
118                 if (Sgl_isnotzero_exponentmantissa(src)) {
119                         inexact = TRUE;
120                         /*  round result  */
121                         switch (Rounding_mode()) {
122                         case ROUNDPLUS:
123                                 if (Sgl_iszero_sign(src)) {
124                                         result++;
125                                 }
126                                 break;
127                         case ROUNDMINUS:
128                                 if (Sgl_isone_sign(src)) {
129                                         result = 0;
130                                         if (Is_invalidtrap_enabled()) {
131                                                 return(INVALIDEXCEPTION);
132                                         }
133                                         Set_invalidflag();
134                                         inexact = FALSE;
135                                 }
136                                 break;
137                         case ROUNDNEAREST:
138                                 if (src_exponent == -1 &&
139                                     Sgl_isnotzero_mantissa(src)) {
140                                         if (Sgl_isone_sign(src)) {
141                                                 result = 0;
142                                                 if (Is_invalidtrap_enabled()) {
143                                                         return(INVALIDEXCEPTION);
144                                                 }
145                                                 Set_invalidflag();
146                                                 inexact = FALSE;
147                                         }
148                                         else result++;
149                                 }
150                                 break;
151                         }
152                 }
153         }
154         *dstptr = result;
155         if (inexact) {
156                 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
157                 else Set_inexactflag();
158         }
159         return(NOEXCEPTION);
160 }
161 
162 /*
163  *  Single Floating-point to Double Unsigned Fixed 
164  */
165 /*ARGSUSED*/
166 int
167 sgl_to_dbl_fcnvfu(
168                     sgl_floating_point *srcptr,
169                     unsigned int *_nullptr,
170                     dbl_unsigned *dstptr,
171                     unsigned int *status)
172 {
173         register int src_exponent;
174         register unsigned int src, resultp1, resultp2;
175         register boolean inexact = FALSE;
176 
177         src = *srcptr;
178         src_exponent = Sgl_exponent(src) - SGL_BIAS;
179 
180         /* 
181          * Test for overflow
182          */
183         if (src_exponent > DBL_FX_MAX_EXP + 1) {
184                 if (Sgl_isone_sign(src)) {
185                         resultp1 = resultp2 = 0;
186                 } else {
187                         resultp1 = resultp2 = 0xffffffff;
188                 }
189                 if (Is_invalidtrap_enabled()) {
190                         return(INVALIDEXCEPTION);
191                 }
192                 Set_invalidflag();
193                 Duint_copytoptr(resultp1,resultp2,dstptr);
194                 return(NOEXCEPTION);
195         }
196         /*
197          * Generate result
198          */
199         if (src_exponent >= 0) {
200                 /* 
201                  * Check sign.
202                  * If negative, trap unimplemented.
203                  */
204                 if (Sgl_isone_sign(src)) {
205                         resultp1 = resultp2 = 0;
206                         if (Is_invalidtrap_enabled()) {
207                                 return(INVALIDEXCEPTION);
208                         }
209                         Set_invalidflag();
210                         Duint_copytoptr(resultp1,resultp2,dstptr);
211                         return(NOEXCEPTION);
212                 }
213                 Sgl_clear_signexponent_set_hidden(src);
214                 Duint_from_sgl_mantissa(src,src_exponent,resultp1,resultp2);
215 
216                 /* check for inexact */
217                 if (Sgl_isinexact_to_unsigned(src,src_exponent)) {
218                         inexact = TRUE;
219                         /*  round result  */
220                         switch (Rounding_mode()) {
221                         case ROUNDPLUS:
222                                 Duint_increment(resultp1,resultp2);
223                                 break;
224                         case ROUNDMINUS: /* never negative */
225                                 break;
226                         case ROUNDNEAREST:
227                                 if (Sgl_isone_roundbit(src,src_exponent) &&
228                                     (Sgl_isone_stickybit(src,src_exponent) || 
229                                      Duint_isone_lowp2(resultp2))) {
230                                         Duint_increment(resultp1,resultp2);
231                                 }
232                                 break;
233                         }
234                 }
235         } else {
236                 Duint_setzero(resultp1,resultp2);
237 
238                 /* check for inexact */
239                 if (Sgl_isnotzero_exponentmantissa(src)) {
240                         inexact = TRUE;
241                         /*  round result  */
242                         switch (Rounding_mode()) {
243                         case ROUNDPLUS:
244                                 if (Sgl_iszero_sign(src)) {
245                                         Duint_increment(resultp1,resultp2);
246                                 }
247                                 break;
248                         case ROUNDMINUS:
249                                 if (Sgl_isone_sign(src)) {
250                                         resultp1 = resultp2 = 0;
251                                         if (Is_invalidtrap_enabled()) {
252                                                 return(INVALIDEXCEPTION);
253                                         }
254                                         Set_invalidflag();
255                                         inexact = FALSE;
256                                 }
257                                 break;
258                         case ROUNDNEAREST:
259                                 if (src_exponent == -1 &&
260                                     Sgl_isnotzero_mantissa(src)) {
261                                         if (Sgl_isone_sign(src)) {
262                                                 resultp1 = 0;
263                                                 resultp2 = 0;
264                                                 if (Is_invalidtrap_enabled()) {
265                                                         return(INVALIDEXCEPTION);
266                                                 }
267                                                 Set_invalidflag();
268                                                 inexact = FALSE;
269                                         }
270                                         else Duint_increment(resultp1,resultp2);
271                                 }
272                         }
273                 }
274         }
275         Duint_copytoptr(resultp1,resultp2,dstptr);
276         if (inexact) {
277                 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
278                 else Set_inexactflag();
279         }
280         return(NOEXCEPTION);
281 }
282 
283 /*
284  *  Double Floating-point to Single Unsigned Fixed 
285  */
286 /*ARGSUSED*/
287 int
288 dbl_to_sgl_fcnvfu (dbl_floating_point * srcptr, unsigned int *_nullptr,
289                    unsigned int *dstptr, unsigned int *status)
290 {
291         register unsigned int srcp1, srcp2, result;
292         register int src_exponent;
293         register boolean inexact = FALSE;
294 
295         Dbl_copyfromptr(srcptr,srcp1,srcp2);
296         src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
297 
298         /* 
299          * Test for overflow
300          */
301         if (src_exponent > SGL_FX_MAX_EXP + 1) {
302                 if (Dbl_isone_sign(srcp1)) {
303                         result = 0;
304                 } else {
305                         result = 0xffffffff;
306                 }
307                 if (Is_invalidtrap_enabled()) {
308                         return(INVALIDEXCEPTION);
309                 }
310                 Set_invalidflag();
311                 *dstptr = result;
312                 return(NOEXCEPTION);
313         }
314         /*
315          * Generate result
316          */
317         if (src_exponent >= 0) {
318                 /* 
319                  * Check sign.
320                  * If negative, trap unimplemented.
321                  */
322                 if (Dbl_isone_sign(srcp1)) {
323                         result = 0;
324                         if (Is_invalidtrap_enabled()) {
325                                 return(INVALIDEXCEPTION);
326                         }
327                         Set_invalidflag();
328                         *dstptr = result;
329                         return(NOEXCEPTION);
330                 }
331                 Dbl_clear_signexponent_set_hidden(srcp1);
332                 Suint_from_dbl_mantissa(srcp1,srcp2,src_exponent,result);
333 
334                 /* check for inexact */
335                 if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
336                         inexact = TRUE;
337                         /*  round result  */
338                         switch (Rounding_mode()) {
339                         case ROUNDPLUS:
340                              result++;
341                              break;
342                         case ROUNDMINUS: /* never negative */
343                              break;
344                         case ROUNDNEAREST:
345                              if(Dbl_isone_roundbit(srcp1,srcp2,src_exponent) &&
346                                 (Dbl_isone_stickybit(srcp1,srcp2,src_exponent)||
347                                  result&1))
348                                    result++;
349                              break;
350                         }
351                         /* check for overflow */
352                         if (result == 0) {
353                                 result = 0xffffffff;
354                                 if (Is_invalidtrap_enabled()) {
355                                         return(INVALIDEXCEPTION);
356                                 }
357                                 Set_invalidflag();
358                                 *dstptr = result;
359                                 return(NOEXCEPTION);
360                         }
361                 }
362         } else {
363                 result = 0;
364 
365                 /* check for inexact */
366                 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
367                         inexact = TRUE;
368                         /*  round result  */
369                         switch (Rounding_mode()) {
370                         case ROUNDPLUS:
371                                 if (Dbl_iszero_sign(srcp1)) result++;
372                                 break;
373                         case ROUNDMINUS:
374                                 if (Dbl_isone_sign(srcp1)) {
375                                         result = 0;
376                                         if (Is_invalidtrap_enabled()) {
377                                                 return(INVALIDEXCEPTION);
378                                         }
379                                         Set_invalidflag();
380                                         inexact = FALSE;
381                                 }
382                                 break;
383                         case ROUNDNEAREST:
384                                 if (src_exponent == -1 &&
385                                     Dbl_isnotzero_mantissa(srcp1,srcp2))
386                                         if (Dbl_isone_sign(srcp1)) {
387                                                 result = 0;
388                                                 if (Is_invalidtrap_enabled()) {
389                                                         return(INVALIDEXCEPTION);
390                                                 }
391                                                 Set_invalidflag();
392                                                 inexact = FALSE;
393                                         }
394                                         else result++;
395                         }
396                 }
397         }
398         *dstptr = result;
399         if (inexact) {
400                 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
401                 else Set_inexactflag();
402         }
403         return(NOEXCEPTION);
404 }
405 
406 /*
407  *  Double Floating-point to Double Unsigned Fixed 
408  */
409 /*ARGSUSED*/
410 int
411 dbl_to_dbl_fcnvfu (dbl_floating_point * srcptr, unsigned int *_nullptr,
412                    dbl_unsigned * dstptr, unsigned int *status)
413 {
414         register int src_exponent;
415         register unsigned int srcp1, srcp2, resultp1, resultp2;
416         register boolean inexact = FALSE;
417 
418         Dbl_copyfromptr(srcptr,srcp1,srcp2);
419         src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
420 
421         /* 
422          * Test for overflow
423          */
424         if (src_exponent > DBL_FX_MAX_EXP + 1) {
425                 if (Dbl_isone_sign(srcp1)) {
426                         resultp1 = resultp2 = 0;
427                 } else {
428                         resultp1 = resultp2 = 0xffffffff;
429                 }
430                 if (Is_invalidtrap_enabled()) {
431                         return(INVALIDEXCEPTION);
432                 }
433                 Set_invalidflag();
434                 Duint_copytoptr(resultp1,resultp2,dstptr);
435                 return(NOEXCEPTION);
436         }
437  
438         /*
439          * Generate result
440          */
441         if (src_exponent >= 0) {
442                 /* 
443                  * Check sign.
444                  * If negative, trap unimplemented.
445                  */
446                 if (Dbl_isone_sign(srcp1)) {
447                         resultp1 = resultp2 = 0;
448                         if (Is_invalidtrap_enabled()) {
449                                 return(INVALIDEXCEPTION);
450                         }
451                         Set_invalidflag();
452                         Duint_copytoptr(resultp1,resultp2,dstptr);
453                         return(NOEXCEPTION);
454                 }
455                 Dbl_clear_signexponent_set_hidden(srcp1);
456                 Duint_from_dbl_mantissa(srcp1,srcp2,src_exponent,resultp1,
457                   resultp2);
458 
459                 /* check for inexact */
460                 if (Dbl_isinexact_to_unsigned(srcp1,srcp2,src_exponent)) {
461                         inexact = TRUE;
462                         /*  round result  */
463                         switch (Rounding_mode()) {
464                         case ROUNDPLUS:
465                                 Duint_increment(resultp1,resultp2);
466                                 break;
467                         case ROUNDMINUS: /* never negative */
468                                 break;
469                         case ROUNDNEAREST:
470                                 if(Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
471                                   if(Dbl_isone_stickybit(srcp1,srcp2,src_exponent) || 
472                                      Duint_isone_lowp2(resultp2))
473                                         Duint_increment(resultp1,resultp2);
474                         } 
475                 }
476         } else {
477                 Duint_setzero(resultp1,resultp2);
478 
479                 /* check for inexact */
480                 if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
481                         inexact = TRUE;
482                         /*  round result  */
483                         switch (Rounding_mode()) {
484                         case ROUNDPLUS:
485                                 if (Dbl_iszero_sign(srcp1)) {
486                                         Duint_increment(resultp1,resultp2);
487                                 }
488                                 break;
489                         case ROUNDMINUS:
490                                 if (Dbl_isone_sign(srcp1)) {
491                                         resultp1 = resultp2 = 0;
492                                         if (Is_invalidtrap_enabled()) {
493                                                 return(INVALIDEXCEPTION);
494                                         }
495                                         Set_invalidflag();
496                                         inexact = FALSE;
497                                 }
498                                 break;
499                         case ROUNDNEAREST:
500                                 if (src_exponent == -1 &&
501                                     Dbl_isnotzero_mantissa(srcp1,srcp2))
502                                         if (Dbl_iszero_sign(srcp1)) {
503                                                 Duint_increment(resultp1,resultp2);
504                                         } else {
505                                                 resultp1 = 0;
506                                                 resultp2 = 0;
507                                                 if (Is_invalidtrap_enabled()) {
508                                                         return(INVALIDEXCEPTION);
509                                                 }
510                                                 Set_invalidflag();
511                                                 inexact = FALSE;
512                                         }
513                         }
514                 }
515         }
516         Duint_copytoptr(resultp1,resultp2,dstptr);
517         if (inexact) {
518                 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
519                 else Set_inexactflag();
520         }
521         return(NOEXCEPTION);
522 }
523 
524 

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