Merge drm/drm-next into drm-misc-next
[linux-2.6-microblaze.git] / arch / parisc / math-emu / sfcmp.c
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  */
35 int
36 sgl_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     }