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