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

TOMOYO Linux Cross Reference
Linux/arch/parisc/math-emu/fcnvxf.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/fcnvxf.c              $Revision: 1.1 $
 13  *
 14  *  Purpose:
 15  *      Single Fixed-point to Single Floating-point
 16  *      Single Fixed-point to Double Floating-point 
 17  *      Double Fixed-point to Single Floating-point 
 18  *      Double Fixed-point to Double Floating-point 
 19  *
 20  *  External Interfaces:
 21  *      dbl_to_dbl_fcnvxf(srcptr,_nullptr,dstptr,status)
 22  *      dbl_to_sgl_fcnvxf(srcptr,_nullptr,dstptr,status)
 23  *      sgl_to_dbl_fcnvxf(srcptr,_nullptr,dstptr,status)
 24  *      sgl_to_sgl_fcnvxf(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  *  Convert single fixed-point to single floating-point format
 42  */
 43 
 44 int
 45 sgl_to_sgl_fcnvxf(
 46                     int *srcptr,
 47                     unsigned int *_nullptr,
 48                     sgl_floating_point *dstptr,
 49                     unsigned int *status)
 50 {
 51         register int src, dst_exponent;
 52         register unsigned int result = 0;
 53 
 54         src = *srcptr;
 55         /* 
 56          * set sign bit of result and get magnitude of source 
 57          */
 58         if (src < 0) {
 59                 Sgl_setone_sign(result);  
 60                 Int_negate(src);
 61         }
 62         else {
 63                 Sgl_setzero_sign(result);
 64                 /* Check for zero */ 
 65                 if (src == 0) { 
 66                         Sgl_setzero(result); 
 67                         *dstptr = result;
 68                         return(NOEXCEPTION); 
 69                 } 
 70         }
 71         /*
 72          * Generate exponent and normalized mantissa
 73          */
 74         dst_exponent = 16;    /* initialize for normalization */
 75         /*
 76          * Check word for most significant bit set.  Returns
 77          * a value in dst_exponent indicating the bit position,
 78          * between -1 and 30.
 79          */
 80         Find_ms_one_bit(src,dst_exponent);
 81         /*  left justify source, with msb at bit position 1  */
 82         if (dst_exponent >= 0) src <<= dst_exponent;
 83         else src = 1 << 30;
 84         Sgl_set_mantissa(result, src >> (SGL_EXP_LENGTH-1));
 85         Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
 86 
 87         /* check for inexact */
 88         if (Int_isinexact_to_sgl(src)) {
 89                 switch (Rounding_mode()) {
 90                         case ROUNDPLUS: 
 91                                 if (Sgl_iszero_sign(result)) 
 92                                         Sgl_increment(result);
 93                                 break;
 94                         case ROUNDMINUS: 
 95                                 if (Sgl_isone_sign(result)) 
 96                                         Sgl_increment(result);
 97                                 break;
 98                         case ROUNDNEAREST:
 99                                 Sgl_roundnearest_from_int(src,result);
100                 }
101                 if (Is_inexacttrap_enabled()) {
102                         *dstptr = result;
103                         return(INEXACTEXCEPTION);
104                 }
105                 else Set_inexactflag();
106         }
107         *dstptr = result;
108         return(NOEXCEPTION);
109 }
110 
111 /*
112  *  Single Fixed-point to Double Floating-point 
113  */
114 
115 int
116 sgl_to_dbl_fcnvxf(
117                     int *srcptr,
118                     unsigned int *_nullptr,
119                     dbl_floating_point *dstptr,
120                     unsigned int *status)
121 {
122         register int src, dst_exponent;
123         register unsigned int resultp1 = 0, resultp2 = 0;
124 
125         src = *srcptr;
126         /* 
127          * set sign bit of result and get magnitude of source 
128          */
129         if (src < 0) {
130                 Dbl_setone_sign(resultp1);  
131                 Int_negate(src);
132         }
133         else {
134                 Dbl_setzero_sign(resultp1);
135                 /* Check for zero */
136                 if (src == 0) {
137                         Dbl_setzero(resultp1,resultp2);
138                         Dbl_copytoptr(resultp1,resultp2,dstptr);
139                         return(NOEXCEPTION);
140                 }
141         }
142         /*
143          * Generate exponent and normalized mantissa
144          */
145         dst_exponent = 16;    /* initialize for normalization */
146         /*
147          * Check word for most significant bit set.  Returns
148          * a value in dst_exponent indicating the bit position,
149          * between -1 and 30.
150          */
151         Find_ms_one_bit(src,dst_exponent);
152         /*  left justify source, with msb at bit position 1  */
153         if (dst_exponent >= 0) src <<= dst_exponent;
154         else src = 1 << 30;
155         Dbl_set_mantissap1(resultp1, src >> DBL_EXP_LENGTH - 1);
156         Dbl_set_mantissap2(resultp2, src << (33-DBL_EXP_LENGTH));
157         Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
158         Dbl_copytoptr(resultp1,resultp2,dstptr);
159         return(NOEXCEPTION);
160 }
161 
162 /*
163  *  Double Fixed-point to Single Floating-point 
164  */
165 
166 int
167 dbl_to_sgl_fcnvxf(
168                         dbl_integer *srcptr,
169                         unsigned int *_nullptr,
170                         sgl_floating_point *dstptr,
171                         unsigned int *status)
172 {
173         int dst_exponent, srcp1;
174         unsigned int result = 0, srcp2;
175 
176         Dint_copyfromptr(srcptr,srcp1,srcp2);
177         /* 
178          * set sign bit of result and get magnitude of source 
179          */
180         if (srcp1 < 0) {
181                 Sgl_setone_sign(result);  
182                 Dint_negate(srcp1,srcp2);
183         }
184         else {
185                 Sgl_setzero_sign(result);
186                 /* Check for zero */
187                 if (srcp1 == 0 && srcp2 == 0) {
188                         Sgl_setzero(result);
189                         *dstptr = result;
190                         return(NOEXCEPTION);
191                 }
192         }
193         /*
194          * Generate exponent and normalized mantissa
195          */
196         dst_exponent = 16;    /* initialize for normalization */
197         if (srcp1 == 0) {
198                 /*
199                  * Check word for most significant bit set.  Returns
200                  * a value in dst_exponent indicating the bit position,
201                  * between -1 and 30.
202                  */
203                 Find_ms_one_bit(srcp2,dst_exponent);
204                 /*  left justify source, with msb at bit position 1  */
205                 if (dst_exponent >= 0) {
206                         srcp1 = srcp2 << dst_exponent;    
207                         srcp2 = 0;
208                 }
209                 else {
210                         srcp1 = srcp2 >> 1;
211                         srcp2 <<= 31; 
212                 }
213                 /*
214                  *  since msb set is in second word, need to 
215                  *  adjust bit position count
216                  */
217                 dst_exponent += 32;
218         }
219         else {
220                 /*
221                  * Check word for most significant bit set.  Returns
222                  * a value in dst_exponent indicating the bit position,
223                  * between -1 and 30.
224                  *
225                  */
226                 Find_ms_one_bit(srcp1,dst_exponent);
227                 /*  left justify source, with msb at bit position 1  */
228                 if (dst_exponent > 0) {
229                         Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
230                          srcp1); 
231                         srcp2 <<= dst_exponent;
232                 }
233                 /*
234                  * If dst_exponent = 0, we don't need to shift anything.
235                  * If dst_exponent = -1, src = - 2**63 so we won't need to 
236                  * shift srcp2.
237                  */
238                 else srcp1 >>= -(dst_exponent);
239         }
240         Sgl_set_mantissa(result, srcp1 >> SGL_EXP_LENGTH - 1);
241         Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
242 
243         /* check for inexact */
244         if (Dint_isinexact_to_sgl(srcp1,srcp2)) {
245                 switch (Rounding_mode()) {
246                         case ROUNDPLUS: 
247                                 if (Sgl_iszero_sign(result)) 
248                                         Sgl_increment(result);
249                                 break;
250                         case ROUNDMINUS: 
251                                 if (Sgl_isone_sign(result)) 
252                                         Sgl_increment(result);
253                                 break;
254                         case ROUNDNEAREST:
255                                 Sgl_roundnearest_from_dint(srcp1,srcp2,result);
256                 }
257                 if (Is_inexacttrap_enabled()) {
258                         *dstptr = result;
259                         return(INEXACTEXCEPTION);
260                 }
261                 else Set_inexactflag();
262         }
263         *dstptr = result;
264         return(NOEXCEPTION);
265 }
266 
267 /*
268  *  Double Fixed-point to Double Floating-point 
269  */
270 
271 int
272 dbl_to_dbl_fcnvxf(
273                     dbl_integer *srcptr,
274                     unsigned int *_nullptr,
275                     dbl_floating_point *dstptr,
276                     unsigned int *status)
277 {
278         register int srcp1, dst_exponent;
279         register unsigned int srcp2, resultp1 = 0, resultp2 = 0;
280 
281         Dint_copyfromptr(srcptr,srcp1,srcp2);
282         /* 
283          * set sign bit of result and get magnitude of source 
284          */
285         if (srcp1 < 0) {
286                 Dbl_setone_sign(resultp1);
287                 Dint_negate(srcp1,srcp2);
288         }
289         else {
290                 Dbl_setzero_sign(resultp1);
291                 /* Check for zero */
292                 if (srcp1 == 0 && srcp2 ==0) {
293                         Dbl_setzero(resultp1,resultp2);
294                         Dbl_copytoptr(resultp1,resultp2,dstptr);
295                         return(NOEXCEPTION);
296                 }
297         }
298         /*
299          * Generate exponent and normalized mantissa
300          */
301         dst_exponent = 16;    /* initialize for normalization */
302         if (srcp1 == 0) {
303                 /*
304                  * Check word for most significant bit set.  Returns
305                  * a value in dst_exponent indicating the bit position,
306                  * between -1 and 30.
307                  */
308                 Find_ms_one_bit(srcp2,dst_exponent);
309                 /*  left justify source, with msb at bit position 1  */
310                 if (dst_exponent >= 0) {
311                         srcp1 = srcp2 << dst_exponent;    
312                         srcp2 = 0;
313                 }
314                 else {
315                         srcp1 = srcp2 >> 1;
316                         srcp2 <<= 31;
317                 }
318                 /*
319                  *  since msb set is in second word, need to 
320                  *  adjust bit position count
321                  */
322                 dst_exponent += 32;
323         }
324         else {
325                 /*
326                  * Check word for most significant bit set.  Returns
327                  * a value in dst_exponent indicating the bit position,
328                  * between -1 and 30.
329                  */
330                 Find_ms_one_bit(srcp1,dst_exponent);
331                 /*  left justify source, with msb at bit position 1  */
332                 if (dst_exponent > 0) {
333                         Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
334                          srcp1); 
335                         srcp2 <<= dst_exponent;
336                 }
337                 /*
338                  * If dst_exponent = 0, we don't need to shift anything.
339                  * If dst_exponent = -1, src = - 2**63 so we won't need to 
340                  * shift srcp2.
341                  */
342                 else srcp1 >>= -(dst_exponent);
343         }
344         Dbl_set_mantissap1(resultp1, srcp1 >> (DBL_EXP_LENGTH-1));
345         Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH-1,resultp2);
346         Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
347 
348         /* check for inexact */
349         if (Dint_isinexact_to_dbl(srcp2)) {
350                 switch (Rounding_mode()) {
351                         case ROUNDPLUS: 
352                                 if (Dbl_iszero_sign(resultp1)) {
353                                         Dbl_increment(resultp1,resultp2);
354                                 }
355                                 break;
356                         case ROUNDMINUS: 
357                                 if (Dbl_isone_sign(resultp1)) {
358                                         Dbl_increment(resultp1,resultp2);
359                                 }
360                                 break;
361                         case ROUNDNEAREST:
362                                 Dbl_roundnearest_from_dint(srcp2,resultp1,
363                                 resultp2);
364                 }
365                 if (Is_inexacttrap_enabled()) {
366                         Dbl_copytoptr(resultp1,resultp2,dstptr);
367                         return(INEXACTEXCEPTION);
368                 }
369                 else Set_inexactflag();
370         }
371         Dbl_copytoptr(resultp1,resultp2,dstptr);
372         return(NOEXCEPTION);
373 }
374 

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