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