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