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