Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/parisc/math-emu/dfcmp.c
26288 views
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) <[email protected]>
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
170