1 /* $NetBSD: fcnvxf.c,v 1.1 2002/06/05 01:04:25 fredette Exp $ */ 2 3 /* $OpenBSD: fcnvxf.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 * Convert single fixed-point to single floating-point format 51 */ 52 int 53 sgl_to_sgl_fcnvxf(srcptr,dstptr,status) 54 55 int *srcptr; 56 sgl_floating_point *dstptr; 57 unsigned int *status; 58 { 59 register int src, dst_exponent; 60 register unsigned int result = 0; 61 62 src = *srcptr; 63 /* 64 * set sign bit of result and get magnitude of source 65 */ 66 if (src < 0) { 67 Sgl_setone_sign(result); 68 Int_negate(src); 69 } 70 else { 71 Sgl_setzero_sign(result); 72 /* Check for zero */ 73 if (src == 0) { 74 Sgl_setzero(result); 75 *dstptr = result; 76 return(NOEXCEPTION); 77 } 78 } 79 /* 80 * Generate exponent and normalized mantissa 81 */ 82 dst_exponent = 16; /* initialize for normalization */ 83 /* 84 * Check word for most significant bit set. Returns 85 * a value in dst_exponent indicating the bit position, 86 * between -1 and 30. 87 */ 88 Find_ms_one_bit(src,dst_exponent); 89 /* left justify source, with msb at bit position 1 */ 90 if (dst_exponent >= 0) src <<= dst_exponent; 91 else src = 1 << 30; 92 Sgl_set_mantissa(result, src >> (SGL_EXP_LENGTH-1)); 93 Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent); 94 95 /* check for inexact */ 96 if (Int_isinexact_to_sgl(src)) { 97 switch (Rounding_mode()) { 98 case ROUNDPLUS: 99 if (Sgl_iszero_sign(result)) 100 Sgl_increment(result); 101 break; 102 case ROUNDMINUS: 103 if (Sgl_isone_sign(result)) 104 Sgl_increment(result); 105 break; 106 case ROUNDNEAREST: 107 Sgl_roundnearest_from_int(src,result); 108 } 109 if (Is_inexacttrap_enabled()) { 110 *dstptr = result; 111 return(INEXACTEXCEPTION); 112 } 113 else Set_inexactflag(); 114 } 115 *dstptr = result; 116 return(NOEXCEPTION); 117 } 118 119 /* 120 * Single Fixed-point to Double Floating-point 121 */ 122 int 123 sgl_to_dbl_fcnvxf(srcptr,dstptr,status) 124 125 int *srcptr; 126 dbl_floating_point *dstptr; 127 unsigned int *status; 128 { 129 register int src, dst_exponent; 130 register unsigned int resultp1 = 0, resultp2 = 0; 131 132 src = *srcptr; 133 /* 134 * set sign bit of result and get magnitude of source 135 */ 136 if (src < 0) { 137 Dbl_setone_sign(resultp1); 138 Int_negate(src); 139 } 140 else { 141 Dbl_setzero_sign(resultp1); 142 /* Check for zero */ 143 if (src == 0) { 144 Dbl_setzero(resultp1,resultp2); 145 Dbl_copytoptr(resultp1,resultp2,dstptr); 146 return(NOEXCEPTION); 147 } 148 } 149 /* 150 * Generate exponent and normalized mantissa 151 */ 152 dst_exponent = 16; /* initialize for normalization */ 153 /* 154 * Check word for most significant bit set. Returns 155 * a value in dst_exponent indicating the bit position, 156 * between -1 and 30. 157 */ 158 Find_ms_one_bit(src,dst_exponent); 159 /* left justify source, with msb at bit position 1 */ 160 if (dst_exponent >= 0) src <<= dst_exponent; 161 else src = 1 << 30; 162 Dbl_set_mantissap1(resultp1, (src >> (DBL_EXP_LENGTH - 1))); 163 Dbl_set_mantissap2(resultp2, (src << (33-DBL_EXP_LENGTH))); 164 Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent); 165 Dbl_copytoptr(resultp1,resultp2,dstptr); 166 return(NOEXCEPTION); 167 } 168 169 /* 170 * Double Fixed-point to Single Floating-point 171 */ 172 int 173 dbl_to_sgl_fcnvxf(srcptr,dstptr,status) 174 175 dbl_integer *srcptr; 176 sgl_floating_point *dstptr; 177 unsigned int *status; 178 { 179 int dst_exponent, srcp1; 180 unsigned int result = 0, srcp2; 181 182 Dint_copyfromptr(srcptr,srcp1,srcp2); 183 /* 184 * set sign bit of result and get magnitude of source 185 */ 186 if (srcp1 < 0) { 187 Sgl_setone_sign(result); 188 Dint_negate(srcp1,srcp2); 189 } 190 else { 191 Sgl_setzero_sign(result); 192 /* Check for zero */ 193 if (srcp1 == 0 && srcp2 == 0) { 194 Sgl_setzero(result); 195 *dstptr = result; 196 return(NOEXCEPTION); 197 } 198 } 199 /* 200 * Generate exponent and normalized mantissa 201 */ 202 dst_exponent = 16; /* initialize for normalization */ 203 if (srcp1 == 0) { 204 /* 205 * Check word for most significant bit set. Returns 206 * a value in dst_exponent indicating the bit position, 207 * between -1 and 30. 208 */ 209 Find_ms_one_bit(srcp2,dst_exponent); 210 /* left justify source, with msb at bit position 1 */ 211 if (dst_exponent >= 0) { 212 srcp1 = srcp2 << dst_exponent; 213 srcp2 = 0; 214 } 215 else { 216 srcp1 = srcp2 >> 1; 217 srcp2 <<= 31; 218 } 219 /* 220 * since msb set is in second word, need to 221 * adjust bit position count 222 */ 223 dst_exponent += 32; 224 } 225 else { 226 /* 227 * Check word for most significant bit set. Returns 228 * a value in dst_exponent indicating the bit position, 229 * between -1 and 30. 230 * 231 */ 232 Find_ms_one_bit(srcp1,dst_exponent); 233 /* left justify source, with msb at bit position 1 */ 234 if (dst_exponent > 0) { 235 Variable_shift_double(srcp1,srcp2,(32-dst_exponent), 236 srcp1); 237 srcp2 <<= dst_exponent; 238 } 239 /* 240 * If dst_exponent = 0, we don't need to shift anything. 241 * If dst_exponent = -1, src = - 2**63 so we won't need to 242 * shift srcp2. 243 */ 244 else srcp1 >>= -(dst_exponent); 245 } 246 Sgl_set_mantissa(result, (srcp1 >> (SGL_EXP_LENGTH - 1))); 247 Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent); 248 249 /* check for inexact */ 250 if (Dint_isinexact_to_sgl(srcp1,srcp2)) { 251 switch (Rounding_mode()) { 252 case ROUNDPLUS: 253 if (Sgl_iszero_sign(result)) 254 Sgl_increment(result); 255 break; 256 case ROUNDMINUS: 257 if (Sgl_isone_sign(result)) 258 Sgl_increment(result); 259 break; 260 case ROUNDNEAREST: 261 Sgl_roundnearest_from_dint(srcp1,srcp2,result); 262 } 263 if (Is_inexacttrap_enabled()) { 264 *dstptr = result; 265 return(INEXACTEXCEPTION); 266 } 267 else Set_inexactflag(); 268 } 269 *dstptr = result; 270 return(NOEXCEPTION); 271 } 272 273 /* 274 * Double Fixed-point to Double Floating-point 275 */ 276 int 277 dbl_to_dbl_fcnvxf(srcptr,dstptr,status) 278 279 dbl_integer *srcptr; 280 dbl_floating_point *dstptr; 281 unsigned int *status; 282 { 283 register int srcp1, dst_exponent; 284 register unsigned int srcp2, resultp1 = 0, resultp2 = 0; 285 286 Dint_copyfromptr(srcptr,srcp1,srcp2); 287 /* 288 * set sign bit of result and get magnitude of source 289 */ 290 if (srcp1 < 0) { 291 Dbl_setone_sign(resultp1); 292 Dint_negate(srcp1,srcp2); 293 } 294 else { 295 Dbl_setzero_sign(resultp1); 296 /* Check for zero */ 297 if (srcp1 == 0 && srcp2 ==0) { 298 Dbl_setzero(resultp1,resultp2); 299 Dbl_copytoptr(resultp1,resultp2,dstptr); 300 return(NOEXCEPTION); 301 } 302 } 303 /* 304 * Generate exponent and normalized mantissa 305 */ 306 dst_exponent = 16; /* initialize for normalization */ 307 if (srcp1 == 0) { 308 /* 309 * Check word for most significant bit set. Returns 310 * a value in dst_exponent indicating the bit position, 311 * between -1 and 30. 312 */ 313 Find_ms_one_bit(srcp2,dst_exponent); 314 /* left justify source, with msb at bit position 1 */ 315 if (dst_exponent >= 0) { 316 srcp1 = srcp2 << dst_exponent; 317 srcp2 = 0; 318 } 319 else { 320 srcp1 = srcp2 >> 1; 321 srcp2 <<= 31; 322 } 323 /* 324 * since msb set is in second word, need to 325 * adjust bit position count 326 */ 327 dst_exponent += 32; 328 } 329 else { 330 /* 331 * Check word for most significant bit set. Returns 332 * a value in dst_exponent indicating the bit position, 333 * between -1 and 30. 334 */ 335 Find_ms_one_bit(srcp1,dst_exponent); 336 /* left justify source, with msb at bit position 1 */ 337 if (dst_exponent > 0) { 338 Variable_shift_double(srcp1,srcp2,(32-dst_exponent), 339 srcp1); 340 srcp2 <<= dst_exponent; 341 } 342 /* 343 * If dst_exponent = 0, we don't need to shift anything. 344 * If dst_exponent = -1, src = - 2**63 so we won't need to 345 * shift srcp2. 346 */ 347 else srcp1 >>= -(dst_exponent); 348 } 349 Dbl_set_mantissap1(resultp1, srcp1 >> (DBL_EXP_LENGTH-1)); 350 Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH-1,resultp2); 351 Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent); 352 353 /* check for inexact */ 354 if (Dint_isinexact_to_dbl(srcp2)) { 355 switch (Rounding_mode()) { 356 case ROUNDPLUS: 357 if (Dbl_iszero_sign(resultp1)) { 358 Dbl_increment(resultp1,resultp2); 359 } 360 break; 361 case ROUNDMINUS: 362 if (Dbl_isone_sign(resultp1)) { 363 Dbl_increment(resultp1,resultp2); 364 } 365 break; 366 case ROUNDNEAREST: 367 Dbl_roundnearest_from_dint(srcp2,resultp1, 368 resultp2); 369 } 370 if (Is_inexacttrap_enabled()) { 371 Dbl_copytoptr(resultp1,resultp2,dstptr); 372 return(INEXACTEXCEPTION); 373 } 374 else Set_inexactflag(); 375 } 376 Dbl_copytoptr(resultp1,resultp2,dstptr); 377 return(NOEXCEPTION); 378 } 379