1 /* $NetBSD: fcnvxf.c,v 1.1.10.1 2004/08/03 10:35:38 skrll Exp $ */
3 /* $OpenBSD: fcnvxf.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: fcnvxf.c,v 1.1.10.1 2004/08/03 10:35:38 skrll 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 * Convert single fixed-point to single floating-point format
56 sgl_to_sgl_fcnvxf(srcptr
,dstptr
,status
)
59 sgl_floating_point
*dstptr
;
62 register int src
, dst_exponent
;
63 register unsigned int result
= 0;
67 * set sign bit of result and get magnitude of source
70 Sgl_setone_sign(result
);
74 Sgl_setzero_sign(result
);
83 * Generate exponent and normalized mantissa
85 dst_exponent
= 16; /* initialize for normalization */
87 * Check word for most significant bit set. Returns
88 * a value in dst_exponent indicating the bit position,
91 Find_ms_one_bit(src
,dst_exponent
);
92 /* left justify source, with msb at bit position 1 */
93 if (dst_exponent
>= 0) src
<<= dst_exponent
;
95 Sgl_set_mantissa(result
, src
>> (SGL_EXP_LENGTH
-1));
96 Sgl_set_exponent(result
, 30+SGL_BIAS
- dst_exponent
);
98 /* check for inexact */
99 if (Int_isinexact_to_sgl(src
)) {
100 switch (Rounding_mode()) {
102 if (Sgl_iszero_sign(result
))
103 Sgl_increment(result
);
106 if (Sgl_isone_sign(result
))
107 Sgl_increment(result
);
110 Sgl_roundnearest_from_int(src
,result
);
112 if (Is_inexacttrap_enabled()) {
114 return(INEXACTEXCEPTION
);
116 else Set_inexactflag();
123 * Single Fixed-point to Double Floating-point
126 sgl_to_dbl_fcnvxf(srcptr
,dstptr
,status
)
129 dbl_floating_point
*dstptr
;
130 unsigned int *status
;
132 register int src
, dst_exponent
;
133 register unsigned int resultp1
= 0, resultp2
= 0;
137 * set sign bit of result and get magnitude of source
140 Dbl_setone_sign(resultp1
);
144 Dbl_setzero_sign(resultp1
);
147 Dbl_setzero(resultp1
,resultp2
);
148 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
153 * Generate exponent and normalized mantissa
155 dst_exponent
= 16; /* initialize for normalization */
157 * Check word for most significant bit set. Returns
158 * a value in dst_exponent indicating the bit position,
161 Find_ms_one_bit(src
,dst_exponent
);
162 /* left justify source, with msb at bit position 1 */
163 if (dst_exponent
>= 0) src
<<= dst_exponent
;
165 Dbl_set_mantissap1(resultp1
, (src
>> (DBL_EXP_LENGTH
- 1)));
166 Dbl_set_mantissap2(resultp2
, (src
<< (33-DBL_EXP_LENGTH
)));
167 Dbl_set_exponent(resultp1
, (30+DBL_BIAS
) - dst_exponent
);
168 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
173 * Double Fixed-point to Single Floating-point
176 dbl_to_sgl_fcnvxf(srcptr
,dstptr
,status
)
179 sgl_floating_point
*dstptr
;
180 unsigned int *status
;
182 int dst_exponent
, srcp1
;
183 unsigned int result
= 0, srcp2
;
185 Dint_copyfromptr(srcptr
,srcp1
,srcp2
);
187 * set sign bit of result and get magnitude of source
190 Sgl_setone_sign(result
);
191 Dint_negate(srcp1
,srcp2
);
194 Sgl_setzero_sign(result
);
196 if (srcp1
== 0 && srcp2
== 0) {
203 * Generate exponent and normalized mantissa
205 dst_exponent
= 16; /* initialize for normalization */
208 * Check word for most significant bit set. Returns
209 * a value in dst_exponent indicating the bit position,
212 Find_ms_one_bit(srcp2
,dst_exponent
);
213 /* left justify source, with msb at bit position 1 */
214 if (dst_exponent
>= 0) {
215 srcp1
= srcp2
<< dst_exponent
;
223 * since msb set is in second word, need to
224 * adjust bit position count
230 * Check word for most significant bit set. Returns
231 * a value in dst_exponent indicating the bit position,
235 Find_ms_one_bit(srcp1
,dst_exponent
);
236 /* left justify source, with msb at bit position 1 */
237 if (dst_exponent
> 0) {
238 Variable_shift_double(srcp1
,srcp2
,(32-dst_exponent
),
240 srcp2
<<= dst_exponent
;
243 * If dst_exponent = 0, we don't need to shift anything.
244 * If dst_exponent = -1, src = - 2**63 so we won't need to
247 else srcp1
>>= -(dst_exponent
);
249 Sgl_set_mantissa(result
, (srcp1
>> (SGL_EXP_LENGTH
- 1)));
250 Sgl_set_exponent(result
, (62+SGL_BIAS
) - dst_exponent
);
252 /* check for inexact */
253 if (Dint_isinexact_to_sgl(srcp1
,srcp2
)) {
254 switch (Rounding_mode()) {
256 if (Sgl_iszero_sign(result
))
257 Sgl_increment(result
);
260 if (Sgl_isone_sign(result
))
261 Sgl_increment(result
);
264 Sgl_roundnearest_from_dint(srcp1
,srcp2
,result
);
266 if (Is_inexacttrap_enabled()) {
268 return(INEXACTEXCEPTION
);
270 else Set_inexactflag();
277 * Double Fixed-point to Double Floating-point
280 dbl_to_dbl_fcnvxf(srcptr
,dstptr
,status
)
283 dbl_floating_point
*dstptr
;
284 unsigned int *status
;
286 register int srcp1
, dst_exponent
;
287 register unsigned int srcp2
, resultp1
= 0, resultp2
= 0;
289 Dint_copyfromptr(srcptr
,srcp1
,srcp2
);
291 * set sign bit of result and get magnitude of source
294 Dbl_setone_sign(resultp1
);
295 Dint_negate(srcp1
,srcp2
);
298 Dbl_setzero_sign(resultp1
);
300 if (srcp1
== 0 && srcp2
==0) {
301 Dbl_setzero(resultp1
,resultp2
);
302 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
307 * Generate exponent and normalized mantissa
309 dst_exponent
= 16; /* initialize for normalization */
312 * Check word for most significant bit set. Returns
313 * a value in dst_exponent indicating the bit position,
316 Find_ms_one_bit(srcp2
,dst_exponent
);
317 /* left justify source, with msb at bit position 1 */
318 if (dst_exponent
>= 0) {
319 srcp1
= srcp2
<< dst_exponent
;
327 * since msb set is in second word, need to
328 * adjust bit position count
334 * Check word for most significant bit set. Returns
335 * a value in dst_exponent indicating the bit position,
338 Find_ms_one_bit(srcp1
,dst_exponent
);
339 /* left justify source, with msb at bit position 1 */
340 if (dst_exponent
> 0) {
341 Variable_shift_double(srcp1
,srcp2
,(32-dst_exponent
),
343 srcp2
<<= dst_exponent
;
346 * If dst_exponent = 0, we don't need to shift anything.
347 * If dst_exponent = -1, src = - 2**63 so we won't need to
350 else srcp1
>>= -(dst_exponent
);
352 Dbl_set_mantissap1(resultp1
, srcp1
>> (DBL_EXP_LENGTH
-1));
353 Shiftdouble(srcp1
,srcp2
,DBL_EXP_LENGTH
-1,resultp2
);
354 Dbl_set_exponent(resultp1
, (62+DBL_BIAS
) - dst_exponent
);
356 /* check for inexact */
357 if (Dint_isinexact_to_dbl(srcp2
)) {
358 switch (Rounding_mode()) {
360 if (Dbl_iszero_sign(resultp1
)) {
361 Dbl_increment(resultp1
,resultp2
);
365 if (Dbl_isone_sign(resultp1
)) {
366 Dbl_increment(resultp1
,resultp2
);
370 Dbl_roundnearest_from_dint(srcp2
,resultp1
,
373 if (Is_inexacttrap_enabled()) {
374 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
375 return(INEXACTEXCEPTION
);
377 else Set_inexactflag();
379 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);