|
|
1.1 ! root 1: /* $Id: softfloat-tme.c,v 1.2 2005/05/14 01:42:28 fredette Exp $ */ ! 2: ! 3: /* ic/ieee754/softfloat-tme.c - this glues tme to SoftFloat: */ ! 4: ! 5: /* ! 6: * Copyright (c) 2004 Matt Fredette ! 7: * All rights reserved. ! 8: * ! 9: * Redistribution and use in source and binary forms, with or without ! 10: * modification, are permitted provided that the following conditions ! 11: * are met: ! 12: * 1. Redistributions of source code must retain the above copyright ! 13: * notice, this list of conditions and the following disclaimer. ! 14: * 2. Redistributions in binary form must reproduce the above copyright ! 15: * notice, this list of conditions and the following disclaimer in the ! 16: * documentation and/or other materials provided with the distribution. ! 17: * 3. All advertising materials mentioning features or use of this software ! 18: * must display the following acknowledgement: ! 19: * This product includes software developed by Matt Fredette. ! 20: * 4. The name of the author may not be used to endorse or promote products ! 21: * derived from this software without specific prior written permission. ! 22: * ! 23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ! 24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ! 25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ! 26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, ! 27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ! 28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ! 29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ! 31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ! 32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ! 33: * POSSIBILITY OF SUCH DAMAGE. ! 34: */ ! 35: ! 36: /*============================================================================ ! 37: ! 38: This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic ! 39: Package, Release 2b. ! 40: ! 41: This C source fragment is part of the SoftFloat IEC/IEEE Floating-point ! 42: Arithmetic Package, Release 2b. ! 43: ! 44: Written by John R. Hauser. This work was made possible in part by the ! 45: International Computer Science Institute, located at Suite 600, 1947 Center ! 46: Street, Berkeley, California 94704. Funding was partially provided by the ! 47: National Science Foundation under grant MIP-9311980. The original version ! 48: of this code was written as part of a project to build a fixed-point vector ! 49: processor in collaboration with the University of California at Berkeley, ! 50: overseen by Profs. Nelson Morgan and John Wawrzynek. More information ! 51: is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ ! 52: arithmetic/SoftFloat.html'. ! 53: ! 54: THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has ! 55: been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES ! 56: RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS ! 57: AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, ! 58: COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE ! 59: EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE ! 60: INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR ! 61: OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. ! 62: ! 63: Derivative works are acceptable, even for commercial purposes, so long as ! 64: (1) the source code for the derivative work includes prominent notice that ! 65: the work is derivative, and (2) the source code includes prominent notice with ! 66: these four paragraphs for those parts of this code that are retained. ! 67: ! 68: =============================================================================*/ ! 69: ! 70: #include <tme/common.h> ! 71: _TME_RCSID("$Id: softfloat-tme.c,v 1.2 2005/05/14 01:42:28 fredette Exp $"); ! 72: ! 73: /* includes: */ ! 74: #define _TME_IEEE754_SOFTFLOAT_GLUE ! 75: #include "softfloat-tme.h" ! 76: ! 77: /* types: */ ! 78: typedef struct tme_ieee754_nan commonNaNT; ! 79: ! 80: /* globals: */ ! 81: ! 82: /* the softfloat lock: */ ! 83: tme_mutex_t tme_ieee754_global_mutex; ! 84: ! 85: /* the softfloat global control: */ ! 86: struct tme_ieee754_ctl *tme_ieee754_global_ctl; ! 87: ! 88: /* the softfloat global exceptions: */ ! 89: tme_int8_t tme_ieee754_global_exceptions; ! 90: ! 91: #ifdef TME_HAVE_INT64_T ! 92: /*---------------------------------------------------------------------------- ! 93: | The `LIT64' macro takes as its argument a textual integer literal and ! 94: | if necessary ``marks'' the literal as having a 64-bit integer type. ! 95: | For example, the GNU C Compiler (`gcc') requires that 64-bit literals be ! 96: | appended with the letters `LL' standing for `long long', which is `gcc's ! 97: | name for the 64-bit integer type. Some compilers may allow `LIT64' to be ! 98: | defined as the identity macro: `#define LIT64( a ) a'. ! 99: *----------------------------------------------------------------------------*/ ! 100: #if defined(__GNUC__) && (_TME_SIZEOF_LONG == 4) ! 101: #define LIT64( a ) a##LL ! 102: #else ! 103: #define LIT64( a ) a ! 104: #endif ! 105: #endif /* TME_HAVE_INT64_T */ ! 106: ! 107: /*---------------------------------------------------------------------------- ! 108: | The macro `INLINE' can be used before functions that should be inlined. If ! 109: | a compiler does not support explicit inlining, this macro should be defined ! 110: | to be `static'. ! 111: *----------------------------------------------------------------------------*/ ! 112: #define INLINE static inline ! 113: ! 114: /*---------------------------------------------------------------------------- ! 115: | Software IEC/IEEE floating-point underflow tininess-detection mode. ! 116: *----------------------------------------------------------------------------*/ ! 117: #define float_detect_tininess (tme_ieee754_global_ctl->tme_ieee754_ctl_detect_tininess) ! 118: #define float_tininess_after_rounding TME_IEEE754_CTL_DETECT_TININESS_AFTER_ROUNDING ! 119: #define float_tininess_before_rounding TME_IEEE754_CTL_DETECT_TININESS_BEFORE_ROUNDING ! 120: ! 121: /*---------------------------------------------------------------------------- ! 122: | Software IEC/IEEE floating-point rounding mode. ! 123: *----------------------------------------------------------------------------*/ ! 124: #define float_rounding_mode (tme_ieee754_global_ctl->tme_ieee754_ctl_rounding_mode) ! 125: #define float_round_nearest_even TME_FLOAT_ROUND_NEAREST_EVEN ! 126: #define float_round_down TME_FLOAT_ROUND_DOWN ! 127: #define float_round_up TME_FLOAT_ROUND_UP ! 128: #define float_round_to_zero TME_FLOAT_ROUND_TO_ZERO ! 129: ! 130: /*---------------------------------------------------------------------------- ! 131: | Software IEC/IEEE floating-point exception flags. ! 132: *----------------------------------------------------------------------------*/ ! 133: #define float_exception_flags tme_ieee754_global_exceptions ! 134: #define float_flag_invalid TME_FLOAT_EXCEPTION_INVALID ! 135: #define float_flag_divbyzero TME_FLOAT_EXCEPTION_DIVBYZERO ! 136: #define float_flag_overflow TME_FLOAT_EXCEPTION_OVERFLOW ! 137: #define float_flag_underflow TME_FLOAT_EXCEPTION_UNDERFLOW ! 138: #define float_flag_inexact TME_FLOAT_EXCEPTION_INEXACT ! 139: ! 140: /*---------------------------------------------------------------------------- ! 141: | Routine to raise any or all of the software IEC/IEEE floating-point ! 142: | exception flags. ! 143: *----------------------------------------------------------------------------*/ ! 144: #define float_raise(excp) \ ! 145: do { \ ! 146: tme_ieee754_global_exceptions |= (excp); \ ! 147: (*tme_ieee754_global_ctl->tme_ieee754_ctl_exception)(tme_ieee754_global_ctl, tme_ieee754_global_exceptions);\ ! 148: } while (/* CONSTCOND */ 0) ! 149: ! 150: /*---------------------------------------------------------------------------- ! 151: | Software IEC/IEEE extended double-precision rounding precision. Valid ! 152: | values are 32, 64, and 80. ! 153: *----------------------------------------------------------------------------*/ ! 154: #define floatx80_rounding_precision (tme_ieee754_global_ctl->tme_ieee754_ctl_extended80_rounding_precision) ! 155: ! 156: /* include either the 32-bit or 64-bit SoftFloat macros: */ ! 157: #ifdef TME_HAVE_INT64_T ! 158: #include "dist/softfloat/softfloat/bits64/softfloat-macros" ! 159: #else /* !TME_HAVE_INT64_T */ ! 160: #include "dist/softfloat/softfloat/bits32/softfloat-macros" ! 161: #endif /* !TME_HAVE_INT64_T */ ! 162: ! 163: /*---------------------------------------------------------------------------- ! 164: | The pattern for a default generated single-precision NaN. ! 165: *----------------------------------------------------------------------------*/ ! 166: ! 167: #define float32_default_nan (tme_ieee754_global_ctl->tme_ieee754_ctl_default_nan_single) ! 168: ! 169: /*---------------------------------------------------------------------------- ! 170: | Returns 1 if the single-precision floating-point value `a' is a signaling ! 171: | NaN; otherwise returns 0. ! 172: *----------------------------------------------------------------------------*/ ! 173: ! 174: INLINE flag ! 175: float32_is_signaling_nan( float32 a ) ! 176: { ! 177: return ((*tme_ieee754_global_ctl->tme_ieee754_ctl_is_snan_single)(&a)); ! 178: } ! 179: ! 180: /*---------------------------------------------------------------------------- ! 181: | Returns the result of converting the single-precision floating-point NaN ! 182: | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid ! 183: | exception is raised. ! 184: *----------------------------------------------------------------------------*/ ! 185: ! 186: void ! 187: tme_ieee754_default_nan_single_to_common(tme_uint32_t a, ! 188: struct tme_ieee754_nan *z) ! 189: { ! 190: z->tme_ieee754_nan_sign = a >> 31; ! 191: z->tme_ieee754_nan_hi.tme_value64_uint32_hi = a << 9; ! 192: z->tme_ieee754_nan_hi.tme_value64_uint32_lo = 0; ! 193: z->tme_ieee754_nan_lo.tme_value64_uint32_hi = 0; ! 194: z->tme_ieee754_nan_lo.tme_value64_uint32_lo = 0; ! 195: } ! 196: ! 197: INLINE commonNaNT ! 198: float32ToCommonNaN( float32 a ) ! 199: { ! 200: commonNaNT z; ! 201: ! 202: if (tme_ieee754_global_ctl->tme_ieee754_ctl_check_snan_on_conversion ! 203: && (*tme_ieee754_global_ctl->tme_ieee754_ctl_is_snan_single)(&a)) { ! 204: float_raise( float_flag_invalid ); ! 205: } ! 206: (*tme_ieee754_global_ctl->tme_ieee754_ctl_nan_single_to_common)(a, &z); ! 207: return (z); ! 208: } ! 209: ! 210: /*---------------------------------------------------------------------------- ! 211: | Returns the result of converting the canonical NaN `a' to the single- ! 212: | precision floating-point format. ! 213: *----------------------------------------------------------------------------*/ ! 214: ! 215: void ! 216: tme_ieee754_default_nan_common_to_single(const struct tme_ieee754_nan *z, ! 217: tme_uint32_t *a) ! 218: { ! 219: *a = ((((bits32) z->tme_ieee754_nan_sign) << 31) ! 220: | 0x7FC00000 ! 221: | (z->tme_ieee754_nan_hi.tme_value64_uint32_hi >> 9) ! 222: ); ! 223: } ! 224: ! 225: INLINE float32 ! 226: commonNaNToFloat32( commonNaNT a ) ! 227: { ! 228: float32 z; ! 229: ! 230: (*tme_ieee754_global_ctl->tme_ieee754_ctl_nan_common_to_single)(&a, &z); ! 231: return (z); ! 232: } ! 233: ! 234: /*---------------------------------------------------------------------------- ! 235: | Takes two single-precision floating-point values `a' and `b', one of which ! 236: | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a ! 237: | signaling NaN, the invalid exception is raised. ! 238: *----------------------------------------------------------------------------*/ ! 239: ! 240: INLINE float32 ! 241: propagateFloat32NaN( float32 a, float32 b ) ! 242: { ! 243: float32 z; ! 244: ! 245: (*tme_ieee754_global_ctl->tme_ieee754_ctl_nan_from_nans_single)(tme_ieee754_global_ctl, &a, &b, &z); ! 246: return (z); ! 247: } ! 248: ! 249: /*---------------------------------------------------------------------------- ! 250: | The pattern for a default generated double-precision NaN. ! 251: *----------------------------------------------------------------------------*/ ! 252: #ifdef TME_HAVE_INT64_T ! 253: #define float64_default_nan (tme_ieee754_global_ctl->tme_ieee754_ctl_default_nan_double.tme_value64_uint) ! 254: #else /* !TME_HAVE_INT64_T */ ! 255: #define float64_default_nan_high (tme_ieee754_global_ctl->tme_ieee754_ctl_default_nan_double.tme_value64_uint32_hi) ! 256: #define float64_default_nan_low (tme_ieee754_global_ctl->tme_ieee754_ctl_default_nan_double.tme_value64_uint32_lo) ! 257: #endif /* !TME_HAVE_INT64_T */ ! 258: ! 259: #define TME_FLOAT64_OUT(a) ((union tme_value64 *) (&(a))) ! 260: ! 261: /*---------------------------------------------------------------------------- ! 262: | Returns 1 if the double-precision floating-point value `a' is a signaling ! 263: | NaN; otherwise returns 0. ! 264: *----------------------------------------------------------------------------*/ ! 265: ! 266: INLINE flag ! 267: float64_is_signaling_nan( float64 a ) ! 268: { ! 269: return ((*tme_ieee754_global_ctl->tme_ieee754_ctl_is_snan_double)(TME_FLOAT64_OUT(a))); ! 270: } ! 271: ! 272: /*---------------------------------------------------------------------------- ! 273: | Returns the result of converting the double-precision floating-point NaN ! 274: | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid ! 275: | exception is raised. ! 276: *----------------------------------------------------------------------------*/ ! 277: ! 278: void ! 279: tme_ieee754_default_nan_double_to_common(const union tme_value64 *a, ! 280: struct tme_ieee754_nan *z) ! 281: { ! 282: z->tme_ieee754_nan_sign = a->tme_value64_uint32_hi >> 31; ! 283: #ifdef TME_HAVE_INT64_T ! 284: z->tme_ieee754_nan_hi.tme_value64_uint = a->tme_value64_uint << 12; ! 285: #else /* !TME_HAVE_INT64_T */ ! 286: shortShift64Left( a->tme_value64_uint32_hi, ! 287: a->tme_value64_uint32_lo, ! 288: 12, ! 289: &z->tme_ieee754_nan_hi.tme_value64_uint32_hi, ! 290: &z->tme_ieee754_nan_hi.tme_value64_uint32_lo ); ! 291: #endif /* !TME_HAVE_INT64_T */ ! 292: z->tme_ieee754_nan_lo.tme_value64_uint32_hi = 0; ! 293: z->tme_ieee754_nan_lo.tme_value64_uint32_lo = 0; ! 294: } ! 295: ! 296: INLINE commonNaNT ! 297: float64ToCommonNaN( float64 a ) ! 298: { ! 299: commonNaNT z; ! 300: ! 301: if (tme_ieee754_global_ctl->tme_ieee754_ctl_check_snan_on_conversion ! 302: && (*tme_ieee754_global_ctl->tme_ieee754_ctl_is_snan_double)(TME_FLOAT64_OUT(a))) { ! 303: float_raise( float_flag_invalid ); ! 304: } ! 305: (*tme_ieee754_global_ctl->tme_ieee754_ctl_nan_double_to_common)(TME_FLOAT64_OUT(a), &z); ! 306: return (z); ! 307: } ! 308: ! 309: /*---------------------------------------------------------------------------- ! 310: | Returns the result of converting the canonical NaN `a' to the double- ! 311: | precision floating-point format. ! 312: *----------------------------------------------------------------------------*/ ! 313: ! 314: void ! 315: tme_ieee754_default_nan_common_to_double(const struct tme_ieee754_nan *a, ! 316: union tme_value64 *z) ! 317: { ! 318: #ifdef TME_HAVE_INT64_T ! 319: z->tme_value64_uint = a->tme_ieee754_nan_hi.tme_value64_uint >> 12; ! 320: #else /* TME_HAVE_INT64_T */ ! 321: shift64Right( a->tme_ieee754_nan_hi.tme_value64_uint32_hi, ! 322: a->tme_ieee754_nan_hi.tme_value64_uint32_lo, ! 323: 12, ! 324: &z->tme_value64_uint32_hi, ! 325: &z->tme_value64_uint32_lo ); ! 326: #endif /* TME_HAVE_INT64_T */ ! 327: z->tme_value64_uint32_hi |= ( ( (bits32) a->tme_ieee754_nan_sign ) << 31 ) | 0x7FF80000; ! 328: } ! 329: ! 330: INLINE float64 ! 331: commonNaNToFloat64( commonNaNT a ) ! 332: { ! 333: float64 z; ! 334: ! 335: (*tme_ieee754_global_ctl->tme_ieee754_ctl_nan_common_to_double)(&a, TME_FLOAT64_OUT(z)); ! 336: return (z); ! 337: } ! 338: ! 339: /*---------------------------------------------------------------------------- ! 340: | Takes two double-precision floating-point values `a' and `b', one of which ! 341: | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a ! 342: | signaling NaN, the invalid exception is raised. ! 343: *----------------------------------------------------------------------------*/ ! 344: ! 345: INLINE float64 ! 346: propagateFloat64NaN( float64 a, float64 b ) ! 347: { ! 348: float64 z; ! 349: ! 350: (*tme_ieee754_global_ctl->tme_ieee754_ctl_nan_from_nans_double)(tme_ieee754_global_ctl, ! 351: TME_FLOAT64_OUT(a), ! 352: TME_FLOAT64_OUT(b), ! 353: TME_FLOAT64_OUT(z)); ! 354: return (z); ! 355: } ! 356: ! 357: #ifdef FLOATX80 ! 358: ! 359: /*---------------------------------------------------------------------------- ! 360: | The pattern for a default generated extended double-precision NaN. The ! 361: | `high' and `low' values hold the most- and least-significant bits, ! 362: | respectively. ! 363: *----------------------------------------------------------------------------*/ ! 364: #define floatx80_default_nan_high (tme_ieee754_global_ctl->tme_ieee754_ctl_default_nan_extended80.tme_float_ieee754_extended80_sexp) ! 365: #define floatx80_default_nan_low (tme_ieee754_global_ctl->tme_ieee754_ctl_default_nan_extended80.tme_float_ieee754_extended80_significand.tme_value64_uint) ! 366: ! 367: #define TME_FLOATX80_OUT(a) ((struct tme_float_ieee754_extended80 *) &(a)) ! 368: ! 369: /*---------------------------------------------------------------------------- ! 370: | Returns 1 if the extended double-precision floating-point value `a' is a ! 371: | signaling NaN; otherwise returns 0. ! 372: *----------------------------------------------------------------------------*/ ! 373: ! 374: INLINE flag ! 375: floatx80_is_signaling_nan( floatx80 a ) ! 376: { ! 377: return ((*tme_ieee754_global_ctl->tme_ieee754_ctl_is_snan_extended80)(TME_FLOATX80_OUT(a))); ! 378: } ! 379: ! 380: /*---------------------------------------------------------------------------- ! 381: | Returns the result of converting the extended double-precision floating- ! 382: | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the ! 383: | invalid exception is raised. ! 384: *----------------------------------------------------------------------------*/ ! 385: ! 386: void ! 387: tme_ieee754_default_nan_extended80_to_common(const struct tme_float_ieee754_extended80 *a, ! 388: struct tme_ieee754_nan *z) ! 389: { ! 390: z->tme_ieee754_nan_sign = a->tme_float_ieee754_extended80_sexp >> 15; ! 391: #ifdef TME_HAVE_INT64_T ! 392: z->tme_ieee754_nan_hi.tme_value64_uint = a->tme_float_ieee754_extended80_significand.tme_value64_uint << 1; ! 393: #else /* !TME_HAVE_INT64_T */ ! 394: shortShift64Left(a->tme_float_ieee754_extended80_significand.tme_value64_uint32_hi, ! 395: a->tme_float_ieee754_extended80_significand.tme_value64_uint32_lo, ! 396: 1, ! 397: &z->tme_ieee754_nan_hi.tme_value64_uint32_hi, ! 398: &z->tme_ieee754_nan_hi.tme_value64_uint32_lo); ! 399: #endif /* !TME_HAVE_INT64_T */ ! 400: z->tme_ieee754_nan_lo.tme_value64_uint32_hi = 0; ! 401: z->tme_ieee754_nan_lo.tme_value64_uint32_lo = 0; ! 402: } ! 403: ! 404: INLINE commonNaNT ! 405: floatx80ToCommonNaN( floatx80 a ) ! 406: { ! 407: commonNaNT z; ! 408: ! 409: if (tme_ieee754_global_ctl->tme_ieee754_ctl_check_snan_on_conversion ! 410: && (*tme_ieee754_global_ctl->tme_ieee754_ctl_is_snan_extended80)(TME_FLOATX80_OUT(a))) { ! 411: float_raise( float_flag_invalid ); ! 412: } ! 413: (*tme_ieee754_global_ctl->tme_ieee754_ctl_nan_extended80_to_common)(TME_FLOATX80_OUT(a), &z); ! 414: return (z); ! 415: } ! 416: ! 417: /*---------------------------------------------------------------------------- ! 418: | Returns the result of converting the canonical NaN `a' to the extended ! 419: | double-precision floating-point format. ! 420: *----------------------------------------------------------------------------*/ ! 421: ! 422: void ! 423: tme_ieee754_default_nan_common_to_extended80(const struct tme_ieee754_nan *a, ! 424: struct tme_float_ieee754_extended80 *z) ! 425: { ! 426: z->tme_float_ieee754_extended80_sexp = (((tme_uint16_t) a->tme_ieee754_nan_sign) << 15) | 0x7FFF; ! 427: #ifdef TME_HAVE_INT64_T ! 428: z->tme_float_ieee754_extended80_significand.tme_value64_uint = a->tme_ieee754_nan_hi.tme_value64_uint >> 1; ! 429: #else /* !TME_HAVE_INT64_T */ ! 430: shift64Right(a->tme_ieee754_nan_hi.tme_value64_uint32_hi, ! 431: a->tme_ieee754_nan_hi.tme_value64_uint32_lo, ! 432: 1, ! 433: z->tme_float_ieee754_extended80_significand.tme_value64_uint32_hi, ! 434: z->tme_float_ieee754_extended80_significand.tme_value64_uint32_lo); ! 435: #endif /* !TME_HAVE_INT64_T */ ! 436: z->tme_float_ieee754_extended80_significand.tme_value64_uint32_hi |= 0xC0000000; ! 437: } ! 438: ! 439: INLINE floatx80 ! 440: commonNaNToFloatx80( commonNaNT a ) ! 441: { ! 442: floatx80 z; ! 443: ! 444: (*tme_ieee754_global_ctl->tme_ieee754_ctl_nan_common_to_extended80)(&a, TME_FLOATX80_OUT(z)); ! 445: return (z); ! 446: } ! 447: ! 448: /*---------------------------------------------------------------------------- ! 449: | Takes two extended double-precision floating-point values `a' and `b', one ! 450: | of which is a NaN, and returns the appropriate NaN result. If either `a' or ! 451: | `b' is a signaling NaN, the invalid exception is raised. ! 452: *----------------------------------------------------------------------------*/ ! 453: ! 454: INLINE floatx80 ! 455: propagateFloatx80NaN( floatx80 a, floatx80 b ) ! 456: { ! 457: floatx80 z; ! 458: ! 459: (*tme_ieee754_global_ctl->tme_ieee754_ctl_nan_from_nans_extended80)(tme_ieee754_global_ctl, ! 460: TME_FLOATX80_OUT(a), ! 461: TME_FLOATX80_OUT(b), ! 462: TME_FLOATX80_OUT(z)); ! 463: return (z); ! 464: } ! 465: ! 466: #endif /* FLOATX80 */ ! 467: ! 468: #ifdef FLOAT128 ! 469: ! 470: /*---------------------------------------------------------------------------- ! 471: | The pattern for a default generated quadruple-precision NaN. The `high' and ! 472: | `low' values hold the most- and least-significant bits, respectively. ! 473: *----------------------------------------------------------------------------*/ ! 474: #define float128_default_nan_high (tme_ieee754_global_ctl->tme_ieee754_ctl_default_nan_quad.tme_float_ieee754_quad_hi.tme_value64_uint) ! 475: #define float128_default_nan_low (tme_ieee754_global_ctl->tme_ieee754_ctl_default_nan_quad.tme_float_ieee754_quad_lo.tme_value64_uint) ! 476: ! 477: #define TME_FLOAT128_OUT(a) ((struct tme_float_ieee754_quad *) &(a)) ! 478: ! 479: /*---------------------------------------------------------------------------- ! 480: | Returns 1 if the quadruple-precision floating-point value `a' is a ! 481: | signaling NaN; otherwise returns 0. ! 482: *----------------------------------------------------------------------------*/ ! 483: ! 484: INLINE flag ! 485: float128_is_signaling_nan( float128 a ) ! 486: { ! 487: return ((*tme_ieee754_global_ctl->tme_ieee754_ctl_is_snan_quad)(TME_FLOAT128_OUT(a))); ! 488: } ! 489: ! 490: /*---------------------------------------------------------------------------- ! 491: | Returns the result of converting the quadruple-precision floating-point NaN ! 492: | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid ! 493: | exception is raised. ! 494: *----------------------------------------------------------------------------*/ ! 495: ! 496: void ! 497: tme_ieee754_default_nan_quad_to_common(const struct tme_float_ieee754_quad *a, ! 498: struct tme_ieee754_nan *z) ! 499: { ! 500: z->tme_ieee754_nan_sign = a->tme_float_ieee754_quad_hi.tme_value64_uint32_hi >> 31; ! 501: shortShift128Left( a->tme_float_ieee754_quad_hi.tme_value64_uint, ! 502: a->tme_float_ieee754_quad_lo.tme_value64_uint, ! 503: 16, ! 504: &z->tme_ieee754_nan_hi.tme_value64_uint, ! 505: &z->tme_ieee754_nan_lo.tme_value64_uint ); ! 506: } ! 507: ! 508: INLINE commonNaNT ! 509: float128ToCommonNaN( float128 a ) ! 510: { ! 511: commonNaNT z; ! 512: ! 513: if (tme_ieee754_global_ctl->tme_ieee754_ctl_check_snan_on_conversion ! 514: && (*tme_ieee754_global_ctl->tme_ieee754_ctl_is_snan_quad)(TME_FLOAT128_OUT(a))) { ! 515: float_raise( float_flag_invalid ); ! 516: } ! 517: (*tme_ieee754_global_ctl->tme_ieee754_ctl_nan_quad_to_common)(TME_FLOAT128_OUT(a), &z); ! 518: return (z); ! 519: } ! 520: ! 521: /*---------------------------------------------------------------------------- ! 522: | Returns the result of converting the canonical NaN `a' to the quadruple- ! 523: | precision floating-point format. ! 524: *----------------------------------------------------------------------------*/ ! 525: ! 526: void ! 527: tme_ieee754_default_nan_common_to_quad(const struct tme_ieee754_nan *a, ! 528: struct tme_float_ieee754_quad *z) ! 529: { ! 530: shift128Right( a->tme_ieee754_nan_hi.tme_value64_uint, ! 531: a->tme_ieee754_nan_lo.tme_value64_uint, ! 532: 16, ! 533: &z->tme_float_ieee754_quad_hi.tme_value64_uint, ! 534: &z->tme_float_ieee754_quad_lo.tme_value64_uint ); ! 535: z->tme_float_ieee754_quad_hi.tme_value64_uint32_hi |= (((tme_uint32_t) a->tme_ieee754_nan_sign) << 31) | 0x7FFF8000; ! 536: } ! 537: ! 538: INLINE float128 ! 539: commonNaNToFloat128( commonNaNT a ) ! 540: { ! 541: float128 z; ! 542: ! 543: (*tme_ieee754_global_ctl->tme_ieee754_ctl_nan_common_to_quad)(&a, TME_FLOAT128_OUT(z)); ! 544: return (z); ! 545: } ! 546: ! 547: /*---------------------------------------------------------------------------- ! 548: | Takes two quadruple-precision floating-point values `a' and `b', one of ! 549: | which is a NaN, and returns the appropriate NaN result. If either `a' or ! 550: | `b' is a signaling NaN, the invalid exception is raised. ! 551: *----------------------------------------------------------------------------*/ ! 552: ! 553: INLINE float128 ! 554: propagateFloat128NaN( float128 a, float128 b ) ! 555: { ! 556: float128 z; ! 557: ! 558: (*tme_ieee754_global_ctl->tme_ieee754_ctl_nan_from_nans_quad)(tme_ieee754_global_ctl, ! 559: TME_FLOAT128_OUT(a), ! 560: TME_FLOAT128_OUT(b), ! 561: TME_FLOAT128_OUT(z)); ! 562: return (z); ! 563: } ! 564: ! 565: #endif /* FLOAT128 */ ! 566: ! 567: /* include either the 32-bit or 64-bit SoftFloat implementation: */ ! 568: #ifdef TME_HAVE_INT64_T ! 569: #include "dist/softfloat/softfloat/bits64/softfloat.c" ! 570: #else /* !TME_HAVE_INT64_T */ ! 571: #include "dist/softfloat/softfloat/bits32/softfloat.c" ! 572: #endif /* !TME_HAVE_INT64_T */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.