1 /* $NetBSD: fcnvff.c,v 1.4 2005/12/11 12:17:40 christos Exp $ */
3 /* $OpenBSD: fcnvff.c,v 1.5 2001/03/29 03:58:18 mickey Exp $ */
6 * Copyright 1996 1995 by Open Software Foundation, Inc.
9 * Permission to use, copy, modify, and distribute this software and
10 * its documentation for any purpose and without fee is hereby granted,
11 * provided that the above copyright notice appears in all copies and
12 * that both the copyright notice and this permission notice appear in
13 * supporting documentation.
15 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
17 * FOR A PARTICULAR PURPOSE.
19 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
22 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
23 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30 * (c) Copyright 1986 HEWLETT-PACKARD COMPANY
32 * To anyone who acknowledges that this file is provided "AS IS"
33 * without any express or implied warranty:
34 * permission to use, copy, modify, and distribute this file
35 * for any purpose is hereby granted without fee, provided that
36 * the above copyright notice and this notice appears in all
37 * copies, and that the name of Hewlett-Packard Company not be
38 * used in advertising or publicity pertaining to distribution
39 * of the software without specific, written prior permission.
40 * Hewlett-Packard Company makes no representations about the
41 * suitability of this software for any purpose.
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: fcnvff.c,v 1.4 2005/12/11 12:17:40 christos Exp $");
47 #include "../spmath/float.h"
48 #include "../spmath/sgl_float.h"
49 #include "../spmath/dbl_float.h"
50 #include "../spmath/cnv_float.h"
53 * Single Floating-point to Double Floating-point
57 sgl_to_dbl_fcnvff(srcptr
,dstptr
,status
)
59 sgl_floating_point
*srcptr
;
60 dbl_floating_point
*dstptr
;
63 register unsigned int src
, resultp1
, resultp2
;
64 register int src_exponent
;
67 src_exponent
= Sgl_exponent(src
);
68 Dbl_allp1(resultp1
) = Sgl_all(src
); /* set sign of result */
70 * Test for NaN or infinity
72 if (src_exponent
== SGL_INFINITY_EXPONENT
) {
74 * determine if NaN or infinity
76 if (Sgl_iszero_mantissa(src
)) {
78 * is infinity; want to return double infinity
80 Dbl_setinfinity_exponentmantissa(resultp1
,resultp2
);
81 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
86 * is NaN; signaling or quiet?
88 if (Sgl_isone_signaling(src
)) {
89 /* trap if INVALIDTRAP enabled */
90 if (Is_invalidtrap_enabled())
91 return(INVALIDEXCEPTION
);
99 * NaN is quiet, return as double NaN
101 Dbl_setinfinity_exponent(resultp1
);
102 Sgl_to_dbl_mantissa(src
,resultp1
,resultp2
);
103 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
108 * Test for zero or denormalized
110 if (src_exponent
== 0) {
112 * determine if zero or denormalized
114 if (Sgl_isnotzero_mantissa(src
)) {
116 * is denormalized; want to normalize
118 Sgl_clear_signexponent(src
);
119 Sgl_leftshiftby1(src
);
120 Sgl_normalize(src
,src_exponent
);
121 Sgl_to_dbl_exponent(src_exponent
,resultp1
);
122 Sgl_to_dbl_mantissa(src
,resultp1
,resultp2
);
125 Dbl_setzero_exponentmantissa(resultp1
,resultp2
);
127 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
131 * No special cases, just complete the conversion
133 Sgl_to_dbl_exponent(src_exponent
, resultp1
);
134 Sgl_to_dbl_mantissa(Sgl_mantissa(src
), resultp1
,resultp2
);
135 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
140 * Double Floating-point to Single Floating-point
144 dbl_to_sgl_fcnvff(srcptr
,dstptr
,status
)
146 dbl_floating_point
*srcptr
;
147 sgl_floating_point
*dstptr
;
148 unsigned int *status
;
150 register unsigned int srcp1
, srcp2
, result
;
151 register int src_exponent
, dest_exponent
, dest_mantissa
;
152 register int inexact
= false, guardbit
= false, stickybit
= false;
153 register int lsb_odd
= false;
156 Dbl_copyfromptr(srcptr
,srcp1
,srcp2
);
157 src_exponent
= Dbl_exponent(srcp1
);
158 Sgl_all(result
) = Dbl_allp1(srcp1
); /* set sign of result */
160 * Test for NaN or infinity
162 if (src_exponent
== DBL_INFINITY_EXPONENT
) {
164 * determine if NaN or infinity
166 if (Dbl_iszero_mantissa(srcp1
,srcp2
)) {
168 * is infinity; want to return single infinity
170 Sgl_setinfinity_exponentmantissa(result
);
175 * is NaN; signaling or quiet?
177 if (Dbl_isone_signaling(srcp1
)) {
178 /* trap if INVALIDTRAP enabled */
179 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION
);
183 Dbl_set_quiet(srcp1
);
187 * NaN is quiet, return as single NaN
189 Sgl_setinfinity_exponent(result
);
190 Sgl_set_mantissa(result
,Dallp1(srcp1
)<<3 | Dallp2(srcp2
)>>29);
191 if (Sgl_iszero_mantissa(result
)) Sgl_set_quiet(result
);
198 Dbl_to_sgl_exponent(src_exponent
,dest_exponent
);
199 if (dest_exponent
> 0) {
200 Dbl_to_sgl_mantissa(srcp1
,srcp2
,dest_mantissa
,inexact
,guardbit
,
204 if (Dbl_iszero_exponentmantissa(srcp1
,srcp2
)){
205 Sgl_setzero_exponentmantissa(result
);
209 if (Is_underflowtrap_enabled()) {
210 Dbl_to_sgl_mantissa(srcp1
,srcp2
,dest_mantissa
,inexact
,
211 guardbit
,stickybit
,lsb_odd
);
214 /* compute result, determine inexact info,
215 * and set Underflowflag if appropriate
217 Dbl_to_sgl_denormalized(srcp1
,srcp2
,dest_exponent
,
218 dest_mantissa
,inexact
,guardbit
,stickybit
,lsb_odd
,
223 * Now round result if not exact
226 switch (Rounding_mode()) {
228 if (Sgl_iszero_sign(result
)) dest_mantissa
++;
231 if (Sgl_isone_sign(result
)) dest_mantissa
++;
235 if (stickybit
|| lsb_odd
) dest_mantissa
++;
239 Sgl_set_exponentmantissa(result
,dest_mantissa
);
242 * check for mantissa overflow after rounding
244 if ((dest_exponent
>0 || Is_underflowtrap_enabled()) &&
245 Sgl_isone_hidden(result
)) dest_exponent
++;
250 if (dest_exponent
>= SGL_INFINITY_EXPONENT
) {
251 /* trap if OVERFLOWTRAP enabled */
252 if (Is_overflowtrap_enabled()) {
254 * Check for gross overflow
256 if (dest_exponent
>= SGL_INFINITY_EXPONENT
+SGL_WRAP
)
257 return(UNIMPLEMENTEDEXCEPTION
);
260 * Adjust bias of result
262 Sgl_setwrapped_exponent(result
,dest_exponent
,ovfl
);
265 if (Is_inexacttrap_enabled())
266 return(OVERFLOWEXCEPTION
|INEXACTEXCEPTION
);
270 return(OVERFLOWEXCEPTION
);
274 /* set result to infinity or largest number */
275 Sgl_setoverflow(result
);
280 else if (dest_exponent
<= 0) {
281 /* trap if UNDERFLOWTRAP enabled */
282 if (Is_underflowtrap_enabled()) {
284 * Check for gross underflow
286 if (dest_exponent
<= -(SGL_WRAP
))
287 return(UNIMPLEMENTEDEXCEPTION
);
289 * Adjust bias of result
291 Sgl_setwrapped_exponent(result
,dest_exponent
,unfl
);
294 if (Is_inexacttrap_enabled())
295 return(UNDERFLOWEXCEPTION
|INEXACTEXCEPTION
);
299 return(UNDERFLOWEXCEPTION
);
302 * result is denormalized or signed zero
304 if (inexact
&& is_tiny
) Set_underflowflag();
307 else Sgl_set_exponent(result
,dest_exponent
);
310 * Trap if inexact trap is enabled
313 if (Is_inexacttrap_enabled())
314 return(INEXACTEXCEPTION
);