1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
5 * Floating-point emulation code
6 * Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
12 * @(#) pa/spmath/fcnvxf.c $Revision: 1.1 $
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
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)
26 * Internal Interfaces:
29 * <<please update with a overview of the operation of this file>>
36 #include "sgl_float.h"
37 #include "dbl_float.h"
38 #include "cnv_float.h"
41 * Convert single fixed-point to single floating-point format
47 unsigned int *nullptr,
48 sgl_floating_point
*dstptr
,
51 register int src
, dst_exponent
;
52 register unsigned int result
= 0;
56 * set sign bit of result and get magnitude of source
59 Sgl_setone_sign(result
);
63 Sgl_setzero_sign(result
);
72 * Generate exponent and normalized mantissa
74 dst_exponent
= 16; /* initialize for normalization */
76 * Check word for most significant bit set. Returns
77 * a value in dst_exponent indicating the bit position,
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
;
84 Sgl_set_mantissa(result
, src
>> (SGL_EXP_LENGTH
-1));
85 Sgl_set_exponent(result
, 30+SGL_BIAS
- dst_exponent
);
87 /* check for inexact */
88 if (Int_isinexact_to_sgl(src
)) {
89 switch (Rounding_mode()) {
91 if (Sgl_iszero_sign(result
))
92 Sgl_increment(result
);
95 if (Sgl_isone_sign(result
))
96 Sgl_increment(result
);
99 Sgl_roundnearest_from_int(src
,result
);
101 if (Is_inexacttrap_enabled()) {
103 return(INEXACTEXCEPTION
);
105 else Set_inexactflag();
112 * Single Fixed-point to Double Floating-point
118 unsigned int *nullptr,
119 dbl_floating_point
*dstptr
,
120 unsigned int *status
)
122 register int src
, dst_exponent
;
123 register unsigned int resultp1
= 0, resultp2
= 0;
127 * set sign bit of result and get magnitude of source
130 Dbl_setone_sign(resultp1
);
134 Dbl_setzero_sign(resultp1
);
137 Dbl_setzero(resultp1
,resultp2
);
138 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
143 * Generate exponent and normalized mantissa
145 dst_exponent
= 16; /* initialize for normalization */
147 * Check word for most significant bit set. Returns
148 * a value in dst_exponent indicating the bit position,
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
;
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
);
163 * Double Fixed-point to Single Floating-point
169 unsigned int *nullptr,
170 sgl_floating_point
*dstptr
,
171 unsigned int *status
)
173 int dst_exponent
, srcp1
;
174 unsigned int result
= 0, srcp2
;
176 Dint_copyfromptr(srcptr
,srcp1
,srcp2
);
178 * set sign bit of result and get magnitude of source
181 Sgl_setone_sign(result
);
182 Dint_negate(srcp1
,srcp2
);
185 Sgl_setzero_sign(result
);
187 if (srcp1
== 0 && srcp2
== 0) {
194 * Generate exponent and normalized mantissa
196 dst_exponent
= 16; /* initialize for normalization */
199 * Check word for most significant bit set. Returns
200 * a value in dst_exponent indicating the bit position,
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
;
214 * since msb set is in second word, need to
215 * adjust bit position count
221 * Check word for most significant bit set. Returns
222 * a value in dst_exponent indicating the bit position,
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
),
231 srcp2
<<= dst_exponent
;
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
238 else srcp1
>>= -(dst_exponent
);
240 Sgl_set_mantissa(result
, srcp1
>> SGL_EXP_LENGTH
- 1);
241 Sgl_set_exponent(result
, (62+SGL_BIAS
) - dst_exponent
);
243 /* check for inexact */
244 if (Dint_isinexact_to_sgl(srcp1
,srcp2
)) {
245 switch (Rounding_mode()) {
247 if (Sgl_iszero_sign(result
))
248 Sgl_increment(result
);
251 if (Sgl_isone_sign(result
))
252 Sgl_increment(result
);
255 Sgl_roundnearest_from_dint(srcp1
,srcp2
,result
);
257 if (Is_inexacttrap_enabled()) {
259 return(INEXACTEXCEPTION
);
261 else Set_inexactflag();
268 * Double Fixed-point to Double Floating-point
274 unsigned int *nullptr,
275 dbl_floating_point
*dstptr
,
276 unsigned int *status
)
278 register int srcp1
, dst_exponent
;
279 register unsigned int srcp2
, resultp1
= 0, resultp2
= 0;
281 Dint_copyfromptr(srcptr
,srcp1
,srcp2
);
283 * set sign bit of result and get magnitude of source
286 Dbl_setone_sign(resultp1
);
287 Dint_negate(srcp1
,srcp2
);
290 Dbl_setzero_sign(resultp1
);
292 if (srcp1
== 0 && srcp2
==0) {
293 Dbl_setzero(resultp1
,resultp2
);
294 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
299 * Generate exponent and normalized mantissa
301 dst_exponent
= 16; /* initialize for normalization */
304 * Check word for most significant bit set. Returns
305 * a value in dst_exponent indicating the bit position,
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
;
319 * since msb set is in second word, need to
320 * adjust bit position count
326 * Check word for most significant bit set. Returns
327 * a value in dst_exponent indicating the bit position,
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
),
335 srcp2
<<= dst_exponent
;
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
342 else srcp1
>>= -(dst_exponent
);
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
);
348 /* check for inexact */
349 if (Dint_isinexact_to_dbl(srcp2
)) {
350 switch (Rounding_mode()) {
352 if (Dbl_iszero_sign(resultp1
)) {
353 Dbl_increment(resultp1
,resultp2
);
357 if (Dbl_isone_sign(resultp1
)) {
358 Dbl_increment(resultp1
,resultp2
);
362 Dbl_roundnearest_from_dint(srcp2
,resultp1
,
365 if (Is_inexacttrap_enabled()) {
366 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
367 return(INEXACTEXCEPTION
);
369 else Set_inexactflag();
371 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);