Home | History | Annotate | Line # | Download | only in include
softfloat-specialize revision 1.1
      1 /* $NetBSD: softfloat-specialize,v 1.1 2001/03/13 07:25:02 ross Exp $ */
      2 
      3 /* This is a derivative work. */
      4 
      5 /*-
      6  * Copyright (c) 2001 The NetBSD Foundation, Inc.
      7  * All rights reserved.
      8  *
      9  * This code is derived from software contributed to The NetBSD Foundation
     10  * by Ross Harvey.
     11  *
     12  * Redistribution and use in source and binary forms, with or without
     13  * modification, are permitted provided that the following conditions
     14  * are met:
     15  * 1. Redistributions of source code must retain the above copyright
     16  *    notice, this list of conditions and the following disclaimer.
     17  * 2. Redistributions in binary form must reproduce the above copyright
     18  *    notice, this list of conditions and the following disclaimer in the
     19  *    documentation and/or other materials provided with the distribution.
     20  * 3. All advertising materials mentioning features or use of this software
     21  *    must display the following acknowledgement:
     22  *        This product includes software developed by the NetBSD
     23  *        Foundation, Inc. and its contributors.
     24  * 4. Neither the name of The NetBSD Foundation nor the names of its
     25  *    contributors may be used to endorse or promote products derived
     26  *    from this software without specific prior written permission.
     27  *
     28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     38  * POSSIBILITY OF SUCH DAMAGE.
     39  */
     40 
     41 /*
     42 ===============================================================================
     43 
     44 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
     45 Arithmetic Package, Release 2a.
     46 
     47 Written by John R. Hauser.  This work was made possible in part by the
     48 International Computer Science Institute, located at Suite 600, 1947 Center
     49 Street, Berkeley, California 94704.  Funding was partially provided by the
     50 National Science Foundation under grant MIP-9311980.  The original version
     51 of this code was written as part of a project to build a fixed-point vector
     52 processor in collaboration with the University of California at Berkeley,
     53 overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
     54 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
     55 arithmetic/SoftFloat.html'.
     56 
     57 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
     58 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
     59 TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
     60 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
     61 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
     62 
     63 Derivative works are acceptable, even for commercial purposes, so long as
     64 (1) they include prominent notice that the work is derivative, and (2) they
     65 include prominent notice akin to these four paragraphs for those parts of
     66 this code that are retained.
     67 
     68 ===============================================================================
     69 */
     70 
     71 /*
     72 -------------------------------------------------------------------------------
     73 Underflow tininess-detection mode, statically initialized to default value.
     74 -------------------------------------------------------------------------------
     75 */
     76 int float_detect_tininess = float_tininess_after_rounding;
     77 
     78 /*
     79 -------------------------------------------------------------------------------
     80 Raises the exceptions specified by `flags'.  Floating-point traps can be
     81 defined here if desired.  It is currently not possible for such a trap
     82 to substitute a result value.  If traps are not implemented, this routine
     83 should be simply `float_exception_flags |= flags;'.
     84 -------------------------------------------------------------------------------
     85 */
     86 void float_raise( int flags )
     87 {
     88 
     89     float_exception_flags |= flags;
     90 
     91 }
     92 
     93 /*
     94 -------------------------------------------------------------------------------
     95 Internal canonical NaN format.
     96 -------------------------------------------------------------------------------
     97 */
     98 typedef struct {
     99     flag sign;
    100     bits64 high, low;
    101 } commonNaNT;
    102 
    103 /*
    104 -------------------------------------------------------------------------------
    105 The pattern for a default generated single-precision NaN.
    106 -------------------------------------------------------------------------------
    107 */
    108 #define float32_default_nan 0xFFC00000
    109 
    110 /*
    111 -------------------------------------------------------------------------------
    112 Returns 1 if the single-precision floating-point value `a' is a NaN;
    113 otherwise returns 0.
    114 -------------------------------------------------------------------------------
    115 */
    116 static flag float32_is_nan( float32 a )
    117 {
    118 
    119     return ( 0xFF000000 < (bits32) ( a<<1 ) );
    120 
    121 }
    122 
    123 /*
    124 -------------------------------------------------------------------------------
    125 Returns 1 if the single-precision floating-point value `a' is a signaling
    126 NaN; otherwise returns 0.
    127 -------------------------------------------------------------------------------
    128 */
    129 flag float32_is_signaling_nan( float32 a )
    130 {
    131 
    132     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
    133 
    134 }
    135 
    136 /*
    137 -------------------------------------------------------------------------------
    138 Returns the result of converting the single-precision floating-point NaN
    139 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    140 exception is raised.
    141 -------------------------------------------------------------------------------
    142 */
    143 static commonNaNT float32ToCommonNaN( float32 a )
    144 {
    145     commonNaNT z;
    146 
    147     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    148     z.sign = a>>31;
    149     z.low = 0;
    150     z.high = ( (bits64) a )<<41;
    151     return z;
    152 
    153 }
    154 
    155 /*
    156 -------------------------------------------------------------------------------
    157 Returns the result of converting the canonical NaN `a' to the single-
    158 precision floating-point format.
    159 -------------------------------------------------------------------------------
    160 */
    161 static float32 commonNaNToFloat32( commonNaNT a )
    162 {
    163 
    164     return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
    165 
    166 }
    167 
    168 /*
    169 -------------------------------------------------------------------------------
    170 Takes two single-precision floating-point values `a' and `b', one of which
    171 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
    172 signaling NaN, the invalid exception is raised.
    173 -------------------------------------------------------------------------------
    174 */
    175 static float32 propagateFloat32NaN( float32 a, float32 b )
    176 {
    177     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    178 
    179     aIsNaN = float32_is_nan( a );
    180     aIsSignalingNaN = float32_is_signaling_nan( a );
    181     bIsNaN = float32_is_nan( b );
    182     bIsSignalingNaN = float32_is_signaling_nan( b );
    183     a |= 0x00400000;
    184     b |= 0x00400000;
    185     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    186     if ( aIsSignalingNaN ) {
    187         if ( bIsSignalingNaN ) goto returnLargerSignificand;
    188         return bIsNaN ? b : a;
    189     }
    190     else if ( aIsNaN ) {
    191         if ( bIsSignalingNaN | ! bIsNaN ) return a;
    192  returnLargerSignificand:
    193         if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
    194         if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
    195         return ( a < b ) ? a : b;
    196     }
    197     else {
    198         return b;
    199     }
    200 
    201 }
    202 
    203 /*
    204 -------------------------------------------------------------------------------
    205 The pattern for a default generated double-precision NaN.
    206 -------------------------------------------------------------------------------
    207 */
    208 #define float64_default_nan LIT64( 0xFFF8000000000000 )
    209 
    210 /*
    211 -------------------------------------------------------------------------------
    212 Returns 1 if the double-precision floating-point value `a' is a NaN;
    213 otherwise returns 0.
    214 -------------------------------------------------------------------------------
    215 */
    216 static flag float64_is_nan( float64 a )
    217 {
    218 
    219     return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
    220 
    221 }
    222 
    223 /*
    224 -------------------------------------------------------------------------------
    225 Returns 1 if the double-precision floating-point value `a' is a signaling
    226 NaN; otherwise returns 0.
    227 -------------------------------------------------------------------------------
    228 */
    229 flag float64_is_signaling_nan( float64 a )
    230 {
    231 
    232     return
    233            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
    234         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
    235 
    236 }
    237 
    238 /*
    239 -------------------------------------------------------------------------------
    240 Returns the result of converting the double-precision floating-point NaN
    241 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    242 exception is raised.
    243 -------------------------------------------------------------------------------
    244 */
    245 static commonNaNT float64ToCommonNaN( float64 a )
    246 {
    247     commonNaNT z;
    248 
    249     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    250     z.sign = a>>63;
    251     z.low = 0;
    252     z.high = a<<12;
    253     return z;
    254 
    255 }
    256 
    257 /*
    258 -------------------------------------------------------------------------------
    259 Returns the result of converting the canonical NaN `a' to the double-
    260 precision floating-point format.
    261 -------------------------------------------------------------------------------
    262 */
    263 static float64 commonNaNToFloat64( commonNaNT a )
    264 {
    265 
    266     return
    267           ( ( (bits64) a.sign )<<63 )
    268         | LIT64( 0x7FF8000000000000 )
    269         | ( a.high>>12 );
    270 
    271 }
    272 
    273 /*
    274 -------------------------------------------------------------------------------
    275 Takes two double-precision floating-point values `a' and `b', one of which
    276 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
    277 signaling NaN, the invalid exception is raised.
    278 -------------------------------------------------------------------------------
    279 */
    280 static float64 propagateFloat64NaN( float64 a, float64 b )
    281 {
    282     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    283 
    284     aIsNaN = float64_is_nan( a );
    285     aIsSignalingNaN = float64_is_signaling_nan( a );
    286     bIsNaN = float64_is_nan( b );
    287     bIsSignalingNaN = float64_is_signaling_nan( b );
    288     a |= LIT64( 0x0008000000000000 );
    289     b |= LIT64( 0x0008000000000000 );
    290     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    291     if ( aIsSignalingNaN ) {
    292         if ( bIsSignalingNaN ) goto returnLargerSignificand;
    293         return bIsNaN ? b : a;
    294     }
    295     else if ( aIsNaN ) {
    296         if ( bIsSignalingNaN | ! bIsNaN ) return a;
    297  returnLargerSignificand:
    298         if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
    299         if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
    300         return ( a < b ) ? a : b;
    301     }
    302     else {
    303         return b;
    304     }
    305 
    306 }
    307 
    308 #ifdef FLOATX80
    309 
    310 /*
    311 -------------------------------------------------------------------------------
    312 The pattern for a default generated extended double-precision NaN.  The
    313 `high' and `low' values hold the most- and least-significant bits,
    314 respectively.
    315 -------------------------------------------------------------------------------
    316 */
    317 #define floatx80_default_nan_high 0xFFFF
    318 #define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
    319 
    320 /*
    321 -------------------------------------------------------------------------------
    322 Returns 1 if the extended double-precision floating-point value `a' is a
    323 NaN; otherwise returns 0.
    324 -------------------------------------------------------------------------------
    325 */
    326 static flag floatx80_is_nan( floatx80 a )
    327 {
    328 
    329     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
    330 
    331 }
    332 
    333 /*
    334 -------------------------------------------------------------------------------
    335 Returns 1 if the extended double-precision floating-point value `a' is a
    336 signaling NaN; otherwise returns 0.
    337 -------------------------------------------------------------------------------
    338 */
    339 flag floatx80_is_signaling_nan( floatx80 a )
    340 {
    341     bits64 aLow;
    342 
    343     aLow = a.low & ~ LIT64( 0x4000000000000000 );
    344     return
    345            ( ( a.high & 0x7FFF ) == 0x7FFF )
    346         && (bits64) ( aLow<<1 )
    347         && ( a.low == aLow );
    348 
    349 }
    350 
    351 /*
    352 -------------------------------------------------------------------------------
    353 Returns the result of converting the extended double-precision floating-
    354 point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
    355 invalid exception is raised.
    356 -------------------------------------------------------------------------------
    357 */
    358 static commonNaNT floatx80ToCommonNaN( floatx80 a )
    359 {
    360     commonNaNT z;
    361 
    362     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    363     z.sign = a.high>>15;
    364     z.low = 0;
    365     z.high = a.low<<1;
    366     return z;
    367 
    368 }
    369 
    370 /*
    371 -------------------------------------------------------------------------------
    372 Returns the result of converting the canonical NaN `a' to the extended
    373 double-precision floating-point format.
    374 -------------------------------------------------------------------------------
    375 */
    376 static floatx80 commonNaNToFloatx80( commonNaNT a )
    377 {
    378     floatx80 z;
    379 
    380     z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
    381     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
    382     return z;
    383 
    384 }
    385 
    386 /*
    387 -------------------------------------------------------------------------------
    388 Takes two extended double-precision floating-point values `a' and `b', one
    389 of which is a NaN, and returns the appropriate NaN result.  If either `a' or
    390 `b' is a signaling NaN, the invalid exception is raised.
    391 -------------------------------------------------------------------------------
    392 */
    393 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
    394 {
    395     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    396 
    397     aIsNaN = floatx80_is_nan( a );
    398     aIsSignalingNaN = floatx80_is_signaling_nan( a );
    399     bIsNaN = floatx80_is_nan( b );
    400     bIsSignalingNaN = floatx80_is_signaling_nan( b );
    401     a.low |= LIT64( 0xC000000000000000 );
    402     b.low |= LIT64( 0xC000000000000000 );
    403     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    404     if ( aIsSignalingNaN ) {
    405         if ( bIsSignalingNaN ) goto returnLargerSignificand;
    406         return bIsNaN ? b : a;
    407     }
    408     else if ( aIsNaN ) {
    409         if ( bIsSignalingNaN | ! bIsNaN ) return a;
    410  returnLargerSignificand:
    411         if ( a.low < b.low ) return b;
    412         if ( b.low < a.low ) return a;
    413         return ( a.high < b.high ) ? a : b;
    414     }
    415     else {
    416         return b;
    417     }
    418 
    419 }
    420 
    421 #endif
    422 
    423 #ifdef FLOAT128
    424 
    425 /*
    426 -------------------------------------------------------------------------------
    427 The pattern for a default generated quadruple-precision NaN.  The `high' and
    428 `low' values hold the most- and least-significant bits, respectively.
    429 -------------------------------------------------------------------------------
    430 */
    431 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
    432 #define float128_default_nan_low  LIT64( 0x0000000000000000 )
    433 
    434 /*
    435 -------------------------------------------------------------------------------
    436 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
    437 otherwise returns 0.
    438 -------------------------------------------------------------------------------
    439 */
    440 flag float128_is_nan( float128 a )
    441 {
    442 
    443     return
    444            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
    445         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
    446 
    447 }
    448 
    449 /*
    450 -------------------------------------------------------------------------------
    451 Returns 1 if the quadruple-precision floating-point value `a' is a
    452 signaling NaN; otherwise returns 0.
    453 -------------------------------------------------------------------------------
    454 */
    455 flag float128_is_signaling_nan( float128 a )
    456 {
    457 
    458     return
    459            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
    460         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
    461 
    462 }
    463 
    464 /*
    465 -------------------------------------------------------------------------------
    466 Returns the result of converting the quadruple-precision floating-point NaN
    467 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    468 exception is raised.
    469 -------------------------------------------------------------------------------
    470 */
    471 static commonNaNT float128ToCommonNaN( float128 a )
    472 {
    473     commonNaNT z;
    474 
    475     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    476     z.sign = a.high>>63;
    477     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
    478     return z;
    479 
    480 }
    481 
    482 /*
    483 -------------------------------------------------------------------------------
    484 Returns the result of converting the canonical NaN `a' to the quadruple-
    485 precision floating-point format.
    486 -------------------------------------------------------------------------------
    487 */
    488 static float128 commonNaNToFloat128( commonNaNT a )
    489 {
    490     float128 z;
    491 
    492     shift128Right( a.high, a.low, 16, &z.high, &z.low );
    493     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
    494     return z;
    495 
    496 }
    497 
    498 /*
    499 -------------------------------------------------------------------------------
    500 Takes two quadruple-precision floating-point values `a' and `b', one of
    501 which is a NaN, and returns the appropriate NaN result.  If either `a' or
    502 `b' is a signaling NaN, the invalid exception is raised.
    503 -------------------------------------------------------------------------------
    504 */
    505 static float128 propagateFloat128NaN( float128 a, float128 b )
    506 {
    507     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    508 
    509     aIsNaN = float128_is_nan( a );
    510     aIsSignalingNaN = float128_is_signaling_nan( a );
    511     bIsNaN = float128_is_nan( b );
    512     bIsSignalingNaN = float128_is_signaling_nan( b );
    513     a.high |= LIT64( 0x0000800000000000 );
    514     b.high |= LIT64( 0x0000800000000000 );
    515     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    516     if ( aIsSignalingNaN ) {
    517         if ( bIsSignalingNaN ) goto returnLargerSignificand;
    518         return bIsNaN ? b : a;
    519     }
    520     else if ( aIsNaN ) {
    521         if ( bIsSignalingNaN | ! bIsNaN ) return a;
    522  returnLargerSignificand:
    523         if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
    524         if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
    525         return ( a.high < b.high ) ? a : b;
    526     }
    527     else {
    528         return b;
    529     }
    530 
    531 }
    532 
    533 #endif
    534 
    535