1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Linux/PA-RISC Project (http://www.parisc-linux.org/)
4 *
5 * Floating-point emulation code
6 *  Copyright (C) 2001 Hewlett-Packard (Paul Bame) <bame@debian.org>
7 */
8/*
9 * BEGIN_DESC
10 *
11 *  File:
12 *	@(#)	pa/spmath/sfcmp.c		$Revision: 1.1 $
13 *
14 *  Purpose:
15 *	sgl_cmp: compare two values
16 *
17 *  External Interfaces:
18 *	sgl_fcmp(leftptr, rightptr, cond, status)
19 *
20 *  Internal Interfaces:
21 *
22 *  Theory:
23 *	<<please update with a overview of the operation of this file>>
24 *
25 * END_DESC
26*/
27
28
29#include "float.h"
30#include "sgl_float.h"
31
32/*
33 * sgl_cmp: compare two values
34 */
35int
36sgl_fcmp (sgl_floating_point * leftptr, sgl_floating_point * rightptr,
37	  unsigned int cond, unsigned int *status)
38
39                       /* The predicate to be tested */
40
41    {
42    register unsigned int left, right;
43    register int xorresult;
44
45    /* Create local copies of the numbers */
46    left = *leftptr;
47    right = *rightptr;
48
49    /*
50     * Test for NaN
51     */
52    if(    (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
53        || (Sgl_exponent(right) == SGL_INFINITY_EXPONENT) )
54	{
55	/* Check if a NaN is involved.  Signal an invalid exception when
56	 * comparing a signaling NaN or when comparing quiet NaNs and the
57	 * low bit of the condition is set */
58        if( (  (Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
59	    && Sgl_isnotzero_mantissa(left)
60	    && (Exception(cond) || Sgl_isone_signaling(left)))
61	   ||
62	    (  (Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
63	    && Sgl_isnotzero_mantissa(right)
64	    && (Exception(cond) || Sgl_isone_signaling(right)) ) )
65	    {
66	    if( Is_invalidtrap_enabled() ) {
67	    	Set_status_cbit(Unordered(cond));
68		return(INVALIDEXCEPTION);
69	    }
70	    else Set_invalidflag();
71	    Set_status_cbit(Unordered(cond));
72	    return(NOEXCEPTION);
73	    }
74	/* All the exceptional conditions are handled, now special case
75	   NaN compares */
76        else if( ((Sgl_exponent(left) == SGL_INFINITY_EXPONENT)
77	    && Sgl_isnotzero_mantissa(left))
78	   ||
79	    ((Sgl_exponent(right) == SGL_INFINITY_EXPONENT)
80	    && Sgl_isnotzero_mantissa(right)) )
81	    {
82	    /* NaNs always compare unordered. */
83	    Set_status_cbit(Unordered(cond));
84	    return(NOEXCEPTION);
85	    }
86	/* infinities will drop down to the normal compare mechanisms */
87	}
88    /* First compare for unequal signs => less or greater or
89     * special equal case */
90    Sgl_xortointp1(left,right,xorresult);
91    if( xorresult < 0 )
92        {
93        /* left negative => less, left positive => greater.
94         * equal is possible if both operands are zeros. */
95        if( Sgl_iszero_exponentmantissa(left)
96	  && Sgl_iszero_exponentmantissa(right) )
97            {
98	    Set_status_cbit(Equal(cond));
99	    }
100	else if( Sgl_isone_sign(left) )
101	    {
102	    Set_status_cbit(Lessthan(cond));
103	    }
104	else
105	    {
106	    Set_status_cbit(Greaterthan(cond));
107	    }
108        }
109    /* Signs are the same.  Treat negative numbers separately
110     * from the positives because of the reversed sense.  */
111    else if( Sgl_all(left) == Sgl_all(right) )
112        {
113        Set_status_cbit(Equal(cond));
114        }
115    else if( Sgl_iszero_sign(left) )
116        {
117        /* Positive compare */
118        if( Sgl_all(left) < Sgl_all(right) )
119	    {
120	    Set_status_cbit(Lessthan(cond));
121	    }
122	else
123	    {
124	    Set_status_cbit(Greaterthan(cond));
125	    }
126	}
127    else
128        {
129        /* Negative compare.  Signed or unsigned compares
130         * both work the same.  That distinction is only
131         * important when the sign bits differ. */
132        if( Sgl_all(left) > Sgl_all(right) )
133	    {
134	    Set_status_cbit(Lessthan(cond));
135	    }
136        else
137	    {
138	    Set_status_cbit(Greaterthan(cond));
139	    }
140        }
141	return(NOEXCEPTION);
142    }
143