xref: /openbsd/sys/arch/hppa/spmath/dfcmp.c (revision 404b540a)
1 /*	$OpenBSD: dfcmp.c,v 1.6 2002/09/20 19:26:59 mickey Exp $	*/
2 /*
3   (c) Copyright 1986 HEWLETT-PACKARD COMPANY
4   To anyone who acknowledges that this file is provided "AS IS"
5   without any express or implied warranty:
6       permission to use, copy, modify, and distribute this file
7   for any purpose is hereby granted without fee, provided that
8   the above copyright notice and this notice appears in all
9   copies, and that the name of Hewlett-Packard Company not be
10   used in advertising or publicity pertaining to distribution
11   of the software without specific, written prior permission.
12   Hewlett-Packard Company makes no representations about the
13   suitability of this software for any purpose.
14 */
15 /* @(#)dfcmp.c: Revision: 1.7.88.2 Date: 93/12/08 13:26:38 */
16 
17 #include "float.h"
18 #include "dbl_float.h"
19 
20 /*
21  * dbl_cmp: compare two values
22  */
23 int
24 dbl_fcmp(leftptr, rightptr, cond, status)
25     dbl_floating_point *leftptr, *rightptr;
26     unsigned int cond; /* The predicate to be tested */
27     unsigned int *status;
28 {
29     register unsigned int leftp1, leftp2, rightp1, rightp2;
30     register int xorresult;
31 
32     /* Create local copies of the numbers */
33     Dbl_copyfromptr(leftptr,leftp1,leftp2);
34     Dbl_copyfromptr(rightptr,rightp1,rightp2);
35     /*
36      * Test for NaN
37      */
38     if(    (Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
39 	|| (Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT) )
40 	{
41 	/* Check if a NaN is involved.  Signal an invalid exception when
42 	 * comparing a signaling NaN or when comparing quiet NaNs and the
43 	 * low bit of the condition is set */
44 	if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
45 	    && Dbl_isnotzero_mantissa(leftp1,leftp2)
46 	    && (Exception(cond) || Dbl_isone_signaling(leftp1)))
47 	   ||
48 	    ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT)
49 	    && Dbl_isnotzero_mantissa(rightp1,rightp2)
50 	    && (Exception(cond) || Dbl_isone_signaling(rightp1))) )
51 	    {
52 	    if( Is_invalidtrap_enabled() ) {
53 		Set_status_cbit(Unordered(cond));
54 		return(INVALIDEXCEPTION);
55 	    }
56 	    else Set_invalidflag();
57 	    Set_status_cbit(Unordered(cond));
58 	    return(NOEXCEPTION);
59 	    }
60 	/* All the exceptional conditions are handled, now special case
61 	   NaN compares */
62 	else if( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT)
63 	    && Dbl_isnotzero_mantissa(leftp1,leftp2))
64 	   ||
65 	    ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT)
66 	    && Dbl_isnotzero_mantissa(rightp1,rightp2)) )
67 	    {
68 	    /* NaNs always compare unordered. */
69 	    Set_status_cbit(Unordered(cond));
70 	    return(NOEXCEPTION);
71 	    }
72 	/* infinities will drop down to the normal compare mechanisms */
73 	}
74     /* First compare for unequal signs => less or greater or
75      * special equal case */
76     Dbl_xortointp1(leftp1,rightp1,xorresult);
77     if( xorresult < 0 )
78 	{
79 	/* left negative => less, left positive => greater.
80 	 * equal is possible if both operands are zeros. */
81 	if( Dbl_iszero_exponentmantissa(leftp1,leftp2)
82 	  && Dbl_iszero_exponentmantissa(rightp1,rightp2) )
83 	    {
84 	    Set_status_cbit(Equal(cond));
85 	    }
86 	else if( Dbl_isone_sign(leftp1) )
87 	    {
88 	    Set_status_cbit(Lessthan(cond));
89 	    }
90 	else
91 	    {
92 	    Set_status_cbit(Greaterthan(cond));
93 	    }
94 	}
95     /* Signs are the same.  Treat negative numbers separately
96      * from the positives because of the reversed sense.  */
97     else if(Dbl_isequal(leftp1,leftp2,rightp1,rightp2))
98 	{
99 	Set_status_cbit(Equal(cond));
100 	}
101     else if( Dbl_iszero_sign(leftp1) )
102 	{
103 	/* Positive compare */
104 	if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) )
105 	    {
106 	    Set_status_cbit(Lessthan(cond));
107 	    }
108 	else if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) )
109 	    {
110 	    Set_status_cbit(Greaterthan(cond));
111 	    }
112 	else
113 	    {
114 	    /* Equal first parts.  Now we must use unsigned compares to
115 	     * resolve the two possibilities. */
116 	    if( Dbl_allp2(leftp2) < Dbl_allp2(rightp2) )
117 		{
118 		Set_status_cbit(Lessthan(cond));
119 		}
120 	    else
121 		{
122 		Set_status_cbit(Greaterthan(cond));
123 		}
124 	    }
125 	}
126     else
127 	{
128 	/* Negative compare.  Signed or unsigned compares
129 	 * both work the same.  That distinction is only
130 	 * important when the sign bits differ. */
131 	if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) )
132 	    {
133 	    Set_status_cbit(Lessthan(cond));
134 	    }
135 	else if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) )
136 	    {
137 	    Set_status_cbit(Greaterthan(cond));
138 	    }
139 	else
140 	    {
141 	    /* Equal first parts.  Now we must use unsigned compares to
142 	     * resolve the two possibilities. */
143 	    if( Dbl_allp2(leftp2) > Dbl_allp2(rightp2) )
144 		{
145 		Set_status_cbit(Lessthan(cond));
146 		}
147 	    else
148 		{
149 		Set_status_cbit(Greaterthan(cond));
150 		}
151 	    }
152 	}
153 	return(NOEXCEPTION);
154 }
155