2 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
4 * Floating-point emulation code
5 * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 * @(#) pa/spmath/fcnvxf.c $Revision: 1.1 $
28 * Single Fixed-point to Single Floating-point
29 * Single Fixed-point to Double Floating-point
30 * Double Fixed-point to Single Floating-point
31 * Double Fixed-point to Double Floating-point
33 * External Interfaces:
34 * dbl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
35 * dbl_to_sgl_fcnvxf(srcptr,nullptr,dstptr,status)
36 * sgl_to_dbl_fcnvxf(srcptr,nullptr,dstptr,status)
37 * sgl_to_sgl_fcnvxf(srcptr,nullptr,dstptr,status)
39 * Internal Interfaces:
42 * <<please update with a overview of the operation of this file>>
49 #include "sgl_float.h"
50 #include "dbl_float.h"
51 #include "cnv_float.h"
54 * Convert single fixed-point to single floating-point format
60 unsigned int *nullptr,
61 sgl_floating_point
*dstptr
,
64 register int src
, dst_exponent
;
65 register unsigned int result
= 0;
69 * set sign bit of result and get magnitude of source
72 Sgl_setone_sign(result
);
76 Sgl_setzero_sign(result
);
85 * Generate exponent and normalized mantissa
87 dst_exponent
= 16; /* initialize for normalization */
89 * Check word for most significant bit set. Returns
90 * a value in dst_exponent indicating the bit position,
93 Find_ms_one_bit(src
,dst_exponent
);
94 /* left justify source, with msb at bit position 1 */
95 if (dst_exponent
>= 0) src
<<= dst_exponent
;
97 Sgl_set_mantissa(result
, src
>> (SGL_EXP_LENGTH
-1));
98 Sgl_set_exponent(result
, 30+SGL_BIAS
- dst_exponent
);
100 /* check for inexact */
101 if (Int_isinexact_to_sgl(src
)) {
102 switch (Rounding_mode()) {
104 if (Sgl_iszero_sign(result
))
105 Sgl_increment(result
);
108 if (Sgl_isone_sign(result
))
109 Sgl_increment(result
);
112 Sgl_roundnearest_from_int(src
,result
);
114 if (Is_inexacttrap_enabled()) {
116 return(INEXACTEXCEPTION
);
118 else Set_inexactflag();
125 * Single Fixed-point to Double Floating-point
131 unsigned int *nullptr,
132 dbl_floating_point
*dstptr
,
133 unsigned int *status
)
135 register int src
, dst_exponent
;
136 register unsigned int resultp1
= 0, resultp2
= 0;
140 * set sign bit of result and get magnitude of source
143 Dbl_setone_sign(resultp1
);
147 Dbl_setzero_sign(resultp1
);
150 Dbl_setzero(resultp1
,resultp2
);
151 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
156 * Generate exponent and normalized mantissa
158 dst_exponent
= 16; /* initialize for normalization */
160 * Check word for most significant bit set. Returns
161 * a value in dst_exponent indicating the bit position,
164 Find_ms_one_bit(src
,dst_exponent
);
165 /* left justify source, with msb at bit position 1 */
166 if (dst_exponent
>= 0) src
<<= dst_exponent
;
168 Dbl_set_mantissap1(resultp1
, src
>> DBL_EXP_LENGTH
- 1);
169 Dbl_set_mantissap2(resultp2
, src
<< (33-DBL_EXP_LENGTH
));
170 Dbl_set_exponent(resultp1
, (30+DBL_BIAS
) - dst_exponent
);
171 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
176 * Double Fixed-point to Single Floating-point
182 unsigned int *nullptr,
183 sgl_floating_point
*dstptr
,
184 unsigned int *status
)
186 int dst_exponent
, srcp1
;
187 unsigned int result
= 0, srcp2
;
189 Dint_copyfromptr(srcptr
,srcp1
,srcp2
);
191 * set sign bit of result and get magnitude of source
194 Sgl_setone_sign(result
);
195 Dint_negate(srcp1
,srcp2
);
198 Sgl_setzero_sign(result
);
200 if (srcp1
== 0 && srcp2
== 0) {
207 * Generate exponent and normalized mantissa
209 dst_exponent
= 16; /* initialize for normalization */
212 * Check word for most significant bit set. Returns
213 * a value in dst_exponent indicating the bit position,
216 Find_ms_one_bit(srcp2
,dst_exponent
);
217 /* left justify source, with msb at bit position 1 */
218 if (dst_exponent
>= 0) {
219 srcp1
= srcp2
<< dst_exponent
;
227 * since msb set is in second word, need to
228 * adjust bit position count
234 * Check word for most significant bit set. Returns
235 * a value in dst_exponent indicating the bit position,
239 Find_ms_one_bit(srcp1
,dst_exponent
);
240 /* left justify source, with msb at bit position 1 */
241 if (dst_exponent
> 0) {
242 Variable_shift_double(srcp1
,srcp2
,(32-dst_exponent
),
244 srcp2
<<= dst_exponent
;
247 * If dst_exponent = 0, we don't need to shift anything.
248 * If dst_exponent = -1, src = - 2**63 so we won't need to
251 else srcp1
>>= -(dst_exponent
);
253 Sgl_set_mantissa(result
, srcp1
>> SGL_EXP_LENGTH
- 1);
254 Sgl_set_exponent(result
, (62+SGL_BIAS
) - dst_exponent
);
256 /* check for inexact */
257 if (Dint_isinexact_to_sgl(srcp1
,srcp2
)) {
258 switch (Rounding_mode()) {
260 if (Sgl_iszero_sign(result
))
261 Sgl_increment(result
);
264 if (Sgl_isone_sign(result
))
265 Sgl_increment(result
);
268 Sgl_roundnearest_from_dint(srcp1
,srcp2
,result
);
270 if (Is_inexacttrap_enabled()) {
272 return(INEXACTEXCEPTION
);
274 else Set_inexactflag();
281 * Double Fixed-point to Double Floating-point
287 unsigned int *nullptr,
288 dbl_floating_point
*dstptr
,
289 unsigned int *status
)
291 register int srcp1
, dst_exponent
;
292 register unsigned int srcp2
, resultp1
= 0, resultp2
= 0;
294 Dint_copyfromptr(srcptr
,srcp1
,srcp2
);
296 * set sign bit of result and get magnitude of source
299 Dbl_setone_sign(resultp1
);
300 Dint_negate(srcp1
,srcp2
);
303 Dbl_setzero_sign(resultp1
);
305 if (srcp1
== 0 && srcp2
==0) {
306 Dbl_setzero(resultp1
,resultp2
);
307 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
312 * Generate exponent and normalized mantissa
314 dst_exponent
= 16; /* initialize for normalization */
317 * Check word for most significant bit set. Returns
318 * a value in dst_exponent indicating the bit position,
321 Find_ms_one_bit(srcp2
,dst_exponent
);
322 /* left justify source, with msb at bit position 1 */
323 if (dst_exponent
>= 0) {
324 srcp1
= srcp2
<< dst_exponent
;
332 * since msb set is in second word, need to
333 * adjust bit position count
339 * Check word for most significant bit set. Returns
340 * a value in dst_exponent indicating the bit position,
343 Find_ms_one_bit(srcp1
,dst_exponent
);
344 /* left justify source, with msb at bit position 1 */
345 if (dst_exponent
> 0) {
346 Variable_shift_double(srcp1
,srcp2
,(32-dst_exponent
),
348 srcp2
<<= dst_exponent
;
351 * If dst_exponent = 0, we don't need to shift anything.
352 * If dst_exponent = -1, src = - 2**63 so we won't need to
355 else srcp1
>>= -(dst_exponent
);
357 Dbl_set_mantissap1(resultp1
, srcp1
>> (DBL_EXP_LENGTH
-1));
358 Shiftdouble(srcp1
,srcp2
,DBL_EXP_LENGTH
-1,resultp2
);
359 Dbl_set_exponent(resultp1
, (62+DBL_BIAS
) - dst_exponent
);
361 /* check for inexact */
362 if (Dint_isinexact_to_dbl(srcp2
)) {
363 switch (Rounding_mode()) {
365 if (Dbl_iszero_sign(resultp1
)) {
366 Dbl_increment(resultp1
,resultp2
);
370 if (Dbl_isone_sign(resultp1
)) {
371 Dbl_increment(resultp1
,resultp2
);
375 Dbl_roundnearest_from_dint(srcp2
,resultp1
,
378 if (Is_inexacttrap_enabled()) {
379 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
380 return(INEXACTEXCEPTION
);
382 else Set_inexactflag();
384 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);