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/fcnvff.c $Revision: 1.1 $
28 * Single Floating-point to Double Floating-point
29 * Double Floating-point to Single Floating-point
31 * External Interfaces:
32 * dbl_to_sgl_fcnvff(srcptr,nullptr,dstptr,status)
33 * sgl_to_dbl_fcnvff(srcptr,nullptr,dstptr,status)
35 * Internal Interfaces:
38 * <<please update with a overview of the operation of this file>>
45 #include "sgl_float.h"
46 #include "dbl_float.h"
47 #include "cnv_float.h"
50 * Single Floating-point to Double Floating-point
55 sgl_floating_point
*srcptr
,
56 unsigned int *nullptr,
57 dbl_floating_point
*dstptr
,
60 register unsigned int src
, resultp1
, resultp2
;
61 register int src_exponent
;
64 src_exponent
= Sgl_exponent(src
);
65 Dbl_allp1(resultp1
) = Sgl_all(src
); /* set sign of result */
67 * Test for NaN or infinity
69 if (src_exponent
== SGL_INFINITY_EXPONENT
) {
71 * determine if NaN or infinity
73 if (Sgl_iszero_mantissa(src
)) {
75 * is infinity; want to return double infinity
77 Dbl_setinfinity_exponentmantissa(resultp1
,resultp2
);
78 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
83 * is NaN; signaling or quiet?
85 if (Sgl_isone_signaling(src
)) {
86 /* trap if INVALIDTRAP enabled */
87 if (Is_invalidtrap_enabled())
88 return(INVALIDEXCEPTION
);
96 * NaN is quiet, return as double NaN
98 Dbl_setinfinity_exponent(resultp1
);
99 Sgl_to_dbl_mantissa(src
,resultp1
,resultp2
);
100 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
105 * Test for zero or denormalized
107 if (src_exponent
== 0) {
109 * determine if zero or denormalized
111 if (Sgl_isnotzero_mantissa(src
)) {
113 * is denormalized; want to normalize
115 Sgl_clear_signexponent(src
);
116 Sgl_leftshiftby1(src
);
117 Sgl_normalize(src
,src_exponent
);
118 Sgl_to_dbl_exponent(src_exponent
,resultp1
);
119 Sgl_to_dbl_mantissa(src
,resultp1
,resultp2
);
122 Dbl_setzero_exponentmantissa(resultp1
,resultp2
);
124 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
128 * No special cases, just complete the conversion
130 Sgl_to_dbl_exponent(src_exponent
, resultp1
);
131 Sgl_to_dbl_mantissa(Sgl_mantissa(src
), resultp1
,resultp2
);
132 Dbl_copytoptr(resultp1
,resultp2
,dstptr
);
137 * Double Floating-point to Single Floating-point
142 dbl_floating_point
*srcptr
,
143 unsigned int *nullptr,
144 sgl_floating_point
*dstptr
,
145 unsigned int *status
)
147 register unsigned int srcp1
, srcp2
, result
;
148 register int src_exponent
, dest_exponent
, dest_mantissa
;
149 register boolean inexact
= FALSE
, guardbit
= FALSE
, stickybit
= FALSE
;
150 register boolean lsb_odd
= FALSE
;
153 Dbl_copyfromptr(srcptr
,srcp1
,srcp2
);
154 src_exponent
= Dbl_exponent(srcp1
);
155 Sgl_all(result
) = Dbl_allp1(srcp1
); /* set sign of result */
157 * Test for NaN or infinity
159 if (src_exponent
== DBL_INFINITY_EXPONENT
) {
161 * determine if NaN or infinity
163 if (Dbl_iszero_mantissa(srcp1
,srcp2
)) {
165 * is infinity; want to return single infinity
167 Sgl_setinfinity_exponentmantissa(result
);
172 * is NaN; signaling or quiet?
174 if (Dbl_isone_signaling(srcp1
)) {
175 /* trap if INVALIDTRAP enabled */
176 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION
);
180 Dbl_set_quiet(srcp1
);
184 * NaN is quiet, return as single NaN
186 Sgl_setinfinity_exponent(result
);
187 Sgl_set_mantissa(result
,Dallp1(srcp1
)<<3 | Dallp2(srcp2
)>>29);
188 if (Sgl_iszero_mantissa(result
)) Sgl_set_quiet(result
);
195 Dbl_to_sgl_exponent(src_exponent
,dest_exponent
);
196 if (dest_exponent
> 0) {
197 Dbl_to_sgl_mantissa(srcp1
,srcp2
,dest_mantissa
,inexact
,guardbit
,
201 if (Dbl_iszero_exponentmantissa(srcp1
,srcp2
)){
202 Sgl_setzero_exponentmantissa(result
);
206 if (Is_underflowtrap_enabled()) {
207 Dbl_to_sgl_mantissa(srcp1
,srcp2
,dest_mantissa
,inexact
,
208 guardbit
,stickybit
,lsb_odd
);
211 /* compute result, determine inexact info,
212 * and set Underflowflag if appropriate
214 Dbl_to_sgl_denormalized(srcp1
,srcp2
,dest_exponent
,
215 dest_mantissa
,inexact
,guardbit
,stickybit
,lsb_odd
,
220 * Now round result if not exact
223 switch (Rounding_mode()) {
225 if (Sgl_iszero_sign(result
)) dest_mantissa
++;
228 if (Sgl_isone_sign(result
)) dest_mantissa
++;
232 if (stickybit
|| lsb_odd
) dest_mantissa
++;
236 Sgl_set_exponentmantissa(result
,dest_mantissa
);
239 * check for mantissa overflow after rounding
241 if ((dest_exponent
>0 || Is_underflowtrap_enabled()) &&
242 Sgl_isone_hidden(result
)) dest_exponent
++;
247 if (dest_exponent
>= SGL_INFINITY_EXPONENT
) {
248 /* trap if OVERFLOWTRAP enabled */
249 if (Is_overflowtrap_enabled()) {
251 * Check for gross overflow
253 if (dest_exponent
>= SGL_INFINITY_EXPONENT
+SGL_WRAP
)
254 return(UNIMPLEMENTEDEXCEPTION
);
257 * Adjust bias of result
259 Sgl_setwrapped_exponent(result
,dest_exponent
,ovfl
);
262 if (Is_inexacttrap_enabled())
263 return(OVERFLOWEXCEPTION
|INEXACTEXCEPTION
);
264 else Set_inexactflag();
265 return(OVERFLOWEXCEPTION
);
269 /* set result to infinity or largest number */
270 Sgl_setoverflow(result
);
275 else if (dest_exponent
<= 0) {
276 /* trap if UNDERFLOWTRAP enabled */
277 if (Is_underflowtrap_enabled()) {
279 * Check for gross underflow
281 if (dest_exponent
<= -(SGL_WRAP
))
282 return(UNIMPLEMENTEDEXCEPTION
);
284 * Adjust bias of result
286 Sgl_setwrapped_exponent(result
,dest_exponent
,unfl
);
289 if (Is_inexacttrap_enabled())
290 return(UNDERFLOWEXCEPTION
|INEXACTEXCEPTION
);
291 else Set_inexactflag();
292 return(UNDERFLOWEXCEPTION
);
295 * result is denormalized or signed zero
297 if (inexact
&& is_tiny
) Set_underflowflag();
300 else Sgl_set_exponent(result
,dest_exponent
);
303 * Trap if inexact trap is enabled
306 if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION
);
307 else Set_inexactflag();