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