xref: /openbsd/sys/arch/hppa/spmath/sfcmp.c (revision 449b444a)
1*449b444aSmickey /*	$OpenBSD: sfcmp.c,v 1.6 2002/09/20 19:26:59 mickey Exp $	*/
2c2feb252Smickey /*
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.
14c2feb252Smickey */
15c2feb252Smickey /* @(#)sfcmp.c: Revision: 1.7.88.2 Date: 93/12/08 13:28:43 */
16b94afd46Smickey 
17c2feb252Smickey #include "float.h"
18c2feb252Smickey #include "sgl_float.h"
198a472b3eSmickey 
208a472b3eSmickey /*
218a472b3eSmickey  * sgl_cmp: compare two values
228a472b3eSmickey  */
23b94afd46Smickey int
sgl_fcmp(leftptr,rightptr,cond,status)248a472b3eSmickey sgl_fcmp(leftptr, rightptr, cond, status)
258a472b3eSmickey     sgl_floating_point *leftptr, *rightptr;
268a472b3eSmickey     unsigned int cond; /* The predicate to be tested */
278a472b3eSmickey     unsigned int *status;
288a472b3eSmickey {
298a472b3eSmickey     register unsigned int left, right;
308a472b3eSmickey     register int xorresult;
318a472b3eSmickey 
328a472b3eSmickey     /* Create local copies of the numbers */
338a472b3eSmickey     left = *leftptr;
348a472b3eSmickey     right = *rightptr;
358a472b3eSmickey     /*
368a472b3eSmickey      * Test for NaN
378a472b3eSmickey      */
388a472b3eSmickey     if(    (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
398a472b3eSmickey 	|| (Sgl_exponent(right) == SGL_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( (  (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
458a472b3eSmickey 	    && Sgl_isnotzero_mantissa(left)
468a472b3eSmickey 	    && (Exception(cond) || Sgl_isone_signaling(left)))
478a472b3eSmickey 	   ||
488a472b3eSmickey 	    (  (Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
498a472b3eSmickey 	    && Sgl_isnotzero_mantissa(right)
508a472b3eSmickey 	    && (Exception(cond) || Sgl_isone_signaling(right)) ) )
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( ((Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
638a472b3eSmickey 	    && Sgl_isnotzero_mantissa(left))
648a472b3eSmickey 	   ||
658a472b3eSmickey 	    ((Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
668a472b3eSmickey 	    && Sgl_isnotzero_mantissa(right)) )
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     Sgl_xortointp1(left,right,xorresult);
778a472b3eSmickey     if( xorresult < 0 )
788a472b3eSmickey 	{
798a472b3eSmickey 	/* left negative => less, left positive => greater.
808a472b3eSmickey 	 * equal is possible if both operands are zeros. */
818a472b3eSmickey 	if( Sgl_iszero_exponentmantissa(left)
828a472b3eSmickey 	  && Sgl_iszero_exponentmantissa(right) )
838a472b3eSmickey 	    {
848a472b3eSmickey 	    Set_status_cbit(Equal(cond));
858a472b3eSmickey 	    }
868a472b3eSmickey 	else if( Sgl_isone_sign(left) )
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( Sgl_all(left) == Sgl_all(right) )
988a472b3eSmickey 	{
998a472b3eSmickey 	Set_status_cbit(Equal(cond));
1008a472b3eSmickey 	}
1018a472b3eSmickey     else if( Sgl_iszero_sign(left) )
1028a472b3eSmickey 	{
1038a472b3eSmickey 	/* Positive compare */
1048a472b3eSmickey 	if( Sgl_all(left) < Sgl_all(right) )
1058a472b3eSmickey 	    {
1068a472b3eSmickey 	    Set_status_cbit(Lessthan(cond));
1078a472b3eSmickey 	    }
1088a472b3eSmickey 	else
1098a472b3eSmickey 	    {
1108a472b3eSmickey 	    Set_status_cbit(Greaterthan(cond));
1118a472b3eSmickey 	    }
1128a472b3eSmickey 	}
1138a472b3eSmickey     else
1148a472b3eSmickey 	{
1158a472b3eSmickey 	/* Negative compare.  Signed or unsigned compares
1168a472b3eSmickey 	 * both work the same.  That distinction is only
1178a472b3eSmickey 	 * important when the sign bits differ. */
1188a472b3eSmickey 	if( Sgl_all(left) > Sgl_all(right) )
1198a472b3eSmickey 	    {
1208a472b3eSmickey 	    Set_status_cbit(Lessthan(cond));
1218a472b3eSmickey 	    }
1228a472b3eSmickey 	else
1238a472b3eSmickey 	    {
1248a472b3eSmickey 	    Set_status_cbit(Greaterthan(cond));
1258a472b3eSmickey 	    }
1268a472b3eSmickey 	}
1278a472b3eSmickey 	return(NOEXCEPTION);
1288a472b3eSmickey }
129