Home | History | Annotate | Download | only in templates
      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 int8 float_detect_tininess = float_tininess_after_rounding;
     39 
     40 /*
     41 -------------------------------------------------------------------------------
     42 Raises the exceptions specified by `flags'.  Floating-point traps can be
     43 defined here if desired.  It is currently not possible for such a trap to
     44 substitute a result value.  If traps are not implemented, this routine
     45 should be simply `float_exception_flags |= flags;'.
     46 -------------------------------------------------------------------------------
     47 */
     48 void float_raise( int8 flags )
     49 {
     50 
     51     float_exception_flags |= flags;
     52 
     53 }
     54 
     55 /*
     56 -------------------------------------------------------------------------------
     57 Internal canonical NaN format.
     58 -------------------------------------------------------------------------------
     59 */
     60 typedef struct {
     61     flag sign;
     62     bits64 high, low;
     63 } commonNaNT;
     64 
     65 /*
     66 -------------------------------------------------------------------------------
     67 The pattern for a default generated single-precision NaN.
     68 -------------------------------------------------------------------------------
     69 */
     70 #define float32_default_nan 0xFFFFFFFF
     71 
     72 /*
     73 -------------------------------------------------------------------------------
     74 Returns 1 if the single-precision floating-point value `a' is a NaN;
     75 otherwise returns 0.
     76 -------------------------------------------------------------------------------
     77 */
     78 flag float32_is_nan( float32 a )
     79 {
     80 
     81     return ( 0xFF000000 < (bits32) ( a<<1 ) );
     82 
     83 }
     84 
     85 /*
     86 -------------------------------------------------------------------------------
     87 Returns 1 if the single-precision floating-point value `a' is a signaling
     88 NaN; otherwise returns 0.
     89 -------------------------------------------------------------------------------
     90 */
     91 flag float32_is_signaling_nan( float32 a )
     92 {
     93 
     94     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
     95 
     96 }
     97 
     98 /*
     99 -------------------------------------------------------------------------------
    100 Returns the result of converting the single-precision floating-point NaN
    101 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    102 exception is raised.
    103 -------------------------------------------------------------------------------
    104 */
    105 static commonNaNT float32ToCommonNaN( float32 a )
    106 {
    107     commonNaNT z;
    108 
    109     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    110     z.sign = a>>31;
    111     z.low = 0;
    112     z.high = ( (bits64) a )<<41;
    113     return z;
    114 
    115 }
    116 
    117 /*
    118 -------------------------------------------------------------------------------
    119 Returns the result of converting the canonical NaN `a' to the single-
    120 precision floating-point format.
    121 -------------------------------------------------------------------------------
    122 */
    123 static float32 commonNaNToFloat32( commonNaNT a )
    124 {
    125 
    126     return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
    127 
    128 }
    129 
    130 /*
    131 -------------------------------------------------------------------------------
    132 Takes two single-precision floating-point values `a' and `b', one of which
    133 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
    134 signaling NaN, the invalid exception is raised.
    135 -------------------------------------------------------------------------------
    136 */
    137 static float32 propagateFloat32NaN( float32 a, float32 b )
    138 {
    139     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    140 
    141     aIsNaN = float32_is_nan( a );
    142     aIsSignalingNaN = float32_is_signaling_nan( a );
    143     bIsNaN = float32_is_nan( b );
    144     bIsSignalingNaN = float32_is_signaling_nan( b );
    145     a |= 0x00400000;
    146     b |= 0x00400000;
    147     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    148     if ( aIsNaN ) {
    149         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
    150     }
    151     else {
    152         return b;
    153     }
    154 
    155 }
    156 
    157 /*
    158 -------------------------------------------------------------------------------
    159 The pattern for a default generated double-precision NaN.
    160 -------------------------------------------------------------------------------
    161 */
    162 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
    163 
    164 /*
    165 -------------------------------------------------------------------------------
    166 Returns 1 if the double-precision floating-point value `a' is a NaN;
    167 otherwise returns 0.
    168 -------------------------------------------------------------------------------
    169 */
    170 flag float64_is_nan( float64 a )
    171 {
    172 
    173     return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
    174 
    175 }
    176 
    177 /*
    178 -------------------------------------------------------------------------------
    179 Returns 1 if the double-precision floating-point value `a' is a signaling
    180 NaN; otherwise returns 0.
    181 -------------------------------------------------------------------------------
    182 */
    183 flag float64_is_signaling_nan( float64 a )
    184 {
    185 
    186     return
    187            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
    188         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
    189 
    190 }
    191 
    192 /*
    193 -------------------------------------------------------------------------------
    194 Returns the result of converting the double-precision floating-point NaN
    195 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    196 exception is raised.
    197 -------------------------------------------------------------------------------
    198 */
    199 static commonNaNT float64ToCommonNaN( float64 a )
    200 {
    201     commonNaNT z;
    202 
    203     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    204     z.sign = a>>63;
    205     z.low = 0;
    206     z.high = a<<12;
    207     return z;
    208 
    209 }
    210 
    211 /*
    212 -------------------------------------------------------------------------------
    213 Returns the result of converting the canonical NaN `a' to the double-
    214 precision floating-point format.
    215 -------------------------------------------------------------------------------
    216 */
    217 static float64 commonNaNToFloat64( commonNaNT a )
    218 {
    219 
    220     return
    221           ( ( (bits64) a.sign )<<63 )
    222         | LIT64( 0x7FF8000000000000 )
    223         | ( a.high>>12 );
    224 
    225 }
    226 
    227 /*
    228 -------------------------------------------------------------------------------
    229 Takes two double-precision floating-point values `a' and `b', one of which
    230 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
    231 signaling NaN, the invalid exception is raised.
    232 -------------------------------------------------------------------------------
    233 */
    234 static float64 propagateFloat64NaN( float64 a, float64 b )
    235 {
    236     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    237 
    238     aIsNaN = float64_is_nan( a );
    239     aIsSignalingNaN = float64_is_signaling_nan( a );
    240     bIsNaN = float64_is_nan( b );
    241     bIsSignalingNaN = float64_is_signaling_nan( b );
    242     a |= LIT64( 0x0008000000000000 );
    243     b |= LIT64( 0x0008000000000000 );
    244     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    245     if ( aIsNaN ) {
    246         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
    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( 0xFFFFFFFFFFFFFFFF )
    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 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 ( aIsNaN ) {
    351         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
    352     }
    353     else {
    354         return b;
    355     }
    356 
    357 }
    358 
    359 #endif
    360 
    361 #ifdef FLOAT128
    362 
    363 /*
    364 -------------------------------------------------------------------------------
    365 The pattern for a default generated quadruple-precision NaN.  The `high' and
    366 `low' values hold the most- and least-significant bits, respectively.
    367 -------------------------------------------------------------------------------
    368 */
    369 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
    370 #define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
    371 
    372 /*
    373 -------------------------------------------------------------------------------
    374 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
    375 otherwise returns 0.
    376 -------------------------------------------------------------------------------
    377 */
    378 flag float128_is_nan( float128 a )
    379 {
    380 
    381     return
    382            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
    383         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
    384 
    385 }
    386 
    387 /*
    388 -------------------------------------------------------------------------------
    389 Returns 1 if the quadruple-precision floating-point value `a' is a
    390 signaling NaN; otherwise returns 0.
    391 -------------------------------------------------------------------------------
    392 */
    393 flag float128_is_signaling_nan( float128 a )
    394 {
    395 
    396     return
    397            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
    398         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
    399 
    400 }
    401 
    402 /*
    403 -------------------------------------------------------------------------------
    404 Returns the result of converting the quadruple-precision floating-point NaN
    405 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    406 exception is raised.
    407 -------------------------------------------------------------------------------
    408 */
    409 static commonNaNT float128ToCommonNaN( float128 a )
    410 {
    411     commonNaNT z;
    412 
    413     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    414     z.sign = a.high>>63;
    415     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
    416     return z;
    417 
    418 }
    419 
    420 /*
    421 -------------------------------------------------------------------------------
    422 Returns the result of converting the canonical NaN `a' to the quadruple-
    423 precision floating-point format.
    424 -------------------------------------------------------------------------------
    425 */
    426 static float128 commonNaNToFloat128( commonNaNT a )
    427 {
    428     float128 z;
    429 
    430     shift128Right( a.high, a.low, 16, &z.high, &z.low );
    431     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
    432     return z;
    433 
    434 }
    435 
    436 /*
    437 -------------------------------------------------------------------------------
    438 Takes two quadruple-precision floating-point values `a' and `b', one of
    439 which is a NaN, and returns the appropriate NaN result.  If either `a' or
    440 `b' is a signaling NaN, the invalid exception is raised.
    441 -------------------------------------------------------------------------------
    442 */
    443 static float128 propagateFloat128NaN( float128 a, float128 b )
    444 {
    445     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    446 
    447     aIsNaN = float128_is_nan( a );
    448     aIsSignalingNaN = float128_is_signaling_nan( a );
    449     bIsNaN = float128_is_nan( b );
    450     bIsSignalingNaN = float128_is_signaling_nan( b );
    451     a.high |= LIT64( 0x0000800000000000 );
    452     b.high |= LIT64( 0x0000800000000000 );
    453     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    454     if ( aIsNaN ) {
    455         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
    456     }
    457     else {
    458         return b;
    459     }
    460 
    461 }
    462 
    463 #endif
    464 
    465