xref: /openbsd-src/sys/arch/hppa/spmath/dfcmp.c (revision 449b444aa9c7d5428e3352b273ef6caa05cc93f5)
1*449b444aSmickey /*	$OpenBSD: dfcmp.c,v 1.6 2002/09/20 19:26:59 mickey Exp $	*/
28a472b3eSmickey /*
3c2feb252Smickey   (c) Copyright 1986 HEWLETT-PACKARD COMPANY
4c2feb252Smickey   To anyone who acknowledges that this file is provided "AS IS"
5c2feb252Smickey   without any express or implied warranty:
6c2feb252Smickey       permission to use, copy, modify, and distribute this file
7c2feb252Smickey   for any purpose is hereby granted without fee, provided that
8c2feb252Smickey   the above copyright notice and this notice appears in all
9c2feb252Smickey   copies, and that the name of Hewlett-Packard Company not be
10c2feb252Smickey   used in advertising or publicity pertaining to distribution
11c2feb252Smickey   of the software without specific, written prior permission.
12c2feb252Smickey   Hewlett-Packard Company makes no representations about the
13c2feb252Smickey   suitability of this software for any purpose.
148a472b3eSmickey */
15c2feb252Smickey /* @(#)dfcmp.c: Revision: 1.7.88.2 Date: 93/12/08 13:26:38 */
168a472b3eSmickey 
17c2feb252Smickey #include "float.h"
18c2feb252Smickey #include "dbl_float.h"
198a472b3eSmickey 
208a472b3eSmickey /*
218a472b3eSmickey  * dbl_cmp: compare two values
228a472b3eSmickey  */
23b94afd46Smickey int
dbl_fcmp(leftptr,rightptr,cond,status)248a472b3eSmickey dbl_fcmp(leftptr, rightptr, cond, status)
258a472b3eSmickey     dbl_floating_point *leftptr, *rightptr;
268a472b3eSmickey     unsigned int cond; /* The predicate to be tested */
278a472b3eSmickey     unsigned int *status;
288a472b3eSmickey {
298a472b3eSmickey     register unsigned int leftp1, leftp2, rightp1, rightp2;
308a472b3eSmickey     register int xorresult;
318a472b3eSmickey 
328a472b3eSmickey     /* Create local copies of the numbers */
338a472b3eSmickey     Dbl_copyfromptr(leftptr,leftp1,leftp2);
348a472b3eSmickey     Dbl_copyfromptr(rightptr,rightp1,rightp2);
358a472b3eSmickey     /*
368a472b3eSmickey      * Test for NaN
378a472b3eSmickey      */
388a472b3eSmickey     if(    (Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
398a472b3eSmickey 	|| (Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT) )
408a472b3eSmickey 	{
418a472b3eSmickey 	/* Check if a NaN is involved.  Signal an invalid exception when
428a472b3eSmickey 	 * comparing a signaling NaN or when comparing quiet NaNs and the
438a472b3eSmickey 	 * low bit of the condition is set */
448a472b3eSmickey 	if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
458a472b3eSmickey 	    && Dbl_isnotzero_mantissa(leftp1,leftp2)
468a472b3eSmickey 	    && (Exception(cond) || Dbl_isone_signaling(leftp1)))
478a472b3eSmickey 	   ||
488a472b3eSmickey 	    ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT)
498a472b3eSmickey 	    && Dbl_isnotzero_mantissa(rightp1,rightp2)
508a472b3eSmickey 	    && (Exception(cond) || Dbl_isone_signaling(rightp1))) )
518a472b3eSmickey 	    {
528a472b3eSmickey 	    if( Is_invalidtrap_enabled() ) {
538a472b3eSmickey 		Set_status_cbit(Unordered(cond));
548a472b3eSmickey 		return(INVALIDEXCEPTION);
558a472b3eSmickey 	    }
568a472b3eSmickey 	    else Set_invalidflag();
578a472b3eSmickey 	    Set_status_cbit(Unordered(cond));
588a472b3eSmickey 	    return(NOEXCEPTION);
598a472b3eSmickey 	    }
608a472b3eSmickey 	/* All the exceptional conditions are handled, now special case
618a472b3eSmickey 	   NaN compares */
628a472b3eSmickey 	else if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
638a472b3eSmickey 	    && Dbl_isnotzero_mantissa(leftp1,leftp2))
648a472b3eSmickey 	   ||
658a472b3eSmickey 	    ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT)
668a472b3eSmickey 	    && Dbl_isnotzero_mantissa(rightp1,rightp2)) )
678a472b3eSmickey 	    {
688a472b3eSmickey 	    /* NaNs always compare unordered. */
698a472b3eSmickey 	    Set_status_cbit(Unordered(cond));
708a472b3eSmickey 	    return(NOEXCEPTION);
718a472b3eSmickey 	    }
728a472b3eSmickey 	/* infinities will drop down to the normal compare mechanisms */
738a472b3eSmickey 	}
748a472b3eSmickey     /* First compare for unequal signs => less or greater or
758a472b3eSmickey      * special equal case */
768a472b3eSmickey     Dbl_xortointp1(leftp1,rightp1,xorresult);
778a472b3eSmickey     if( xorresult < 0 )
788a472b3eSmickey 	{
798a472b3eSmickey 	/* left negative => less, left positive => greater.
808a472b3eSmickey 	 * equal is possible if both operands are zeros. */
818a472b3eSmickey 	if( Dbl_iszero_exponentmantissa(leftp1,leftp2)
828a472b3eSmickey 	  && Dbl_iszero_exponentmantissa(rightp1,rightp2) )
838a472b3eSmickey 	    {
848a472b3eSmickey 	    Set_status_cbit(Equal(cond));
858a472b3eSmickey 	    }
868a472b3eSmickey 	else if( Dbl_isone_sign(leftp1) )
878a472b3eSmickey 	    {
888a472b3eSmickey 	    Set_status_cbit(Lessthan(cond));
898a472b3eSmickey 	    }
908a472b3eSmickey 	else
918a472b3eSmickey 	    {
928a472b3eSmickey 	    Set_status_cbit(Greaterthan(cond));
938a472b3eSmickey 	    }
948a472b3eSmickey 	}
958a472b3eSmickey     /* Signs are the same.  Treat negative numbers separately
968a472b3eSmickey      * from the positives because of the reversed sense.  */
978a472b3eSmickey     else if(Dbl_isequal(leftp1,leftp2,rightp1,rightp2))
988a472b3eSmickey 	{
998a472b3eSmickey 	Set_status_cbit(Equal(cond));
1008a472b3eSmickey 	}
1018a472b3eSmickey     else if( Dbl_iszero_sign(leftp1) )
1028a472b3eSmickey 	{
1038a472b3eSmickey 	/* Positive compare */
1048a472b3eSmickey 	if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) )
1058a472b3eSmickey 	    {
1068a472b3eSmickey 	    Set_status_cbit(Lessthan(cond));
1078a472b3eSmickey 	    }
1088a472b3eSmickey 	else if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) )
1098a472b3eSmickey 	    {
1108a472b3eSmickey 	    Set_status_cbit(Greaterthan(cond));
1118a472b3eSmickey 	    }
1128a472b3eSmickey 	else
1138a472b3eSmickey 	    {
1148a472b3eSmickey 	    /* Equal first parts.  Now we must use unsigned compares to
1158a472b3eSmickey 	     * resolve the two possibilities. */
1168a472b3eSmickey 	    if( Dbl_allp2(leftp2) < Dbl_allp2(rightp2) )
1178a472b3eSmickey 		{
1188a472b3eSmickey 		Set_status_cbit(Lessthan(cond));
1198a472b3eSmickey 		}
1208a472b3eSmickey 	    else
1218a472b3eSmickey 		{
1228a472b3eSmickey 		Set_status_cbit(Greaterthan(cond));
1238a472b3eSmickey 		}
1248a472b3eSmickey 	    }
1258a472b3eSmickey 	}
1268a472b3eSmickey     else
1278a472b3eSmickey 	{
1288a472b3eSmickey 	/* Negative compare.  Signed or unsigned compares
1298a472b3eSmickey 	 * both work the same.  That distinction is only
1308a472b3eSmickey 	 * important when the sign bits differ. */
1318a472b3eSmickey 	if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) )
1328a472b3eSmickey 	    {
1338a472b3eSmickey 	    Set_status_cbit(Lessthan(cond));
1348a472b3eSmickey 	    }
1358a472b3eSmickey 	else if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) )
1368a472b3eSmickey 	    {
1378a472b3eSmickey 	    Set_status_cbit(Greaterthan(cond));
1388a472b3eSmickey 	    }
1398a472b3eSmickey 	else
1408a472b3eSmickey 	    {
1418a472b3eSmickey 	    /* Equal first parts.  Now we must use unsigned compares to
1428a472b3eSmickey 	     * resolve the two possibilities. */
1438a472b3eSmickey 	    if( Dbl_allp2(leftp2) > Dbl_allp2(rightp2) )
1448a472b3eSmickey 		{
1458a472b3eSmickey 		Set_status_cbit(Lessthan(cond));
1468a472b3eSmickey 		}
1478a472b3eSmickey 	    else
1488a472b3eSmickey 		{
1498a472b3eSmickey 		Set_status_cbit(Greaterthan(cond));
1508a472b3eSmickey 		}
1518a472b3eSmickey 	    }
1528a472b3eSmickey 	}
1538a472b3eSmickey 	return(NOEXCEPTION);
1548a472b3eSmickey }
155