Annotation of sys/arch/hppa/spmath/fcnvxf.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: fcnvxf.c,v 1.7 2003/04/10 17:27:58 mickey Exp $ */
! 2: /*
! 3: (c) Copyright 1986 HEWLETT-PACKARD COMPANY
! 4: To anyone who acknowledges that this file is provided "AS IS"
! 5: without any express or implied warranty:
! 6: permission to use, copy, modify, and distribute this file
! 7: for any purpose is hereby granted without fee, provided that
! 8: the above copyright notice and this notice appears in all
! 9: copies, and that the name of Hewlett-Packard Company not be
! 10: used in advertising or publicity pertaining to distribution
! 11: of the software without specific, written prior permission.
! 12: Hewlett-Packard Company makes no representations about the
! 13: suitability of this software for any purpose.
! 14: */
! 15: /* @(#)fcnvxf.c: Revision: 2.7.88.1 Date: 93/12/07 15:06:16 */
! 16:
! 17: #include "float.h"
! 18: #include "sgl_float.h"
! 19: #include "dbl_float.h"
! 20: #include "cnv_float.h"
! 21:
! 22: /*
! 23: * Convert single fixed-point to single floating-point format
! 24: */
! 25: int
! 26: sgl_to_sgl_fcnvxf(srcptr, null, dstptr, status)
! 27: int *srcptr, *null;
! 28: sgl_floating_point *dstptr;
! 29: unsigned int *status;
! 30: {
! 31: register int src, dst_exponent;
! 32: register unsigned int result = 0;
! 33:
! 34: src = *srcptr;
! 35: /*
! 36: * set sign bit of result and get magnitude of source
! 37: */
! 38: if (src < 0) {
! 39: Sgl_setone_sign(result);
! 40: Int_negate(src);
! 41: }
! 42: else {
! 43: Sgl_setzero_sign(result);
! 44: /* Check for zero */
! 45: if (src == 0) {
! 46: Sgl_setzero(result);
! 47: *dstptr = result;
! 48: return(NOEXCEPTION);
! 49: }
! 50: }
! 51: /*
! 52: * Generate exponent and normalized mantissa
! 53: */
! 54: dst_exponent = 16; /* initialize for normalization */
! 55: /*
! 56: * Check word for most significant bit set. Returns
! 57: * a value in dst_exponent indicating the bit position,
! 58: * between -1 and 30.
! 59: */
! 60: Find_ms_one_bit(src,dst_exponent);
! 61: /* left justify source, with msb at bit position 1 */
! 62: if (dst_exponent >= 0) src <<= dst_exponent;
! 63: else src = 1 << 30;
! 64: Sgl_set_mantissa(result, src >> (SGL_EXP_LENGTH-1));
! 65: Sgl_set_exponent(result, 30+SGL_BIAS - dst_exponent);
! 66:
! 67: /* check for inexact */
! 68: if (Int_isinexact_to_sgl(src)) {
! 69: switch (Rounding_mode()) {
! 70: case ROUNDPLUS:
! 71: if (Sgl_iszero_sign(result))
! 72: Sgl_increment(result);
! 73: break;
! 74: case ROUNDMINUS:
! 75: if (Sgl_isone_sign(result))
! 76: Sgl_increment(result);
! 77: break;
! 78: case ROUNDNEAREST:
! 79: Sgl_roundnearest_from_int(src,result);
! 80: }
! 81: if (Is_inexacttrap_enabled()) {
! 82: *dstptr = result;
! 83: return(INEXACTEXCEPTION);
! 84: }
! 85: else Set_inexactflag();
! 86: }
! 87: *dstptr = result;
! 88: return(NOEXCEPTION);
! 89: }
! 90:
! 91: /*
! 92: * Single Fixed-point to Double Floating-point
! 93: */
! 94: int
! 95: sgl_to_dbl_fcnvxf(srcptr, null, dstptr, status)
! 96: int *srcptr, *null;
! 97: dbl_floating_point *dstptr;
! 98: unsigned int *status;
! 99: {
! 100: register int src, dst_exponent;
! 101: register unsigned int resultp1 = 0, resultp2 = 0;
! 102:
! 103: src = *srcptr;
! 104: /*
! 105: * set sign bit of result and get magnitude of source
! 106: */
! 107: if (src < 0) {
! 108: Dbl_setone_sign(resultp1);
! 109: Int_negate(src);
! 110: }
! 111: else {
! 112: Dbl_setzero_sign(resultp1);
! 113: /* Check for zero */
! 114: if (src == 0) {
! 115: Dbl_setzero(resultp1,resultp2);
! 116: Dbl_copytoptr(resultp1,resultp2,dstptr);
! 117: return(NOEXCEPTION);
! 118: }
! 119: }
! 120: /*
! 121: * Generate exponent and normalized mantissa
! 122: */
! 123: dst_exponent = 16; /* initialize for normalization */
! 124: /*
! 125: * Check word for most significant bit set. Returns
! 126: * a value in dst_exponent indicating the bit position,
! 127: * between -1 and 30.
! 128: */
! 129: Find_ms_one_bit(src,dst_exponent);
! 130: /* left justify source, with msb at bit position 1 */
! 131: if (dst_exponent >= 0) src <<= dst_exponent;
! 132: else src = 1 << 30;
! 133: Dbl_set_mantissap1(resultp1, (src >> (DBL_EXP_LENGTH - 1)));
! 134: Dbl_set_mantissap2(resultp2, (src << (33-DBL_EXP_LENGTH)));
! 135: Dbl_set_exponent(resultp1, (30+DBL_BIAS) - dst_exponent);
! 136: Dbl_copytoptr(resultp1,resultp2,dstptr);
! 137: return(NOEXCEPTION);
! 138: }
! 139:
! 140: /*
! 141: * Double Fixed-point to Single Floating-point
! 142: */
! 143: int
! 144: dbl_to_sgl_fcnvxf(srcptr, null, dstptr, status)
! 145: dbl_integer *srcptr, *null;
! 146: sgl_floating_point *dstptr;
! 147: unsigned int *status;
! 148: {
! 149: int dst_exponent, srcp1;
! 150: unsigned int result = 0, srcp2;
! 151:
! 152: Dint_copyfromptr(srcptr,srcp1,srcp2);
! 153: /*
! 154: * set sign bit of result and get magnitude of source
! 155: */
! 156: if (srcp1 < 0) {
! 157: Sgl_setone_sign(result);
! 158: Dint_negate(srcp1,srcp2);
! 159: }
! 160: else {
! 161: Sgl_setzero_sign(result);
! 162: /* Check for zero */
! 163: if (srcp1 == 0 && srcp2 == 0) {
! 164: Sgl_setzero(result);
! 165: *dstptr = result;
! 166: return(NOEXCEPTION);
! 167: }
! 168: }
! 169: /*
! 170: * Generate exponent and normalized mantissa
! 171: */
! 172: dst_exponent = 16; /* initialize for normalization */
! 173: if (srcp1 == 0) {
! 174: /*
! 175: * Check word for most significant bit set. Returns
! 176: * a value in dst_exponent indicating the bit position,
! 177: * between -1 and 30.
! 178: */
! 179: Find_ms_one_bit(srcp2,dst_exponent);
! 180: /* left justify source, with msb at bit position 1 */
! 181: if (dst_exponent >= 0) {
! 182: srcp1 = srcp2 << dst_exponent;
! 183: srcp2 = 0;
! 184: }
! 185: else {
! 186: srcp1 = srcp2 >> 1;
! 187: srcp2 <<= 31;
! 188: }
! 189: /*
! 190: * since msb set is in second word, need to
! 191: * adjust bit position count
! 192: */
! 193: dst_exponent += 32;
! 194: }
! 195: else {
! 196: /*
! 197: * Check word for most significant bit set. Returns
! 198: * a value in dst_exponent indicating the bit position,
! 199: * between -1 and 30.
! 200: *
! 201: */
! 202: Find_ms_one_bit(srcp1,dst_exponent);
! 203: /* left justify source, with msb at bit position 1 */
! 204: if (dst_exponent > 0) {
! 205: Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
! 206: srcp1);
! 207: srcp2 <<= dst_exponent;
! 208: }
! 209: /*
! 210: * If dst_exponent = 0, we don't need to shift anything.
! 211: * If dst_exponent = -1, src = - 2**63 so we won't need to
! 212: * shift srcp2.
! 213: */
! 214: else srcp1 >>= -(dst_exponent);
! 215: }
! 216: Sgl_set_mantissa(result, (srcp1 >> (SGL_EXP_LENGTH - 1)));
! 217: Sgl_set_exponent(result, (62+SGL_BIAS) - dst_exponent);
! 218:
! 219: /* check for inexact */
! 220: if (Dint_isinexact_to_sgl(srcp1,srcp2)) {
! 221: switch (Rounding_mode()) {
! 222: case ROUNDPLUS:
! 223: if (Sgl_iszero_sign(result))
! 224: Sgl_increment(result);
! 225: break;
! 226: case ROUNDMINUS:
! 227: if (Sgl_isone_sign(result))
! 228: Sgl_increment(result);
! 229: break;
! 230: case ROUNDNEAREST:
! 231: Sgl_roundnearest_from_dint(srcp1,srcp2,result);
! 232: }
! 233: if (Is_inexacttrap_enabled()) {
! 234: *dstptr = result;
! 235: return(INEXACTEXCEPTION);
! 236: }
! 237: else Set_inexactflag();
! 238: }
! 239: *dstptr = result;
! 240: return(NOEXCEPTION);
! 241: }
! 242:
! 243: /*
! 244: * Double Fixed-point to Double Floating-point
! 245: */
! 246: int
! 247: dbl_to_dbl_fcnvxf(srcptr, null, dstptr, status)
! 248: dbl_integer *srcptr, *null;
! 249: dbl_floating_point *dstptr;
! 250: unsigned int *status;
! 251: {
! 252: register int srcp1, dst_exponent;
! 253: register unsigned int srcp2, resultp1 = 0, resultp2 = 0;
! 254:
! 255: Dint_copyfromptr(srcptr,srcp1,srcp2);
! 256: /*
! 257: * set sign bit of result and get magnitude of source
! 258: */
! 259: if (srcp1 < 0) {
! 260: Dbl_setone_sign(resultp1);
! 261: Dint_negate(srcp1,srcp2);
! 262: }
! 263: else {
! 264: Dbl_setzero_sign(resultp1);
! 265: /* Check for zero */
! 266: if (srcp1 == 0 && srcp2 ==0) {
! 267: Dbl_setzero(resultp1,resultp2);
! 268: Dbl_copytoptr(resultp1,resultp2,dstptr);
! 269: return(NOEXCEPTION);
! 270: }
! 271: }
! 272: /*
! 273: * Generate exponent and normalized mantissa
! 274: */
! 275: dst_exponent = 16; /* initialize for normalization */
! 276: if (srcp1 == 0) {
! 277: /*
! 278: * Check word for most significant bit set. Returns
! 279: * a value in dst_exponent indicating the bit position,
! 280: * between -1 and 30.
! 281: */
! 282: Find_ms_one_bit(srcp2,dst_exponent);
! 283: /* left justify source, with msb at bit position 1 */
! 284: if (dst_exponent >= 0) {
! 285: srcp1 = srcp2 << dst_exponent;
! 286: srcp2 = 0;
! 287: }
! 288: else {
! 289: srcp1 = srcp2 >> 1;
! 290: srcp2 <<= 31;
! 291: }
! 292: /*
! 293: * since msb set is in second word, need to
! 294: * adjust bit position count
! 295: */
! 296: dst_exponent += 32;
! 297: }
! 298: else {
! 299: /*
! 300: * Check word for most significant bit set. Returns
! 301: * a value in dst_exponent indicating the bit position,
! 302: * between -1 and 30.
! 303: */
! 304: Find_ms_one_bit(srcp1,dst_exponent);
! 305: /* left justify source, with msb at bit position 1 */
! 306: if (dst_exponent > 0) {
! 307: Variable_shift_double(srcp1,srcp2,(32-dst_exponent),
! 308: srcp1);
! 309: srcp2 <<= dst_exponent;
! 310: }
! 311: /*
! 312: * If dst_exponent = 0, we don't need to shift anything.
! 313: * If dst_exponent = -1, src = - 2**63 so we won't need to
! 314: * shift srcp2.
! 315: */
! 316: else srcp1 >>= -(dst_exponent);
! 317: }
! 318: Dbl_set_mantissap1(resultp1, srcp1 >> (DBL_EXP_LENGTH-1));
! 319: Shiftdouble(srcp1,srcp2,DBL_EXP_LENGTH-1,resultp2);
! 320: Dbl_set_exponent(resultp1, (62+DBL_BIAS) - dst_exponent);
! 321:
! 322: /* check for inexact */
! 323: if (Dint_isinexact_to_dbl(srcp2)) {
! 324: switch (Rounding_mode()) {
! 325: case ROUNDPLUS:
! 326: if (Dbl_iszero_sign(resultp1)) {
! 327: Dbl_increment(resultp1,resultp2);
! 328: }
! 329: break;
! 330: case ROUNDMINUS:
! 331: if (Dbl_isone_sign(resultp1)) {
! 332: Dbl_increment(resultp1,resultp2);
! 333: }
! 334: break;
! 335: case ROUNDNEAREST:
! 336: Dbl_roundnearest_from_dint(srcp2,resultp1,
! 337: resultp2);
! 338: }
! 339: if (Is_inexacttrap_enabled()) {
! 340: Dbl_copytoptr(resultp1,resultp2,dstptr);
! 341: return(INEXACTEXCEPTION);
! 342: }
! 343: else Set_inexactflag();
! 344: }
! 345: Dbl_copytoptr(resultp1,resultp2,dstptr);
! 346: return(NOEXCEPTION);
! 347: }
CVSweb