The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/lib/libkern/softfloat-specialize.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: e8bb272f6628940b34ca55778631e6bd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.