root/lib/libkern/softfloat-specialize.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. commonNaNT
  2. float32_is_nan
  3. float32_is_signaling_nan
  4. float32ToCommonNaN
  5. commonNaNToFloat32
  6. propagateFloat32NaN
  7. float64ToCommonNaN
  8. commonNaNToFloat64
  9. propagateFloat64NaN
  10. floatx80_is_nan
  11. floatx80_is_signaling_nan
  12. floatx80ToCommonNaN
  13. commonNaNToFloatx80
  14. propagateFloatx80NaN
  15. float128_is_nan
  16. float128_is_signaling_nan
  17. float128ToCommonNaN
  18. commonNaNToFloat128
  19. propagateFloat128NaN

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

/* [<][>][^][v][top][bottom][index][help] */