Annotation of tme/ic/ieee754/softfloat-tme.c, revision 1.1.1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.