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

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

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