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/fcnvff.c $Revision: 1.1 $
15 * Single Floating-point to Double Floating-point
16 * Double Floating-point to Single Floating-point
18 * External Interfaces:
19 * dbl_to_sgl_fcnvff(srcptr,nullptr,dstptr,status)
20 * sgl_to_dbl_fcnvff(srcptr,nullptr,dstptr,status)
22 * Internal Interfaces:
25 * <<please update with a overview of the operation of this file>>
32 #include "sgl_float.h"
33 #include "dbl_float.h"
34 #include "cnv_float.h"
37 * Single Floating-point to Double Floating-point
42 sgl_floating_point
*srcptr
,
43 unsigned int *nullptr,
44 dbl_floating_point
*dstptr
,
47 register unsigned int src
, resultp1
, resultp2
;
48 register int src_exponent
;
51 src_exponent
= Sgl_exponent(src
);
52 Dbl_allp1(resultp1
) = Sgl_all(src
); /* set sign of result */
54 * Test for NaN or infinity
56 if (src_exponent
== SGL_INFINITY_EXPONENT
) {
58 * determine if NaN or infinity
60 if (Sgl_iszero_mantissa(src
)) {
62 * is infinity; want to return double infinity
64 Dbl_setinfinity_exponentmantissa(resultp1
,resultp2
);
65 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
70 * is NaN; signaling or quiet?
72 if (Sgl_isone_signaling(src
)) {
73 /* trap if INVALIDTRAP enabled */
74 if (Is_invalidtrap_enabled())
75 return(INVALIDEXCEPTION
);
83 * NaN is quiet, return as double NaN
85 Dbl_setinfinity_exponent(resultp1
);
86 Sgl_to_dbl_mantissa(src
,resultp1
,resultp2
);
87 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
92 * Test for zero or denormalized
94 if (src_exponent
== 0) {
96 * determine if zero or denormalized
98 if (Sgl_isnotzero_mantissa(src
)) {
100 * is denormalized; want to normalize
102 Sgl_clear_signexponent(src
);
103 Sgl_leftshiftby1(src
);
104 Sgl_normalize(src
,src_exponent
);
105 Sgl_to_dbl_exponent(src_exponent
,resultp1
);
106 Sgl_to_dbl_mantissa(src
,resultp1
,resultp2
);
109 Dbl_setzero_exponentmantissa(resultp1
,resultp2
);
111 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
115 * No special cases, just complete the conversion
117 Sgl_to_dbl_exponent(src_exponent
, resultp1
);
118 Sgl_to_dbl_mantissa(Sgl_mantissa(src
), resultp1
,resultp2
);
119 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
124 * Double Floating-point to Single Floating-point
129 dbl_floating_point
*srcptr
,
130 unsigned int *nullptr,
131 sgl_floating_point
*dstptr
,
132 unsigned int *status
)
134 register unsigned int srcp1
, srcp2
, result
;
135 register int src_exponent
, dest_exponent
, dest_mantissa
;
136 register boolean inexact
= FALSE
, guardbit
= FALSE
, stickybit
= FALSE
;
137 register boolean lsb_odd
= FALSE
;
138 boolean is_tiny
= FALSE
;
140 Dbl_copyfromptr(srcptr
,srcp1
,srcp2
);
141 src_exponent
= Dbl_exponent(srcp1
);
142 Sgl_all(result
) = Dbl_allp1(srcp1
); /* set sign of result */
144 * Test for NaN or infinity
146 if (src_exponent
== DBL_INFINITY_EXPONENT
) {
148 * determine if NaN or infinity
150 if (Dbl_iszero_mantissa(srcp1
,srcp2
)) {
152 * is infinity; want to return single infinity
154 Sgl_setinfinity_exponentmantissa(result
);
159 * is NaN; signaling or quiet?
161 if (Dbl_isone_signaling(srcp1
)) {
162 /* trap if INVALIDTRAP enabled */
163 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION
);
167 Dbl_set_quiet(srcp1
);
171 * NaN is quiet, return as single NaN
173 Sgl_setinfinity_exponent(result
);
174 Sgl_set_mantissa(result
,Dallp1(srcp1
)<<3 | Dallp2(srcp2
)>>29);
175 if (Sgl_iszero_mantissa(result
)) Sgl_set_quiet(result
);
182 Dbl_to_sgl_exponent(src_exponent
,dest_exponent
);
183 if (dest_exponent
> 0) {
184 Dbl_to_sgl_mantissa(srcp1
,srcp2
,dest_mantissa
,inexact
,guardbit
,
188 if (Dbl_iszero_exponentmantissa(srcp1
,srcp2
)){
189 Sgl_setzero_exponentmantissa(result
);
193 if (Is_underflowtrap_enabled()) {
194 Dbl_to_sgl_mantissa(srcp1
,srcp2
,dest_mantissa
,inexact
,
195 guardbit
,stickybit
,lsb_odd
);
198 /* compute result, determine inexact info,
199 * and set Underflowflag if appropriate
201 Dbl_to_sgl_denormalized(srcp1
,srcp2
,dest_exponent
,
202 dest_mantissa
,inexact
,guardbit
,stickybit
,lsb_odd
,
207 * Now round result if not exact
210 switch (Rounding_mode()) {
212 if (Sgl_iszero_sign(result
)) dest_mantissa
++;
215 if (Sgl_isone_sign(result
)) dest_mantissa
++;
219 if (stickybit
|| lsb_odd
) dest_mantissa
++;
223 Sgl_set_exponentmantissa(result
,dest_mantissa
);
226 * check for mantissa overflow after rounding
228 if ((dest_exponent
>0 || Is_underflowtrap_enabled()) &&
229 Sgl_isone_hidden(result
)) dest_exponent
++;
234 if (dest_exponent
>= SGL_INFINITY_EXPONENT
) {
235 /* trap if OVERFLOWTRAP enabled */
236 if (Is_overflowtrap_enabled()) {
238 * Check for gross overflow
240 if (dest_exponent
>= SGL_INFINITY_EXPONENT
+SGL_WRAP
)
241 return(UNIMPLEMENTEDEXCEPTION
);
244 * Adjust bias of result
246 Sgl_setwrapped_exponent(result
,dest_exponent
,ovfl
);
249 if (Is_inexacttrap_enabled())
250 return(OVERFLOWEXCEPTION
|INEXACTEXCEPTION
);
251 else Set_inexactflag();
252 return(OVERFLOWEXCEPTION
);
256 /* set result to infinity or largest number */
257 Sgl_setoverflow(result
);
262 else if (dest_exponent
<= 0) {
263 /* trap if UNDERFLOWTRAP enabled */
264 if (Is_underflowtrap_enabled()) {
266 * Check for gross underflow
268 if (dest_exponent
<= -(SGL_WRAP
))
269 return(UNIMPLEMENTEDEXCEPTION
);
271 * Adjust bias of result
273 Sgl_setwrapped_exponent(result
,dest_exponent
,unfl
);
276 if (Is_inexacttrap_enabled())
277 return(UNDERFLOWEXCEPTION
|INEXACTEXCEPTION
);
278 else Set_inexactflag();
279 return(UNDERFLOWEXCEPTION
);
282 * result is denormalized or signed zero
284 if (inexact
&& is_tiny
) Set_underflowflag();
287 else Sgl_set_exponent(result
,dest_exponent
);
290 * Trap if inexact trap is enabled
293 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
294 else Set_inexactflag();