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/dfcmp.c $Revision: 1.1 $ |
13 | * |
14 | * Purpose: |
15 | * dbl_cmp: compare two values |
16 | * |
17 | * External Interfaces: |
18 | * dbl_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 | |
30 | #include "float.h" |
31 | #include "dbl_float.h" |
32 | |
33 | /* |
34 | * dbl_cmp: compare two values |
35 | */ |
36 | int |
37 | dbl_fcmp (dbl_floating_point * leftptr, dbl_floating_point * rightptr, |
38 | unsigned int cond, unsigned int *status) |
39 | |
40 | /* The predicate to be tested */ |
41 | |
42 | { |
43 | register unsigned int leftp1, leftp2, rightp1, rightp2; |
44 | register int xorresult; |
45 | |
46 | /* Create local copies of the numbers */ |
47 | Dbl_copyfromptr(leftptr,leftp1,leftp2); |
48 | Dbl_copyfromptr(rightptr,rightp1,rightp2); |
49 | /* |
50 | * Test for NaN |
51 | */ |
52 | if( (Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT) |
53 | || (Dbl_exponent(rightp1) == DBL_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( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT) |
59 | && Dbl_isnotzero_mantissa(leftp1,leftp2) |
60 | && (Exception(cond) || Dbl_isone_signaling(leftp1))) |
61 | || |
62 | ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT) |
63 | && Dbl_isnotzero_mantissa(rightp1,rightp2) |
64 | && (Exception(cond) || Dbl_isone_signaling(rightp1))) ) |
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( ((Dbl_exponent(leftp1) == DBL_INFINITY_EXPONENT) |
77 | && Dbl_isnotzero_mantissa(leftp1,leftp2)) |
78 | || |
79 | ((Dbl_exponent(rightp1) == DBL_INFINITY_EXPONENT) |
80 | && Dbl_isnotzero_mantissa(rightp1,rightp2)) ) |
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 | Dbl_xortointp1(leftp1,rightp1,xorresult); |
91 | if( xorresult < 0 ) |
92 | { |
93 | /* left negative => less, left positive => greater. |
94 | * equal is possible if both operands are zeros. */ |
95 | if( Dbl_iszero_exponentmantissa(leftp1,leftp2) |
96 | && Dbl_iszero_exponentmantissa(rightp1,rightp2) ) |
97 | { |
98 | Set_status_cbit(Equal(cond)); |
99 | } |
100 | else if( Dbl_isone_sign(leftp1) ) |
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(Dbl_isequal(leftp1,leftp2,rightp1,rightp2)) |
112 | { |
113 | Set_status_cbit(Equal(cond)); |
114 | } |
115 | else if( Dbl_iszero_sign(leftp1) ) |
116 | { |
117 | /* Positive compare */ |
118 | if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) ) |
119 | { |
120 | Set_status_cbit(Lessthan(cond)); |
121 | } |
122 | else if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) ) |
123 | { |
124 | Set_status_cbit(Greaterthan(cond)); |
125 | } |
126 | else |
127 | { |
128 | /* Equal first parts. Now we must use unsigned compares to |
129 | * resolve the two possibilities. */ |
130 | if( Dbl_allp2(leftp2) < Dbl_allp2(rightp2) ) |
131 | { |
132 | Set_status_cbit(Lessthan(cond)); |
133 | } |
134 | else |
135 | { |
136 | Set_status_cbit(Greaterthan(cond)); |
137 | } |
138 | } |
139 | } |
140 | else |
141 | { |
142 | /* Negative compare. Signed or unsigned compares |
143 | * both work the same. That distinction is only |
144 | * important when the sign bits differ. */ |
145 | if( Dbl_allp1(leftp1) > Dbl_allp1(rightp1) ) |
146 | { |
147 | Set_status_cbit(Lessthan(cond)); |
148 | } |
149 | else if( Dbl_allp1(leftp1) < Dbl_allp1(rightp1) ) |
150 | { |
151 | Set_status_cbit(Greaterthan(cond)); |
152 | } |
153 | else |
154 | { |
155 | /* Equal first parts. Now we must use unsigned compares to |
156 | * resolve the two possibilities. */ |
157 | if( Dbl_allp2(leftp2) > Dbl_allp2(rightp2) ) |
158 | { |
159 | Set_status_cbit(Lessthan(cond)); |
160 | } |
161 | else |
162 | { |
163 | Set_status_cbit(Greaterthan(cond)); |
164 | } |
165 | } |
166 | } |
167 | return(NOEXCEPTION); |
168 | } |
169 | |