Annotation of sys/arch/hppa/spmath/fcnvfx.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: fcnvfx.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: /* @(#)fcnvfx.c: Revision: 2.8.88.2 Date: 93/12/08 13:27:29 */
! 16:
! 17: #include "float.h"
! 18: #include "sgl_float.h"
! 19: #include "dbl_float.h"
! 20: #include "cnv_float.h"
! 21:
! 22: /*
! 23: * Single Floating-point to Single Fixed-point
! 24: */
! 25: /*ARGSUSED*/
! 26: int
! 27: sgl_to_sgl_fcnvfx(srcptr, null, dstptr, status)
! 28: sgl_floating_point *srcptr, *null;
! 29: int *dstptr;
! 30: unsigned int *status;
! 31: {
! 32: register unsigned int src, temp;
! 33: register int src_exponent, result;
! 34: register int inexact = FALSE;
! 35:
! 36: src = *srcptr;
! 37: src_exponent = Sgl_exponent(src) - SGL_BIAS;
! 38:
! 39: /*
! 40: * Test for overflow
! 41: */
! 42: if (src_exponent > SGL_FX_MAX_EXP) {
! 43: /* check for MININT */
! 44: if ((src_exponent > SGL_FX_MAX_EXP + 1) ||
! 45: Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
! 46: if( Sgl_isnan(src) )
! 47: /*
! 48: * On NaN go unimplemented.
! 49: */
! 50: return(UNIMPLEMENTEDEXCEPTION);
! 51: else {
! 52: if (Sgl_iszero_sign(src)) result = 0x7fffffff;
! 53: else result = 0x80000000;
! 54:
! 55: if (Is_overflowtrap_enabled()) {
! 56: if (Is_inexacttrap_enabled())
! 57: return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
! 58: else Set_inexactflag();
! 59: return(OVERFLOWEXCEPTION);
! 60: }
! 61: Set_overflowflag();
! 62: *dstptr = result;
! 63: if (Is_inexacttrap_enabled() )
! 64: return(INEXACTEXCEPTION);
! 65: else Set_inexactflag();
! 66: return(NOEXCEPTION);
! 67: }
! 68: }
! 69: }
! 70: /*
! 71: * Generate result
! 72: */
! 73: if (src_exponent >= 0) {
! 74: temp = src;
! 75: Sgl_clear_signexponent_set_hidden(temp);
! 76: Int_from_sgl_mantissa(temp,src_exponent);
! 77: if (Sgl_isone_sign(src)) result = -Sgl_all(temp);
! 78: else result = Sgl_all(temp);
! 79:
! 80: /* check for inexact */
! 81: if (Sgl_isinexact_to_fix(src,src_exponent)) {
! 82: inexact = TRUE;
! 83: /* round result */
! 84: switch (Rounding_mode()) {
! 85: case ROUNDPLUS:
! 86: if (Sgl_iszero_sign(src)) result++;
! 87: break;
! 88: case ROUNDMINUS:
! 89: if (Sgl_isone_sign(src)) result--;
! 90: break;
! 91: case ROUNDNEAREST:
! 92: if (Sgl_isone_roundbit(src,src_exponent)) {
! 93: if (Sgl_isone_stickybit(src,src_exponent)
! 94: || (Sgl_isone_lowmantissa(temp))) {
! 95: if (Sgl_iszero_sign(src)) result++;
! 96: else result--;
! 97: }
! 98: }
! 99: }
! 100: }
! 101: }
! 102: else {
! 103: result = 0;
! 104:
! 105: /* check for inexact */
! 106: if (Sgl_isnotzero_exponentmantissa(src)) {
! 107: inexact = TRUE;
! 108: /* round result */
! 109: switch (Rounding_mode()) {
! 110: case ROUNDPLUS:
! 111: if (Sgl_iszero_sign(src)) result++;
! 112: break;
! 113: case ROUNDMINUS:
! 114: if (Sgl_isone_sign(src)) result--;
! 115: break;
! 116: case ROUNDNEAREST:
! 117: if (src_exponent == -1)
! 118: if (Sgl_isnotzero_mantissa(src)) {
! 119: if (Sgl_iszero_sign(src)) result++;
! 120: else result--;
! 121: }
! 122: }
! 123: }
! 124: }
! 125: *dstptr = result;
! 126: if (inexact) {
! 127: if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
! 128: else Set_inexactflag();
! 129: }
! 130: return(NOEXCEPTION);
! 131: }
! 132:
! 133: /*
! 134: * Single Floating-point to Double Fixed-point
! 135: */
! 136: /*ARGSUSED*/
! 137: int
! 138: sgl_to_dbl_fcnvfx(srcptr, null, dstptr, status)
! 139: sgl_floating_point *srcptr, *null;
! 140: dbl_integer *dstptr;
! 141: unsigned int *status;
! 142: {
! 143: register int src_exponent, resultp1;
! 144: register unsigned int src, temp, resultp2;
! 145: register int inexact = FALSE;
! 146:
! 147: src = *srcptr;
! 148: src_exponent = Sgl_exponent(src) - SGL_BIAS;
! 149:
! 150: /*
! 151: * Test for overflow
! 152: */
! 153: if (src_exponent > DBL_FX_MAX_EXP) {
! 154: /* check for MININT */
! 155: if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
! 156: Sgl_isnotzero_mantissa(src) || Sgl_iszero_sign(src)) {
! 157: if( Sgl_isnan(src) )
! 158: /*
! 159: * On NaN go unimplemented.
! 160: */
! 161: return(UNIMPLEMENTEDEXCEPTION);
! 162: else {
! 163: if (Sgl_iszero_sign(src)) {
! 164: resultp1 = 0x7fffffff;
! 165: resultp2 = 0xffffffff;
! 166: }
! 167: else {
! 168: resultp1 = 0x80000000;
! 169: resultp2 = 0;
! 170: }
! 171: if (Is_overflowtrap_enabled()) {
! 172: if (Is_inexacttrap_enabled())
! 173: return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
! 174: else Set_inexactflag();
! 175: return(OVERFLOWEXCEPTION);
! 176: }
! 177: Set_overflowflag();
! 178: Dint_copytoptr(resultp1,resultp2,dstptr);
! 179: if (Is_inexacttrap_enabled() )
! 180: return(INEXACTEXCEPTION);
! 181: else Set_inexactflag();
! 182: return(NOEXCEPTION);
! 183: }
! 184: }
! 185: Dint_set_minint(resultp1,resultp2);
! 186: Dint_copytoptr(resultp1,resultp2,dstptr);
! 187: return(NOEXCEPTION);
! 188: }
! 189: /*
! 190: * Generate result
! 191: */
! 192: if (src_exponent >= 0) {
! 193: temp = src;
! 194: Sgl_clear_signexponent_set_hidden(temp);
! 195: Dint_from_sgl_mantissa(temp,src_exponent,resultp1,resultp2);
! 196: if (Sgl_isone_sign(src)) {
! 197: Dint_setone_sign(resultp1,resultp2);
! 198: }
! 199:
! 200: /* check for inexact */
! 201: if (Sgl_isinexact_to_fix(src,src_exponent)) {
! 202: inexact = TRUE;
! 203: /* round result */
! 204: switch (Rounding_mode()) {
! 205: case ROUNDPLUS:
! 206: if (Sgl_iszero_sign(src)) {
! 207: Dint_increment(resultp1,resultp2);
! 208: }
! 209: break;
! 210: case ROUNDMINUS:
! 211: if (Sgl_isone_sign(src)) {
! 212: Dint_decrement(resultp1,resultp2);
! 213: }
! 214: break;
! 215: case ROUNDNEAREST:
! 216: if (Sgl_isone_roundbit(src,src_exponent))
! 217: if (Sgl_isone_stickybit(src,src_exponent) ||
! 218: (Dint_isone_lowp2(resultp2))) {
! 219: if (Sgl_iszero_sign(src)) {
! 220: Dint_increment(resultp1,resultp2);
! 221: }
! 222: else {
! 223: Dint_decrement(resultp1,resultp2);
! 224: }
! 225: }
! 226: }
! 227: }
! 228: }
! 229: else {
! 230: Dint_setzero(resultp1,resultp2);
! 231:
! 232: /* check for inexact */
! 233: if (Sgl_isnotzero_exponentmantissa(src)) {
! 234: inexact = TRUE;
! 235: /* round result */
! 236: switch (Rounding_mode()) {
! 237: case ROUNDPLUS:
! 238: if (Sgl_iszero_sign(src)) {
! 239: Dint_increment(resultp1,resultp2);
! 240: }
! 241: break;
! 242: case ROUNDMINUS:
! 243: if (Sgl_isone_sign(src)) {
! 244: Dint_decrement(resultp1,resultp2);
! 245: }
! 246: break;
! 247: case ROUNDNEAREST:
! 248: if (src_exponent == -1)
! 249: if (Sgl_isnotzero_mantissa(src)) {
! 250: if (Sgl_iszero_sign(src)) {
! 251: Dint_increment(resultp1,resultp2);
! 252: }
! 253: else {
! 254: Dint_decrement(resultp1,resultp2);
! 255: }
! 256: }
! 257: }
! 258: }
! 259: }
! 260: Dint_copytoptr(resultp1,resultp2,dstptr);
! 261: if (inexact) {
! 262: if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
! 263: else Set_inexactflag();
! 264: }
! 265: return(NOEXCEPTION);
! 266: }
! 267:
! 268: /*
! 269: * Double Floating-point to Single Fixed-point
! 270: */
! 271: /*ARGSUSED*/
! 272: int
! 273: dbl_to_sgl_fcnvfx(srcptr, null, dstptr, status)
! 274: dbl_floating_point *srcptr, *null;
! 275: int *dstptr;
! 276: unsigned int *status;
! 277: {
! 278: register unsigned int srcp1,srcp2, tempp1,tempp2;
! 279: register int src_exponent, result;
! 280: register int inexact = FALSE;
! 281:
! 282: Dbl_copyfromptr(srcptr,srcp1,srcp2);
! 283: src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
! 284:
! 285: /*
! 286: * Test for overflow
! 287: */
! 288: if (src_exponent > SGL_FX_MAX_EXP) {
! 289: /* check for MININT */
! 290: if (Dbl_isoverflow_to_int(src_exponent,srcp1,srcp2)) {
! 291: if( Dbl_isnan(srcp1,srcp2) )
! 292: /*
! 293: * On NaN go unimplemented.
! 294: */
! 295: return(UNIMPLEMENTEDEXCEPTION);
! 296: else {
! 297: if (Dbl_iszero_sign(srcp1)) result = 0x7fffffff;
! 298: else result = 0x80000000;
! 299:
! 300: if (Is_overflowtrap_enabled()) {
! 301: if (Is_inexacttrap_enabled())
! 302: return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
! 303: else Set_inexactflag();
! 304: return(OVERFLOWEXCEPTION);
! 305: }
! 306: Set_overflowflag();
! 307: *dstptr = result;
! 308: if (Is_inexacttrap_enabled() )
! 309: return(INEXACTEXCEPTION);
! 310: else Set_inexactflag();
! 311: return(NOEXCEPTION);
! 312: }
! 313: }
! 314: }
! 315: /*
! 316: * Generate result
! 317: */
! 318: if (src_exponent >= 0) {
! 319: tempp1 = srcp1;
! 320: tempp2 = srcp2;
! 321: Dbl_clear_signexponent_set_hidden(tempp1);
! 322: Int_from_dbl_mantissa(tempp1,tempp2,src_exponent);
! 323: if (Dbl_isone_sign(srcp1) && (src_exponent <= SGL_FX_MAX_EXP))
! 324: result = -Dbl_allp1(tempp1);
! 325: else result = Dbl_allp1(tempp1);
! 326:
! 327: /* check for inexact */
! 328: if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
! 329: inexact = TRUE;
! 330: /* round result */
! 331: switch (Rounding_mode()) {
! 332: case ROUNDPLUS:
! 333: if (Dbl_iszero_sign(srcp1))
! 334: result++;
! 335: break;
! 336: case ROUNDMINUS:
! 337: if (Dbl_isone_sign(srcp1)) result--;
! 338: break;
! 339: case ROUNDNEAREST:
! 340: if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
! 341: if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) ||
! 342: (Dbl_isone_lowmantissap1(tempp1))) {
! 343: if (Dbl_iszero_sign(srcp1)) result++;
! 344: else result--;
! 345: }
! 346: }
! 347: /* check for overflow */
! 348: if ((Dbl_iszero_sign(srcp1) && result < 0) ||
! 349: (Dbl_isone_sign(srcp1) && result > 0)) {
! 350:
! 351: if (Dbl_iszero_sign(srcp1))
! 352: result = 0x7fffffff;
! 353: else
! 354: result = 0x80000000;
! 355:
! 356: if (Is_overflowtrap_enabled()) {
! 357: if (Is_inexacttrap_enabled())
! 358: return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
! 359: else Set_inexactflag();
! 360: return(OVERFLOWEXCEPTION);
! 361: }
! 362: Set_overflowflag();
! 363: *dstptr = result;
! 364: if (Is_inexacttrap_enabled() )
! 365: return(INEXACTEXCEPTION);
! 366: else Set_inexactflag();
! 367: return(NOEXCEPTION);
! 368: }
! 369: }
! 370: }
! 371: else {
! 372: result = 0;
! 373:
! 374: /* check for inexact */
! 375: if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
! 376: inexact = TRUE;
! 377: /* round result */
! 378: switch (Rounding_mode()) {
! 379: case ROUNDPLUS:
! 380: if (Dbl_iszero_sign(srcp1)) result++;
! 381: break;
! 382: case ROUNDMINUS:
! 383: if (Dbl_isone_sign(srcp1)) result--;
! 384: break;
! 385: case ROUNDNEAREST:
! 386: if (src_exponent == -1)
! 387: if (Dbl_isnotzero_mantissa(srcp1,srcp2)) {
! 388: if (Dbl_iszero_sign(srcp1)) result++;
! 389: else result--;
! 390: }
! 391: }
! 392: }
! 393: }
! 394: *dstptr = result;
! 395: if (inexact) {
! 396: if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
! 397: else Set_inexactflag();
! 398: }
! 399: return(NOEXCEPTION);
! 400: }
! 401:
! 402: /*
! 403: * Double Floating-point to Double Fixed-point
! 404: */
! 405: /*ARGSUSED*/
! 406: int
! 407: dbl_to_dbl_fcnvfx(srcptr, null, dstptr, status)
! 408: dbl_floating_point *srcptr, *null;
! 409: dbl_integer *dstptr;
! 410: unsigned int *status;
! 411: {
! 412: register int src_exponent, resultp1;
! 413: register unsigned int srcp1, srcp2, tempp1, tempp2, resultp2;
! 414: register int inexact = FALSE;
! 415:
! 416: Dbl_copyfromptr(srcptr,srcp1,srcp2);
! 417: src_exponent = Dbl_exponent(srcp1) - DBL_BIAS;
! 418:
! 419: /*
! 420: * Test for overflow
! 421: */
! 422: if (src_exponent > DBL_FX_MAX_EXP) {
! 423: /* check for MININT */
! 424: if ((src_exponent > DBL_FX_MAX_EXP + 1) ||
! 425: Dbl_isnotzero_mantissa(srcp1,srcp2) || Dbl_iszero_sign(srcp1)) {
! 426: if( Dbl_isnan(srcp1,srcp2) )
! 427: /*
! 428: * On NaN go unimplemented.
! 429: */
! 430: return(UNIMPLEMENTEDEXCEPTION);
! 431: else {
! 432: if (Dbl_iszero_sign(srcp1)) {
! 433: resultp1 = 0x7fffffff;
! 434: resultp2 = 0xffffffff;
! 435: }
! 436: else {
! 437: resultp1 = 0x80000000;
! 438: resultp2 = 0;
! 439: }
! 440: if (Is_overflowtrap_enabled()) {
! 441: if (Is_inexacttrap_enabled())
! 442: return(OVERFLOWEXCEPTION|INEXACTEXCEPTION);
! 443: else Set_inexactflag();
! 444: return(OVERFLOWEXCEPTION);
! 445: }
! 446: Set_overflowflag();
! 447: Dint_copytoptr(resultp1,resultp2,dstptr);
! 448: if (Is_inexacttrap_enabled() )
! 449: return(INEXACTEXCEPTION);
! 450: else Set_inexactflag();
! 451: return(NOEXCEPTION);
! 452: }
! 453: }
! 454: }
! 455:
! 456: /*
! 457: * Generate result
! 458: */
! 459: if (src_exponent >= 0) {
! 460: tempp1 = srcp1;
! 461: tempp2 = srcp2;
! 462: Dbl_clear_signexponent_set_hidden(tempp1);
! 463: Dint_from_dbl_mantissa(tempp1,tempp2,src_exponent,
! 464: resultp1, resultp2);
! 465: if (Dbl_isone_sign(srcp1)) {
! 466: Dint_setone_sign(resultp1,resultp2);
! 467: }
! 468:
! 469: /* check for inexact */
! 470: if (Dbl_isinexact_to_fix(srcp1,srcp2,src_exponent)) {
! 471: inexact = TRUE;
! 472: /* round result */
! 473: switch (Rounding_mode()) {
! 474: case ROUNDPLUS:
! 475: if (Dbl_iszero_sign(srcp1)) {
! 476: Dint_increment(resultp1,resultp2);
! 477: }
! 478: break;
! 479: case ROUNDMINUS:
! 480: if (Dbl_isone_sign(srcp1)) {
! 481: Dint_decrement(resultp1,resultp2);
! 482: }
! 483: break;
! 484: case ROUNDNEAREST:
! 485: if (Dbl_isone_roundbit(srcp1,srcp2,src_exponent))
! 486: if (Dbl_isone_stickybit(srcp1,srcp2,src_exponent) ||
! 487: (Dint_isone_lowp2(resultp2))) {
! 488: if (Dbl_iszero_sign(srcp1)) {
! 489: Dint_increment(resultp1,resultp2);
! 490: }
! 491: else {
! 492: Dint_decrement(resultp1,resultp2);
! 493: }
! 494: }
! 495: }
! 496: }
! 497: }
! 498: else {
! 499: Dint_setzero(resultp1,resultp2);
! 500:
! 501: /* check for inexact */
! 502: if (Dbl_isnotzero_exponentmantissa(srcp1,srcp2)) {
! 503: inexact = TRUE;
! 504: /* round result */
! 505: switch (Rounding_mode()) {
! 506: case ROUNDPLUS:
! 507: if (Dbl_iszero_sign(srcp1)) {
! 508: Dint_increment(resultp1,resultp2);
! 509: }
! 510: break;
! 511: case ROUNDMINUS:
! 512: if (Dbl_isone_sign(srcp1)) {
! 513: Dint_decrement(resultp1,resultp2);
! 514: }
! 515: break;
! 516: case ROUNDNEAREST:
! 517: if (src_exponent == -1)
! 518: if (Dbl_isnotzero_mantissa(srcp1,srcp2)) {
! 519: if (Dbl_iszero_sign(srcp1)) {
! 520: Dint_increment(resultp1,resultp2);
! 521: }
! 522: else {
! 523: Dint_decrement(resultp1,resultp2);
! 524: }
! 525: }
! 526: }
! 527: }
! 528: }
! 529: Dint_copytoptr(resultp1,resultp2,dstptr);
! 530: if (inexact) {
! 531: if (Is_inexacttrap_enabled()) return(INEXACTEXCEPTION);
! 532: else Set_inexactflag();
! 533: }
! 534: return(NOEXCEPTION);
! 535: }
CVSweb