Home | History | Annotate | Line # | Download | only in softfloat
      1  1.14       nat /*	$NetBSD: softfloat-specialize,v 1.14 2025/09/17 11:42:17 nat Exp $	*/
      2   1.3     bjh21 
      3   1.3     bjh21 /* This is a derivative work. */
      4   1.1     bjh21 
      5   1.1     bjh21 /*
      6   1.1     bjh21 ===============================================================================
      7   1.1     bjh21 
      8   1.1     bjh21 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
      9   1.1     bjh21 Arithmetic Package, Release 2a.
     10   1.1     bjh21 
     11   1.1     bjh21 Written by John R. Hauser.  This work was made possible in part by the
     12   1.1     bjh21 International Computer Science Institute, located at Suite 600, 1947 Center
     13   1.1     bjh21 Street, Berkeley, California 94704.  Funding was partially provided by the
     14   1.1     bjh21 National Science Foundation under grant MIP-9311980.  The original version
     15   1.1     bjh21 of this code was written as part of a project to build a fixed-point vector
     16   1.1     bjh21 processor in collaboration with the University of California at Berkeley,
     17   1.1     bjh21 overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
     18   1.1     bjh21 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
     19   1.1     bjh21 arithmetic/SoftFloat.html'.
     20   1.1     bjh21 
     21   1.1     bjh21 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
     22   1.1     bjh21 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
     23   1.1     bjh21 TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
     24   1.1     bjh21 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
     25   1.1     bjh21 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
     26   1.1     bjh21 
     27   1.1     bjh21 Derivative works are acceptable, even for commercial purposes, so long as
     28   1.1     bjh21 (1) they include prominent notice that the work is derivative, and (2) they
     29   1.1     bjh21 include prominent notice akin to these four paragraphs for those parts of
     30   1.1     bjh21 this code that are retained.
     31   1.1     bjh21 
     32   1.1     bjh21 ===============================================================================
     33   1.1     bjh21 */
     34   1.1     bjh21 
     35   1.3     bjh21 #include <signal.h>
     36   1.5    martin #include <string.h>
     37   1.5    martin #include <unistd.h>
     38   1.3     bjh21 
     39  1.10  riastrad #include "reentrant.h"
     40  1.10  riastrad 
     41   1.1     bjh21 /*
     42   1.1     bjh21 -------------------------------------------------------------------------------
     43   1.1     bjh21 Underflow tininess-detection mode, statically initialized to default value.
     44   1.1     bjh21 (The declaration in `softfloat.h' must match the `int8' type here.)
     45   1.1     bjh21 -------------------------------------------------------------------------------
     46   1.1     bjh21 */
     47   1.1     bjh21 #ifdef SOFTFLOAT_FOR_GCC
     48   1.1     bjh21 static
     49   1.1     bjh21 #endif
     50   1.1     bjh21 int8 float_detect_tininess = float_tininess_after_rounding;
     51   1.1     bjh21 
     52   1.1     bjh21 /*
     53   1.1     bjh21 -------------------------------------------------------------------------------
     54   1.1     bjh21 Raises the exceptions specified by `flags'.  Floating-point traps can be
     55   1.1     bjh21 defined here if desired.  It is currently not possible for such a trap to
     56   1.1     bjh21 substitute a result value.  If traps are not implemented, this routine
     57   1.1     bjh21 should be simply `float_exception_flags |= flags;'.
     58   1.1     bjh21 -------------------------------------------------------------------------------
     59   1.1     bjh21 */
     60   1.6    martin #ifdef SOFTFLOAT_FOR_GCC
     61   1.8      matt #ifndef set_float_exception_mask
     62   1.6    martin #define float_exception_mask	_softfloat_float_exception_mask
     63   1.6    martin #endif
     64   1.8      matt #endif
     65   1.8      matt #ifndef set_float_exception_mask
     66   1.3     bjh21 fp_except float_exception_mask = 0;
     67   1.8      matt #endif
     68   1.8      matt void
     69  1.10  riastrad float_raise( fp_except newflags )
     70   1.1     bjh21 {
     71   1.5    martin     siginfo_t info;
     72  1.10  riastrad     struct sigaction sa;
     73  1.10  riastrad     sigset_t sigmask, osigmask;
     74  1.10  riastrad     fp_except flags;
     75   1.1     bjh21 
     76  1.10  riastrad     for (;;) {
     77   1.8      matt #ifdef set_float_exception_mask
     78  1.10  riastrad 	flags = newflags | set_float_exception_flags(newflags, 0);
     79   1.8      matt #else
     80  1.10  riastrad 	float_exception_flags |= newflags;
     81  1.10  riastrad 	flags = float_exception_flags;
     82   1.8      matt #endif
     83   1.1     bjh21 
     84  1.10  riastrad 	/*
     85  1.10  riastrad 	 * If none of the sticky flags are trapped (i.e., enabled in
     86  1.10  riastrad 	 * float_exception_mask), we're done.  Trapping is unusual and
     87  1.10  riastrad 	 * costly anyway, so take the non-trapping path as the fast
     88  1.10  riastrad 	 * path.
     89  1.10  riastrad 	 */
     90  1.10  riastrad 	flags &= float_exception_mask;
     91  1.10  riastrad 	if (__predict_true(flags == 0))
     92  1.10  riastrad 	    break;
     93  1.10  riastrad 
     94  1.10  riastrad 	/*
     95  1.10  riastrad 	 * Block all signals while we figure out how to deliver a
     96  1.10  riastrad 	 * non-maskable (as a signal), non-ignorable SIGFPE, and obtain
     97  1.10  riastrad 	 * the current signal mask.
     98  1.10  riastrad 	 */
     99  1.10  riastrad 	sigfillset(&sigmask);
    100  1.11  riastrad #ifdef _REENTRANT	/* XXX PR lib/59401 */
    101  1.10  riastrad 	thr_sigsetmask(SIG_BLOCK, &sigmask, &osigmask);
    102  1.11  riastrad #else
    103  1.11  riastrad 	sigprocmask(SIG_BLOCK, &sigmask, &osigmask);
    104  1.11  riastrad #endif
    105  1.10  riastrad 
    106  1.10  riastrad 	/*
    107  1.10  riastrad 	 * Find the current signal disposition of SIGFPE.
    108  1.10  riastrad 	 */
    109  1.10  riastrad 	sigaction(SIGFPE, NULL, &sa);
    110  1.10  riastrad 
    111  1.10  riastrad 	/*
    112  1.10  riastrad 	 * If SIGFPE is masked or ignored, unmask it and reset it to
    113  1.10  riastrad 	 * the default disposition to deliver the signal.
    114  1.10  riastrad 	 */
    115  1.10  riastrad 	if (sigismember(&osigmask, SIGFPE) ||
    116  1.10  riastrad 	    ((sa.sa_flags & SA_SIGINFO) == 0 &&
    117  1.10  riastrad 		sa.sa_handler == SIG_IGN)) {
    118  1.10  riastrad 		/*
    119  1.10  riastrad 		 * Prepare to unmask SIGFPE.  This will take effect
    120  1.10  riastrad 		 * when we use thr_sigsetmask(SIG_SETMASK, ...) below,
    121  1.10  riastrad 		 * once the signal has been queued, so that it happens
    122  1.10  riastrad 		 * atomically with respect to other signal delivery.
    123  1.10  riastrad 		 */
    124  1.10  riastrad 		sigdelset(&osigmask, SIGFPE);
    125  1.10  riastrad 
    126  1.10  riastrad 		/*
    127  1.10  riastrad 		 * Reset SIGFPE to the default disposition, which is to
    128  1.10  riastrad 		 * terminate the process.
    129  1.10  riastrad 		 */
    130  1.10  riastrad 		memset(&sa, 0, sizeof(sa));
    131  1.10  riastrad 		sa.sa_handler = SIG_DFL;
    132  1.10  riastrad 		sigemptyset(&sa.sa_mask);
    133  1.10  riastrad 		sa.sa_flags = 0;
    134  1.10  riastrad 		sigaction(SIGFPE, &sa, NULL);
    135  1.10  riastrad 	}
    136  1.10  riastrad 
    137  1.10  riastrad 	/*
    138  1.10  riastrad 	 * Queue the signal for delivery.  It won't trigger the signal
    139  1.10  riastrad 	 * handler yet, because it's still masked, but as soon as we
    140  1.10  riastrad 	 * unmask it either the process will terminate or the signal
    141  1.10  riastrad 	 * handler will be called.
    142  1.10  riastrad 	 */
    143   1.5    martin 	memset(&info, 0, sizeof info);
    144   1.5    martin 	info.si_signo = SIGFPE;
    145   1.5    martin 	info.si_pid = getpid();
    146   1.5    martin 	info.si_uid = geteuid();
    147   1.5    martin 	if (flags & float_flag_underflow)
    148   1.5    martin 	    info.si_code = FPE_FLTUND;
    149   1.5    martin 	else if (flags & float_flag_overflow)
    150   1.5    martin 	    info.si_code = FPE_FLTOVF;
    151   1.5    martin 	else if (flags & float_flag_divbyzero)
    152   1.5    martin 	    info.si_code = FPE_FLTDIV;
    153   1.5    martin 	else if (flags & float_flag_invalid)
    154   1.5    martin 	    info.si_code = FPE_FLTINV;
    155   1.5    martin 	else if (flags & float_flag_inexact)
    156   1.5    martin 	    info.si_code = FPE_FLTRES;
    157   1.5    martin 	sigqueueinfo(getpid(), &info);
    158  1.10  riastrad 
    159  1.10  riastrad 	/*
    160  1.10  riastrad 	 * Restore the old signal mask, except with SIGFPE unmasked
    161  1.10  riastrad 	 * even if it was masked before.
    162  1.10  riastrad 	 *
    163  1.10  riastrad 	 * At this point, either the process will terminate (if SIGFPE
    164  1.10  riastrad 	 * had or now has the default disposition) or the signal
    165  1.10  riastrad 	 * handler will be called (if SIGFPE had a non-default,
    166  1.10  riastrad 	 * non-ignored disposition).
    167  1.10  riastrad 	 *
    168  1.10  riastrad 	 * If the signal handler returns, it can't change the set of
    169  1.10  riastrad 	 * exceptions raised by this floating-point operation -- but it
    170  1.10  riastrad 	 * can change the sticky set from previous operations, and it
    171  1.10  riastrad 	 * can change the set of exceptions that are trapped, so loop
    172  1.10  riastrad 	 * around; next time we might make progress instead of calling
    173  1.10  riastrad 	 * the signal handler again.
    174  1.10  riastrad 	 */
    175  1.11  riastrad #ifdef _REENTRANT	/* XXX PR lib/59401 */
    176  1.10  riastrad 	thr_sigsetmask(SIG_SETMASK, &osigmask, NULL);
    177  1.11  riastrad #else
    178  1.11  riastrad 	sigprocmask(SIG_SETMASK, &osigmask, NULL);
    179  1.11  riastrad #endif
    180   1.3     bjh21     }
    181   1.1     bjh21 }
    182   1.6    martin #undef float_exception_mask
    183   1.1     bjh21 
    184   1.1     bjh21 /*
    185   1.1     bjh21 -------------------------------------------------------------------------------
    186   1.1     bjh21 Internal canonical NaN format.
    187   1.1     bjh21 -------------------------------------------------------------------------------
    188   1.1     bjh21 */
    189   1.1     bjh21 typedef struct {
    190   1.1     bjh21     flag sign;
    191   1.1     bjh21     bits64 high, low;
    192   1.1     bjh21 } commonNaNT;
    193   1.1     bjh21 
    194   1.1     bjh21 /*
    195   1.1     bjh21 -------------------------------------------------------------------------------
    196   1.1     bjh21 The pattern for a default generated single-precision NaN.
    197   1.1     bjh21 -------------------------------------------------------------------------------
    198   1.1     bjh21 */
    199   1.1     bjh21 #define float32_default_nan 0xFFFFFFFF
    200   1.1     bjh21 
    201   1.1     bjh21 /*
    202   1.1     bjh21 -------------------------------------------------------------------------------
    203   1.1     bjh21 Returns 1 if the single-precision floating-point value `a' is a NaN;
    204   1.1     bjh21 otherwise returns 0.
    205   1.1     bjh21 -------------------------------------------------------------------------------
    206   1.1     bjh21 */
    207   1.1     bjh21 #ifdef SOFTFLOAT_FOR_GCC
    208   1.1     bjh21 static
    209   1.1     bjh21 #endif
    210   1.1     bjh21 flag float32_is_nan( float32 a )
    211   1.1     bjh21 {
    212   1.1     bjh21 
    213   1.7  christos     return ( (bits32)0xFF000000 < (bits32) ( a<<1 ) );
    214   1.1     bjh21 
    215   1.1     bjh21 }
    216   1.1     bjh21 
    217   1.1     bjh21 /*
    218   1.1     bjh21 -------------------------------------------------------------------------------
    219   1.1     bjh21 Returns 1 if the single-precision floating-point value `a' is a signaling
    220   1.1     bjh21 NaN; otherwise returns 0.
    221   1.1     bjh21 -------------------------------------------------------------------------------
    222   1.1     bjh21 */
    223   1.9      matt #if defined(SOFTFLOAT_FOR_GCC) \
    224   1.9      matt     && !defined(SOFTFLOATAARCH64_FOR_GCC) \
    225   1.9      matt     && !defined(SOFTFLOATSPARC64_FOR_GCC) \
    226   1.9      matt     && !defined(SOFTFLOATM68K_FOR_GCC)
    227   1.1     bjh21 static
    228   1.1     bjh21 #endif
    229   1.1     bjh21 flag float32_is_signaling_nan( float32 a )
    230   1.1     bjh21 {
    231   1.1     bjh21 
    232   1.1     bjh21     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
    233   1.1     bjh21 
    234   1.1     bjh21 }
    235   1.1     bjh21 
    236   1.1     bjh21 /*
    237   1.1     bjh21 -------------------------------------------------------------------------------
    238   1.1     bjh21 Returns the result of converting the single-precision floating-point NaN
    239   1.1     bjh21 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    240   1.1     bjh21 exception is raised.
    241   1.1     bjh21 -------------------------------------------------------------------------------
    242   1.1     bjh21 */
    243   1.1     bjh21 static commonNaNT float32ToCommonNaN( float32 a )
    244   1.1     bjh21 {
    245   1.1     bjh21     commonNaNT z;
    246   1.1     bjh21 
    247   1.1     bjh21     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    248   1.1     bjh21     z.sign = a>>31;
    249   1.1     bjh21     z.low = 0;
    250   1.1     bjh21     z.high = ( (bits64) a )<<41;
    251   1.1     bjh21     return z;
    252   1.1     bjh21 
    253   1.1     bjh21 }
    254   1.1     bjh21 
    255   1.1     bjh21 /*
    256   1.1     bjh21 -------------------------------------------------------------------------------
    257   1.1     bjh21 Returns the result of converting the canonical NaN `a' to the single-
    258   1.1     bjh21 precision floating-point format.
    259   1.1     bjh21 -------------------------------------------------------------------------------
    260   1.1     bjh21 */
    261   1.1     bjh21 static float32 commonNaNToFloat32( commonNaNT a )
    262   1.1     bjh21 {
    263   1.1     bjh21 
    264   1.7  christos     return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | (bits32)( a.high>>41 );
    265   1.1     bjh21 
    266   1.1     bjh21 }
    267   1.1     bjh21 
    268   1.1     bjh21 /*
    269   1.1     bjh21 -------------------------------------------------------------------------------
    270   1.1     bjh21 Takes two single-precision floating-point values `a' and `b', one of which
    271   1.1     bjh21 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
    272   1.1     bjh21 signaling NaN, the invalid exception is raised.
    273   1.1     bjh21 -------------------------------------------------------------------------------
    274   1.1     bjh21 */
    275   1.1     bjh21 static float32 propagateFloat32NaN( float32 a, float32 b )
    276   1.1     bjh21 {
    277   1.1     bjh21     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    278   1.1     bjh21 
    279   1.1     bjh21     aIsNaN = float32_is_nan( a );
    280   1.1     bjh21     aIsSignalingNaN = float32_is_signaling_nan( a );
    281   1.1     bjh21     bIsNaN = float32_is_nan( b );
    282   1.1     bjh21     bIsSignalingNaN = float32_is_signaling_nan( b );
    283   1.1     bjh21     a |= 0x00400000;
    284   1.1     bjh21     b |= 0x00400000;
    285   1.1     bjh21     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    286   1.1     bjh21     if ( aIsNaN ) {
    287   1.1     bjh21         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
    288   1.1     bjh21     }
    289   1.1     bjh21     else {
    290   1.1     bjh21         return b;
    291   1.1     bjh21     }
    292   1.1     bjh21 
    293   1.1     bjh21 }
    294   1.1     bjh21 
    295   1.1     bjh21 /*
    296   1.1     bjh21 -------------------------------------------------------------------------------
    297   1.1     bjh21 The pattern for a default generated double-precision NaN.
    298   1.1     bjh21 -------------------------------------------------------------------------------
    299   1.1     bjh21 */
    300   1.1     bjh21 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
    301   1.1     bjh21 
    302   1.1     bjh21 /*
    303   1.1     bjh21 -------------------------------------------------------------------------------
    304   1.1     bjh21 Returns 1 if the double-precision floating-point value `a' is a NaN;
    305   1.1     bjh21 otherwise returns 0.
    306   1.1     bjh21 -------------------------------------------------------------------------------
    307   1.1     bjh21 */
    308   1.1     bjh21 #ifdef SOFTFLOAT_FOR_GCC
    309   1.1     bjh21 static
    310   1.1     bjh21 #endif
    311   1.1     bjh21 flag float64_is_nan( float64 a )
    312   1.1     bjh21 {
    313   1.1     bjh21 
    314   1.7  christos     return ( (bits64)LIT64( 0xFFE0000000000000 ) <
    315   1.1     bjh21 	     (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) );
    316   1.1     bjh21 
    317   1.1     bjh21 }
    318   1.1     bjh21 
    319   1.1     bjh21 /*
    320   1.1     bjh21 -------------------------------------------------------------------------------
    321   1.1     bjh21 Returns 1 if the double-precision floating-point value `a' is a signaling
    322   1.1     bjh21 NaN; otherwise returns 0.
    323   1.1     bjh21 -------------------------------------------------------------------------------
    324   1.1     bjh21 */
    325   1.9      matt #if defined(SOFTFLOAT_FOR_GCC) \
    326   1.9      matt     && !defined(SOFTFLOATAARCH64_FOR_GCC) \
    327   1.9      matt     && !defined(SOFTFLOATSPARC64_FOR_GCC) \
    328   1.9      matt     && !defined(SOFTFLOATM68K_FOR_GCC)
    329   1.1     bjh21 static
    330   1.1     bjh21 #endif
    331   1.1     bjh21 flag float64_is_signaling_nan( float64 a )
    332   1.1     bjh21 {
    333   1.1     bjh21 
    334   1.1     bjh21     return
    335   1.1     bjh21            ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
    336   1.1     bjh21         && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
    337   1.1     bjh21 
    338   1.1     bjh21 }
    339   1.1     bjh21 
    340   1.1     bjh21 /*
    341   1.1     bjh21 -------------------------------------------------------------------------------
    342   1.1     bjh21 Returns the result of converting the double-precision floating-point NaN
    343   1.1     bjh21 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    344   1.1     bjh21 exception is raised.
    345   1.1     bjh21 -------------------------------------------------------------------------------
    346   1.1     bjh21 */
    347   1.1     bjh21 static commonNaNT float64ToCommonNaN( float64 a )
    348   1.1     bjh21 {
    349   1.1     bjh21     commonNaNT z;
    350   1.1     bjh21 
    351   1.1     bjh21     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    352   1.7  christos     z.sign = (flag)(FLOAT64_DEMANGLE(a)>>63);
    353   1.1     bjh21     z.low = 0;
    354   1.1     bjh21     z.high = FLOAT64_DEMANGLE(a)<<12;
    355   1.1     bjh21     return z;
    356   1.1     bjh21 
    357   1.1     bjh21 }
    358   1.1     bjh21 
    359   1.1     bjh21 /*
    360   1.1     bjh21 -------------------------------------------------------------------------------
    361   1.1     bjh21 Returns the result of converting the canonical NaN `a' to the double-
    362   1.1     bjh21 precision floating-point format.
    363   1.1     bjh21 -------------------------------------------------------------------------------
    364   1.1     bjh21 */
    365   1.1     bjh21 static float64 commonNaNToFloat64( commonNaNT a )
    366   1.1     bjh21 {
    367   1.1     bjh21 
    368   1.1     bjh21     return FLOAT64_MANGLE(
    369   1.1     bjh21 	( ( (bits64) a.sign )<<63 )
    370   1.1     bjh21         | LIT64( 0x7FF8000000000000 )
    371   1.1     bjh21         | ( a.high>>12 ) );
    372   1.1     bjh21 
    373   1.1     bjh21 }
    374   1.1     bjh21 
    375   1.1     bjh21 /*
    376   1.1     bjh21 -------------------------------------------------------------------------------
    377   1.1     bjh21 Takes two double-precision floating-point values `a' and `b', one of which
    378   1.1     bjh21 is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
    379   1.1     bjh21 signaling NaN, the invalid exception is raised.
    380   1.1     bjh21 -------------------------------------------------------------------------------
    381   1.1     bjh21 */
    382   1.1     bjh21 static float64 propagateFloat64NaN( float64 a, float64 b )
    383   1.1     bjh21 {
    384   1.1     bjh21     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    385   1.1     bjh21 
    386   1.1     bjh21     aIsNaN = float64_is_nan( a );
    387   1.1     bjh21     aIsSignalingNaN = float64_is_signaling_nan( a );
    388   1.1     bjh21     bIsNaN = float64_is_nan( b );
    389   1.1     bjh21     bIsSignalingNaN = float64_is_signaling_nan( b );
    390   1.1     bjh21     a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
    391   1.1     bjh21     b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
    392   1.1     bjh21     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    393   1.1     bjh21     if ( aIsNaN ) {
    394   1.1     bjh21         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
    395   1.1     bjh21     }
    396   1.1     bjh21     else {
    397   1.1     bjh21         return b;
    398   1.1     bjh21     }
    399   1.1     bjh21 
    400   1.1     bjh21 }
    401   1.1     bjh21 
    402   1.1     bjh21 #ifdef FLOATX80
    403   1.1     bjh21 
    404   1.1     bjh21 /*
    405   1.1     bjh21 -------------------------------------------------------------------------------
    406   1.1     bjh21 The pattern for a default generated extended double-precision NaN.  The
    407   1.1     bjh21 `high' and `low' values hold the most- and least-significant bits,
    408   1.1     bjh21 respectively.
    409   1.1     bjh21 -------------------------------------------------------------------------------
    410   1.1     bjh21 */
    411   1.1     bjh21 #define floatx80_default_nan_high 0xFFFF
    412   1.1     bjh21 #define floatx80_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
    413   1.1     bjh21 
    414   1.1     bjh21 /*
    415   1.1     bjh21 -------------------------------------------------------------------------------
    416   1.1     bjh21 Returns 1 if the extended double-precision floating-point value `a' is a
    417   1.1     bjh21 NaN; otherwise returns 0.
    418   1.1     bjh21 -------------------------------------------------------------------------------
    419   1.1     bjh21 */
    420   1.1     bjh21 flag floatx80_is_nan( floatx80 a )
    421   1.1     bjh21 {
    422   1.1     bjh21 
    423  1.13       nat     return (((a.high >> X80SHIFT) & 0x7FFF) == 0x7FFF) && (bits64)(a.low<<1);
    424   1.1     bjh21 
    425   1.1     bjh21 }
    426   1.1     bjh21 
    427   1.1     bjh21 /*
    428   1.1     bjh21 -------------------------------------------------------------------------------
    429   1.1     bjh21 Returns 1 if the extended double-precision floating-point value `a' is a
    430   1.1     bjh21 signaling NaN; otherwise returns 0.
    431   1.1     bjh21 -------------------------------------------------------------------------------
    432   1.1     bjh21 */
    433   1.1     bjh21 flag floatx80_is_signaling_nan( floatx80 a )
    434   1.1     bjh21 {
    435   1.1     bjh21     bits64 aLow;
    436   1.1     bjh21 
    437   1.1     bjh21     aLow = a.low & ~ LIT64( 0x4000000000000000 );
    438   1.1     bjh21     return
    439  1.13       nat            ( ( (a.high >> X80SHIFT) & 0x7FFF ) == 0x7FFF )
    440   1.1     bjh21         && (bits64) ( aLow<<1 )
    441   1.1     bjh21         && ( a.low == aLow );
    442   1.1     bjh21 
    443   1.1     bjh21 }
    444   1.1     bjh21 
    445  1.12       nat #ifndef SOFTFLOAT_BITS32
    446   1.1     bjh21 /*
    447   1.1     bjh21 -------------------------------------------------------------------------------
    448   1.1     bjh21 Returns the result of converting the extended double-precision floating-
    449   1.1     bjh21 point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
    450   1.1     bjh21 invalid exception is raised.
    451   1.1     bjh21 -------------------------------------------------------------------------------
    452   1.1     bjh21 */
    453   1.1     bjh21 static commonNaNT floatx80ToCommonNaN( floatx80 a )
    454   1.1     bjh21 {
    455   1.1     bjh21     commonNaNT z;
    456   1.1     bjh21 
    457   1.1     bjh21     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    458  1.14       nat     z.sign = a.high>>(15 + X80SHIFT);
    459  1.14       nat     z.low = a.low<<1;
    460  1.14       nat     z.high = (a.high>>X80SHIFT) & 0x7FFF;
    461   1.1     bjh21     return z;
    462   1.1     bjh21 
    463   1.1     bjh21 }
    464   1.1     bjh21 
    465   1.1     bjh21 /*
    466   1.1     bjh21 -------------------------------------------------------------------------------
    467   1.1     bjh21 Returns the result of converting the canonical NaN `a' to the extended
    468   1.1     bjh21 double-precision floating-point format.
    469   1.1     bjh21 -------------------------------------------------------------------------------
    470   1.1     bjh21 */
    471   1.1     bjh21 static floatx80 commonNaNToFloatx80( commonNaNT a )
    472   1.1     bjh21 {
    473   1.1     bjh21     floatx80 z;
    474   1.1     bjh21 
    475  1.14       nat     z.low = LIT64( 0xC000000000000000 ) | ( a.low );
    476  1.14       nat     z.high = (( ( (bits16) a.sign )<<15 ) | 0x7FFF) << X80SHIFT;
    477   1.1     bjh21     return z;
    478   1.1     bjh21 
    479   1.1     bjh21 }
    480   1.1     bjh21 
    481   1.1     bjh21 /*
    482   1.1     bjh21 -------------------------------------------------------------------------------
    483   1.1     bjh21 Takes two extended double-precision floating-point values `a' and `b', one
    484   1.1     bjh21 of which is a NaN, and returns the appropriate NaN result.  If either `a' or
    485   1.1     bjh21 `b' is a signaling NaN, the invalid exception is raised.
    486   1.1     bjh21 -------------------------------------------------------------------------------
    487   1.1     bjh21 */
    488   1.1     bjh21 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
    489   1.1     bjh21 {
    490   1.1     bjh21     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    491   1.1     bjh21 
    492   1.1     bjh21     aIsNaN = floatx80_is_nan( a );
    493   1.1     bjh21     aIsSignalingNaN = floatx80_is_signaling_nan( a );
    494   1.1     bjh21     bIsNaN = floatx80_is_nan( b );
    495   1.1     bjh21     bIsSignalingNaN = floatx80_is_signaling_nan( b );
    496   1.1     bjh21     a.low |= LIT64( 0xC000000000000000 );
    497   1.1     bjh21     b.low |= LIT64( 0xC000000000000000 );
    498   1.1     bjh21     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    499   1.1     bjh21     if ( aIsNaN ) {
    500   1.1     bjh21         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
    501   1.1     bjh21     }
    502   1.1     bjh21     else {
    503   1.1     bjh21         return b;
    504   1.1     bjh21     }
    505   1.1     bjh21 
    506   1.1     bjh21 }
    507   1.1     bjh21 
    508   1.1     bjh21 #endif
    509  1.12       nat #endif
    510   1.1     bjh21 
    511   1.1     bjh21 #ifdef FLOAT128
    512   1.1     bjh21 
    513   1.1     bjh21 /*
    514   1.1     bjh21 -------------------------------------------------------------------------------
    515   1.1     bjh21 The pattern for a default generated quadruple-precision NaN.  The `high' and
    516   1.1     bjh21 `low' values hold the most- and least-significant bits, respectively.
    517   1.1     bjh21 -------------------------------------------------------------------------------
    518   1.1     bjh21 */
    519   1.1     bjh21 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
    520   1.1     bjh21 #define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
    521   1.1     bjh21 
    522   1.1     bjh21 /*
    523   1.1     bjh21 -------------------------------------------------------------------------------
    524   1.1     bjh21 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
    525   1.1     bjh21 otherwise returns 0.
    526   1.1     bjh21 -------------------------------------------------------------------------------
    527   1.1     bjh21 */
    528   1.1     bjh21 flag float128_is_nan( float128 a )
    529   1.1     bjh21 {
    530   1.1     bjh21 
    531   1.1     bjh21     return
    532   1.7  christos            ( (bits64)LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
    533   1.1     bjh21         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
    534   1.1     bjh21 
    535   1.1     bjh21 }
    536   1.1     bjh21 
    537   1.1     bjh21 /*
    538   1.1     bjh21 -------------------------------------------------------------------------------
    539   1.1     bjh21 Returns 1 if the quadruple-precision floating-point value `a' is a
    540   1.1     bjh21 signaling NaN; otherwise returns 0.
    541   1.1     bjh21 -------------------------------------------------------------------------------
    542   1.1     bjh21 */
    543   1.1     bjh21 flag float128_is_signaling_nan( float128 a )
    544   1.1     bjh21 {
    545   1.1     bjh21 
    546   1.1     bjh21     return
    547   1.1     bjh21            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
    548   1.1     bjh21         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
    549   1.1     bjh21 
    550   1.1     bjh21 }
    551   1.1     bjh21 
    552   1.1     bjh21 /*
    553   1.1     bjh21 -------------------------------------------------------------------------------
    554   1.1     bjh21 Returns the result of converting the quadruple-precision floating-point NaN
    555   1.1     bjh21 `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
    556   1.1     bjh21 exception is raised.
    557   1.1     bjh21 -------------------------------------------------------------------------------
    558   1.1     bjh21 */
    559   1.1     bjh21 static commonNaNT float128ToCommonNaN( float128 a )
    560   1.1     bjh21 {
    561   1.1     bjh21     commonNaNT z;
    562   1.1     bjh21 
    563   1.1     bjh21     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
    564   1.7  christos     z.sign = (flag)(a.high>>63);
    565   1.1     bjh21     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
    566   1.1     bjh21     return z;
    567   1.1     bjh21 
    568   1.1     bjh21 }
    569   1.1     bjh21 
    570   1.1     bjh21 /*
    571   1.1     bjh21 -------------------------------------------------------------------------------
    572   1.1     bjh21 Returns the result of converting the canonical NaN `a' to the quadruple-
    573   1.1     bjh21 precision floating-point format.
    574   1.1     bjh21 -------------------------------------------------------------------------------
    575   1.1     bjh21 */
    576   1.1     bjh21 static float128 commonNaNToFloat128( commonNaNT a )
    577   1.1     bjh21 {
    578   1.1     bjh21     float128 z;
    579   1.1     bjh21 
    580   1.1     bjh21     shift128Right( a.high, a.low, 16, &z.high, &z.low );
    581   1.1     bjh21     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
    582   1.1     bjh21     return z;
    583   1.1     bjh21 
    584   1.1     bjh21 }
    585   1.1     bjh21 
    586   1.1     bjh21 /*
    587   1.1     bjh21 -------------------------------------------------------------------------------
    588   1.1     bjh21 Takes two quadruple-precision floating-point values `a' and `b', one of
    589   1.1     bjh21 which is a NaN, and returns the appropriate NaN result.  If either `a' or
    590   1.1     bjh21 `b' is a signaling NaN, the invalid exception is raised.
    591   1.1     bjh21 -------------------------------------------------------------------------------
    592   1.1     bjh21 */
    593   1.1     bjh21 static float128 propagateFloat128NaN( float128 a, float128 b )
    594   1.1     bjh21 {
    595   1.1     bjh21     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
    596   1.1     bjh21 
    597   1.1     bjh21     aIsNaN = float128_is_nan( a );
    598   1.1     bjh21     aIsSignalingNaN = float128_is_signaling_nan( a );
    599   1.1     bjh21     bIsNaN = float128_is_nan( b );
    600   1.1     bjh21     bIsSignalingNaN = float128_is_signaling_nan( b );
    601   1.1     bjh21     a.high |= LIT64( 0x0000800000000000 );
    602   1.1     bjh21     b.high |= LIT64( 0x0000800000000000 );
    603   1.1     bjh21     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
    604   1.1     bjh21     if ( aIsNaN ) {
    605   1.1     bjh21         return ( aIsSignalingNaN & bIsNaN ) ? b : a;
    606   1.1     bjh21     }
    607   1.1     bjh21     else {
    608   1.1     bjh21         return b;
    609   1.1     bjh21     }
    610   1.1     bjh21 
    611   1.1     bjh21 }
    612   1.1     bjh21 
    613   1.1     bjh21 #endif
    614   1.1     bjh21 
    615