1 /* $NetBSD: fcnvff.c,v 1.1 2002/06/05 01:04:25 fredette Exp $ */ 2 3 /* $OpenBSD: fcnvff.c,v 1.5 2001/03/29 03:58:18 mickey Exp $ */ 4 5 /* 6 * Copyright 1996 1995 by Open Software Foundation, Inc. 7 * All Rights Reserved 8 * 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. 14 * 15 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 17 * FOR A PARTICULAR PURPOSE. 18 * 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. 24 * 25 */ 26 /* 27 * pmk1.1 28 */ 29 /* 30 * (c) Copyright 1986 HEWLETT-PACKARD COMPANY 31 * 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. 42 */ 43 44 #include "../spmath/float.h" 45 #include "../spmath/sgl_float.h" 46 #include "../spmath/dbl_float.h" 47 #include "../spmath/cnv_float.h" 48 49 /* 50 * Single Floating-point to Double Floating-point 51 */ 52 /*ARGSUSED*/ 53 int 54 sgl_to_dbl_fcnvff(srcptr,dstptr,status) 55 56 sgl_floating_point *srcptr; 57 dbl_floating_point *dstptr; 58 unsigned int *status; 59 { 60 register unsigned int src, resultp1, resultp2; 61 register int src_exponent; 62 63 src = *srcptr; 64 src_exponent = Sgl_exponent(src); 65 Dbl_allp1(resultp1) = Sgl_all(src); /* set sign of result */ 66 /* 67 * Test for NaN or infinity 68 */ 69 if (src_exponent == SGL_INFINITY_EXPONENT) { 70 /* 71 * determine if NaN or infinity 72 */ 73 if (Sgl_iszero_mantissa(src)) { 74 /* 75 * is infinity; want to return double infinity 76 */ 77 Dbl_setinfinity_exponentmantissa(resultp1,resultp2); 78 Dbl_copytoptr(resultp1,resultp2,dstptr); 79 return(NOEXCEPTION); 80 } 81 else { 82 /* 83 * is NaN; signaling or quiet? 84 */ 85 if (Sgl_isone_signaling(src)) { 86 /* trap if INVALIDTRAP enabled */ 87 if (Is_invalidtrap_enabled()) 88 return(INVALIDEXCEPTION); 89 /* make NaN quiet */ 90 else { 91 Set_invalidflag(); 92 Sgl_set_quiet(src); 93 } 94 } 95 /* 96 * NaN is quiet, return as double NaN 97 */ 98 Dbl_setinfinity_exponent(resultp1); 99 Sgl_to_dbl_mantissa(src,resultp1,resultp2); 100 Dbl_copytoptr(resultp1,resultp2,dstptr); 101 return(NOEXCEPTION); 102 } 103 } 104 /* 105 * Test for zero or denormalized 106 */ 107 if (src_exponent == 0) { 108 /* 109 * determine if zero or denormalized 110 */ 111 if (Sgl_isnotzero_mantissa(src)) { 112 /* 113 * is denormalized; want to normalize 114 */ 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); 120 } 121 else { 122 Dbl_setzero_exponentmantissa(resultp1,resultp2); 123 } 124 Dbl_copytoptr(resultp1,resultp2,dstptr); 125 return(NOEXCEPTION); 126 } 127 /* 128 * No special cases, just complete the conversion 129 */ 130 Sgl_to_dbl_exponent(src_exponent, resultp1); 131 Sgl_to_dbl_mantissa(Sgl_mantissa(src), resultp1,resultp2); 132 Dbl_copytoptr(resultp1,resultp2,dstptr); 133 return(NOEXCEPTION); 134 } 135 136 /* 137 * Double Floating-point to Single Floating-point 138 */ 139 /*ARGSUSED*/ 140 int 141 dbl_to_sgl_fcnvff(srcptr,dstptr,status) 142 143 dbl_floating_point *srcptr; 144 sgl_floating_point *dstptr; 145 unsigned int *status; 146 { 147 register unsigned int srcp1, srcp2, result; 148 register int src_exponent, dest_exponent, dest_mantissa; 149 register int inexact = FALSE, guardbit = FALSE, stickybit = FALSE; 150 register int lsb_odd = FALSE; 151 int is_tiny; 152 153 Dbl_copyfromptr(srcptr,srcp1,srcp2); 154 src_exponent = Dbl_exponent(srcp1); 155 Sgl_all(result) = Dbl_allp1(srcp1); /* set sign of result */ 156 /* 157 * Test for NaN or infinity 158 */ 159 if (src_exponent == DBL_INFINITY_EXPONENT) { 160 /* 161 * determine if NaN or infinity 162 */ 163 if (Dbl_iszero_mantissa(srcp1,srcp2)) { 164 /* 165 * is infinity; want to return single infinity 166 */ 167 Sgl_setinfinity_exponentmantissa(result); 168 *dstptr = result; 169 return(NOEXCEPTION); 170 } 171 /* 172 * is NaN; signaling or quiet? 173 */ 174 if (Dbl_isone_signaling(srcp1)) { 175 /* trap if INVALIDTRAP enabled */ 176 if (Is_invalidtrap_enabled()) return(INVALIDEXCEPTION); 177 else { 178 Set_invalidflag(); 179 /* make NaN quiet */ 180 Dbl_set_quiet(srcp1); 181 } 182 } 183 /* 184 * NaN is quiet, return as single NaN 185 */ 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); 189 *dstptr = result; 190 return(NOEXCEPTION); 191 } 192 /* 193 * Generate result 194 */ 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, 198 stickybit,lsb_odd); 199 } 200 else { 201 if (Dbl_iszero_exponentmantissa(srcp1,srcp2)){ 202 Sgl_setzero_exponentmantissa(result); 203 *dstptr = result; 204 return(NOEXCEPTION); 205 } 206 if (Is_underflowtrap_enabled()) { 207 Dbl_to_sgl_mantissa(srcp1,srcp2,dest_mantissa,inexact, 208 guardbit,stickybit,lsb_odd); 209 } 210 else { 211 /* compute result, determine inexact info, 212 * and set Underflowflag if appropriate 213 */ 214 Dbl_to_sgl_denormalized(srcp1,srcp2,dest_exponent, 215 dest_mantissa,inexact,guardbit,stickybit,lsb_odd, 216 is_tiny); 217 } 218 } 219 /* 220 * Now round result if not exact 221 */ 222 if (inexact) { 223 switch (Rounding_mode()) { 224 case ROUNDPLUS: 225 if (Sgl_iszero_sign(result)) dest_mantissa++; 226 break; 227 case ROUNDMINUS: 228 if (Sgl_isone_sign(result)) dest_mantissa++; 229 break; 230 case ROUNDNEAREST: 231 if (guardbit) { 232 if (stickybit || lsb_odd) dest_mantissa++; 233 } 234 } 235 } 236 Sgl_set_exponentmantissa(result,dest_mantissa); 237 238 /* 239 * check for mantissa overflow after rounding 240 */ 241 if ((dest_exponent>0 || Is_underflowtrap_enabled()) && 242 Sgl_isone_hidden(result)) dest_exponent++; 243 244 /* 245 * Test for overflow 246 */ 247 if (dest_exponent >= SGL_INFINITY_EXPONENT) { 248 /* trap if OVERFLOWTRAP enabled */ 249 if (Is_overflowtrap_enabled()) { 250 /* 251 * Check for gross overflow 252 */ 253 if (dest_exponent >= SGL_INFINITY_EXPONENT+SGL_WRAP) 254 return(UNIMPLEMENTEDEXCEPTION); 255 256 /* 257 * Adjust bias of result 258 */ 259 Sgl_setwrapped_exponent(result,dest_exponent,ovfl); 260 *dstptr = result; 261 if (inexact) { 262 if (Is_inexacttrap_enabled()) 263 return(OVERFLOWEXCEPTION|INEXACTEXCEPTION); 264 else 265 Set_inexactflag(); 266 } 267 return(OVERFLOWEXCEPTION); 268 } 269 Set_overflowflag(); 270 inexact = TRUE; 271 /* set result to infinity or largest number */ 272 Sgl_setoverflow(result); 273 } 274 /* 275 * Test for underflow 276 */ 277 else if (dest_exponent <= 0) { 278 /* trap if UNDERFLOWTRAP enabled */ 279 if (Is_underflowtrap_enabled()) { 280 /* 281 * Check for gross underflow 282 */ 283 if (dest_exponent <= -(SGL_WRAP)) 284 return(UNIMPLEMENTEDEXCEPTION); 285 /* 286 * Adjust bias of result 287 */ 288 Sgl_setwrapped_exponent(result,dest_exponent,unfl); 289 *dstptr = result; 290 if (inexact) { 291 if (Is_inexacttrap_enabled()) 292 return(UNDERFLOWEXCEPTION|INEXACTEXCEPTION); 293 else 294 Set_inexactflag(); 295 } 296 return(UNDERFLOWEXCEPTION); 297 } 298 /* 299 * result is denormalized or signed zero 300 */ 301 if (inexact && is_tiny) Set_underflowflag(); 302 303 } 304 else Sgl_set_exponent(result,dest_exponent); 305 *dstptr = result; 306 /* 307 * Trap if inexact trap is enabled 308 */ 309 if (inexact) { 310 if (Is_inexacttrap_enabled()) 311 return(INEXACTEXCEPTION); 312 else 313 Set_inexactflag(); 314 } 315 return(NOEXCEPTION); 316 } 317