Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/math-emu/dp_fmax.c
26442 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* IEEE754 floating point arithmetic
4
* double precision: MIN{,A}.f
5
* MIN : Scalar Floating-Point Minimum
6
* MINA: Scalar Floating-Point argument with Minimum Absolute Value
7
*
8
* MIN.D : FPR[fd] = minNum(FPR[fs],FPR[ft])
9
* MINA.D: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
10
*
11
* MIPS floating point support
12
* Copyright (C) 2015 Imagination Technologies, Ltd.
13
* Author: Markos Chandras <[email protected]>
14
*/
15
16
#include "ieee754dp.h"
17
18
union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y)
19
{
20
COMPXDP;
21
COMPYDP;
22
23
EXPLODEXDP;
24
EXPLODEYDP;
25
26
FLUSHXDP;
27
FLUSHYDP;
28
29
ieee754_clearcx();
30
31
switch (CLPAIR(xc, yc)) {
32
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
33
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
34
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
35
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
36
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
37
return ieee754dp_nanxcpt(y);
38
39
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
40
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
41
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
42
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
43
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
44
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
45
return ieee754dp_nanxcpt(x);
46
47
/*
48
* Quiet NaN handling
49
*/
50
51
/*
52
* The case of both inputs quiet NaNs
53
*/
54
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
55
return x;
56
57
/*
58
* The cases of exactly one input quiet NaN (numbers
59
* are here preferred as returned values to NaNs)
60
*/
61
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
62
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
63
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
64
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
65
return x;
66
67
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
68
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
69
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
70
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
71
return y;
72
73
/*
74
* Infinity and zero handling
75
*/
76
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
77
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
78
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
79
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
80
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
81
return xs ? y : x;
82
83
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
84
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
85
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
86
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
87
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
88
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
89
return ys ? x : y;
90
91
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
92
return ieee754dp_zero(xs & ys);
93
94
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
95
DPDNORMX;
96
fallthrough;
97
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
98
DPDNORMY;
99
break;
100
101
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
102
DPDNORMX;
103
}
104
105
/* Finally get to do some computation */
106
107
assert(xm & DP_HIDDEN_BIT);
108
assert(ym & DP_HIDDEN_BIT);
109
110
/* Compare signs */
111
if (xs > ys)
112
return y;
113
else if (xs < ys)
114
return x;
115
116
/* Signs of inputs are equal, let's compare exponents */
117
if (xs == 0) {
118
/* Inputs are both positive */
119
if (xe > ye)
120
return x;
121
else if (xe < ye)
122
return y;
123
} else {
124
/* Inputs are both negative */
125
if (xe > ye)
126
return y;
127
else if (xe < ye)
128
return x;
129
}
130
131
/* Signs and exponents of inputs are equal, let's compare mantissas */
132
if (xs == 0) {
133
/* Inputs are both positive, with equal signs and exponents */
134
if (xm <= ym)
135
return y;
136
return x;
137
}
138
/* Inputs are both negative, with equal signs and exponents */
139
if (xm <= ym)
140
return x;
141
return y;
142
}
143
144
union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
145
{
146
COMPXDP;
147
COMPYDP;
148
149
EXPLODEXDP;
150
EXPLODEYDP;
151
152
FLUSHXDP;
153
FLUSHYDP;
154
155
ieee754_clearcx();
156
157
switch (CLPAIR(xc, yc)) {
158
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
159
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
160
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
161
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
162
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
163
return ieee754dp_nanxcpt(y);
164
165
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
166
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
167
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
168
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
169
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
170
case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
171
return ieee754dp_nanxcpt(x);
172
173
/*
174
* Quiet NaN handling
175
*/
176
177
/*
178
* The case of both inputs quiet NaNs
179
*/
180
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
181
return x;
182
183
/*
184
* The cases of exactly one input quiet NaN (numbers
185
* are here preferred as returned values to NaNs)
186
*/
187
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
188
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
189
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
190
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
191
return x;
192
193
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
194
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
195
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
196
case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
197
return y;
198
199
/*
200
* Infinity and zero handling
201
*/
202
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
203
return ieee754dp_inf(xs & ys);
204
205
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
206
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
207
case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
208
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
209
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
210
return x;
211
212
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
213
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
214
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
215
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
216
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
217
return y;
218
219
case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
220
return ieee754dp_zero(xs & ys);
221
222
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
223
DPDNORMX;
224
fallthrough;
225
case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
226
DPDNORMY;
227
break;
228
229
case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
230
DPDNORMX;
231
}
232
233
/* Finally get to do some computation */
234
235
assert(xm & DP_HIDDEN_BIT);
236
assert(ym & DP_HIDDEN_BIT);
237
238
/* Compare exponent */
239
if (xe > ye)
240
return x;
241
else if (xe < ye)
242
return y;
243
244
/* Compare mantissa */
245
if (xm < ym)
246
return y;
247
else if (xm > ym)
248
return x;
249
else if (xs == 0)
250
return x;
251
return y;
252
}
253
254