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