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

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

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ 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/fcnvff.c              $Revision: 1.1 $
 13  *
 14  *  Purpose:
 15  *      Single Floating-point to Double Floating-point
 16  *      Double Floating-point to Single Floating-point
 17  *
 18  *  External Interfaces:
 19  *      dbl_to_sgl_fcnvff(srcptr,_nullptr,dstptr,status)
 20  *      sgl_to_dbl_fcnvff(srcptr,_nullptr,dstptr,status)
 21  *
 22  *  Internal Interfaces:
 23  *
 24  *  Theory:
 25  *      <<please update with a overview of the operation of this file>>
 26  *
 27  * END_DESC
 28 */
 29 
 30 
 31 #include "float.h"
 32 #include "sgl_float.h"
 33 #include "dbl_float.h"
 34 #include "cnv_float.h"
 35 
 36 /*
 37  *  Single Floating-point to Double Floating-point 
 38  */
 39 /*ARGSUSED*/
 40 int
 41 sgl_to_dbl_fcnvff(
 42             sgl_floating_point *srcptr,
 43             unsigned int *_nullptr,
 44             dbl_floating_point *dstptr,
 45             unsigned int *status)
 46 {
 47         register unsigned int src, resultp1, resultp2;
 48         register int src_exponent;
 49 
 50         src = *srcptr;
 51         src_exponent = Sgl_exponent(src);
 52         Dbl_allp1(resultp1) = Sgl_all(src);  /* set sign of result */
 53         /* 
 54          * Test for NaN or infinity
 55          */
 56         if (src_exponent == SGL_INFINITY_EXPONENT) {
 57                 /*
 58                  * determine if NaN or infinity
 59                  */
 60                 if (Sgl_iszero_mantissa(src)) {
 61                         /*
 62                          * is infinity; want to return double infinity
 63                          */
 64                         Dbl_setinfinity_exponentmantissa(resultp1,resultp2);
 65                         Dbl_copytoptr(resultp1,resultp2,dstptr);
 66                         return(NOEXCEPTION);
 67                 }
 68                 else {
 69                         /* 
 70                          * is NaN; signaling or quiet?
 71                          */
 72                         if (Sgl_isone_signaling(src)) {
 73                                 /* trap if INVALIDTRAP enabled */
 74                                 if (Is_invalidtrap_enabled())
 75                                         return(INVALIDEXCEPTION);
 76                                 /* make NaN quiet */
 77                                 else {
 78                                         Set_invalidflag();
 79                                         Sgl_set_quiet(src);
 80                                 }
 81                         }
 82                         /* 
 83                          * NaN is quiet, return as double NaN 
 84                          */
 85                         Dbl_setinfinity_exponent(resultp1);
 86                         Sgl_to_dbl_mantissa(src,resultp1,resultp2);
 87                         Dbl_copytoptr(resultp1,resultp2,dstptr);
 88                         return(NOEXCEPTION);
 89                 }
 90         }
 91         /* 
 92          * Test for zero or denormalized
 93          */
 94         if (src_exponent == 0) {
 95                 /*
 96                  * determine if zero or denormalized
 97                  */
 98                 if (Sgl_isnotzero_mantissa(src)) {
 99                         /*
100                          * is denormalized; want to normalize
101                          */
102                         Sgl_clear_signexponent(src);
103                         Sgl_leftshiftby1(src);
104                         Sgl_normalize(src,src_exponent);
105                         Sgl_to_dbl_exponent(src_exponent,resultp1);
106                         Sgl_to_dbl_mantissa(src,resultp1,resultp2);
107                 }
108                 else {
109                         Dbl_setzero_exponentmantissa(resultp1,resultp2);
110                 }
111                 Dbl_copytoptr(resultp1,resultp2,dstptr);
112                 return(NOEXCEPTION);
113         }
114         /*
115          * No special cases, just complete the conversion
116          */
117         Sgl_to_dbl_exponent(src_exponent, resultp1);
118         Sgl_to_dbl_mantissa(Sgl_mantissa(src), resultp1,resultp2);
119         Dbl_copytoptr(resultp1,resultp2,dstptr);
120         return(NOEXCEPTION);
121 }
122 
123 /*
124  *  Double Floating-point to Single Floating-point 
125  */
126 /*ARGSUSED*/
127 int
128 dbl_to_sgl_fcnvff(
129                     dbl_floating_point *srcptr,
130                     unsigned int *_nullptr,
131                     sgl_floating_point *dstptr,
132                     unsigned int *status)
133 {
134         register unsigned int srcp1, srcp2, result;
135         register int src_exponent, dest_exponent, dest_mantissa;
136         register boolean inexact = FALSE, guardbit = FALSE, stickybit = FALSE;
137         register boolean lsb_odd = FALSE;
138         boolean is_tiny = FALSE;
139 
140         Dbl_copyfromptr(srcptr,srcp1,srcp2);
141         src_exponent = Dbl_exponent(srcp1);
142         Sgl_all(result) = Dbl_allp1(srcp1);  /* set sign of result */
143         /* 
144          * Test for NaN or infinity
145          */
146         if (src_exponent == DBL_INFINITY_EXPONENT) {
147                 /*
148                  * determine if NaN or infinity
149                  */
150                 if (Dbl_iszero_mantissa(srcp1,srcp2)) {
151                         /*
152                          * is infinity; want to return single infinity
153                          */
154                         Sgl_setinfinity_exponentmantissa(result);
155                         *dstptr = result;
156                         return(NOEXCEPTION);
157                 }
158                 /* 
159                  * is NaN; signaling or quiet?
160                  */
161                 if (Dbl_isone_signaling(srcp1)) {
162                         /* trap if INVALIDTRAP enabled */
163                         if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION);
164                         else {
165                                 Set_invalidflag();
166                                 /* make NaN quiet */
167                                 Dbl_set_quiet(srcp1);
168                         }
169                 }
170                 /* 
171                  * NaN is quiet, return as single NaN 
172                  */
173                 Sgl_setinfinity_exponent(result);
174                 Sgl_set_mantissa(result,Dallp1(srcp1)<<3 | Dallp2(srcp2)>>29);
175                 if (Sgl_iszero_mantissa(result)) Sgl_set_quiet(result);
176                 *dstptr = result;
177                 return(NOEXCEPTION);
178         }
179         /*
180          * Generate result
181          */
182         Dbl_to_sgl_exponent(src_exponent,dest_exponent);
183         if (dest_exponent > 0) {
184                 Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,guardbit, 
185                 stickybit,lsb_odd);
186         }
187         else {
188                 if (Dbl_iszero_exponentmantissa(srcp1,srcp2)){
189                         Sgl_setzero_exponentmantissa(result);
190                         *dstptr = result;
191                         return(NOEXCEPTION);
192                 }
193                 if (Is_underflowtrap_enabled()) {
194                         Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact,
195                         guardbit,stickybit,lsb_odd);
196                 }
197                 else {
198                         /* compute result, determine inexact info,
199                          * and set Underflowflag if appropriate
200                          */
201                         Dbl_to_sgl_denormalized(srcp1,srcp2,dest_exponent,
202                         dest_mantissa,inexact,guardbit,stickybit,lsb_odd,
203                         is_tiny);
204                 }
205         }
206         /* 
207          * Now round result if not exact
208          */
209         if (inexact) {
210                 switch (Rounding_mode()) {
211                         case ROUNDPLUS: 
212                                 if (Sgl_iszero_sign(result)) dest_mantissa++;
213                                 break;
214                         case ROUNDMINUS: 
215                                 if (Sgl_isone_sign(result)) dest_mantissa++;
216                                 break;
217                         case ROUNDNEAREST:
218                                 if (guardbit) {
219                                    if (stickybit || lsb_odd) dest_mantissa++;
220                                    }
221                 }
222         }
223         Sgl_set_exponentmantissa(result,dest_mantissa);
224 
225         /*
226          * check for mantissa overflow after rounding
227          */
228         if ((dest_exponent>0 || Is_underflowtrap_enabled()) && 
229             Sgl_isone_hidden(result)) dest_exponent++;
230 
231         /* 
232          * Test for overflow
233          */
234         if (dest_exponent >= SGL_INFINITY_EXPONENT) {
235                 /* trap if OVERFLOWTRAP enabled */
236                 if (Is_overflowtrap_enabled()) {
237                         /* 
238                          * Check for gross overflow
239                          */
240                         if (dest_exponent >= SGL_INFINITY_EXPONENT+SGL_WRAP) 
241                                 return(UNIMPLEMENTEDEXCEPTION);
242                         
243                         /*
244                          * Adjust bias of result
245                          */
246                         Sgl_setwrapped_exponent(result,dest_exponent,ovfl);
247                         *dstptr = result;
248                         if (inexact) 
249                             if (Is_inexacttrap_enabled())
250                                 return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
251                             else Set_inexactflag();
252                         return(OVERFLOWEXCEPTION);
253                 }
254                 Set_overflowflag();
255                 inexact = TRUE;
256                 /* set result to infinity or largest number */
257                 Sgl_setoverflow(result);
258         }
259         /* 
260          * Test for underflow
261          */
262         else if (dest_exponent <= 0) {
263                 /* trap if UNDERFLOWTRAP enabled */
264                 if (Is_underflowtrap_enabled()) {
265                         /* 
266                          * Check for gross underflow
267                          */
268                         if (dest_exponent <= -(SGL_WRAP))
269                                 return(UNIMPLEMENTEDEXCEPTION);
270                         /*
271                          * Adjust bias of result
272                          */
273                         Sgl_setwrapped_exponent(result,dest_exponent,unfl);
274                         *dstptr = result;
275                         if (inexact) 
276                             if (Is_inexacttrap_enabled())
277                                 return(UNDERFLOWEXCEPTION|INEXACTEXCEPTION);
278                             else Set_inexactflag();
279                         return(UNDERFLOWEXCEPTION);
280                 }
281                  /* 
282                   * result is denormalized or signed zero
283                   */
284                if (inexact && is_tiny) Set_underflowflag();
285 
286         }
287         else Sgl_set_exponent(result,dest_exponent);
288         *dstptr = result;
289         /* 
290          * Trap if inexact trap is enabled
291          */
292         if (inexact)
293                 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
294                 else Set_inexactflag();
295         return(NOEXCEPTION);
296 }
297 

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