Linux-libre 5.7.3-gnu
[librecmc/linux-libre.git] / arch / mips / math-emu / dp_fmax.c
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 <markos.chandras@imgtec.com>
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                 /* fall through */
97
98         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
99                 DPDNORMY;
100                 break;
101
102         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
103                 DPDNORMX;
104         }
105
106         /* Finally get to do some computation */
107
108         assert(xm & DP_HIDDEN_BIT);
109         assert(ym & DP_HIDDEN_BIT);
110
111         /* Compare signs */
112         if (xs > ys)
113                 return y;
114         else if (xs < ys)
115                 return x;
116
117         /* Signs of inputs are equal, let's compare exponents */
118         if (xs == 0) {
119                 /* Inputs are both positive */
120                 if (xe > ye)
121                         return x;
122                 else if (xe < ye)
123                         return y;
124         } else {
125                 /* Inputs are both negative */
126                 if (xe > ye)
127                         return y;
128                 else if (xe < ye)
129                         return x;
130         }
131
132         /* Signs and exponents of inputs are equal, let's compare mantissas */
133         if (xs == 0) {
134                 /* Inputs are both positive, with equal signs and exponents */
135                 if (xm <= ym)
136                         return y;
137                 return x;
138         }
139         /* Inputs are both negative, with equal signs and exponents */
140         if (xm <= ym)
141                 return x;
142         return y;
143 }
144
145 union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
146 {
147         COMPXDP;
148         COMPYDP;
149
150         EXPLODEXDP;
151         EXPLODEYDP;
152
153         FLUSHXDP;
154         FLUSHYDP;
155
156         ieee754_clearcx();
157
158         switch (CLPAIR(xc, yc)) {
159         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
160         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
161         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
162         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
163         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
164                 return ieee754dp_nanxcpt(y);
165
166         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
167         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
168         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
169         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
170         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
171         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
172                 return ieee754dp_nanxcpt(x);
173
174         /*
175          * Quiet NaN handling
176          */
177
178         /*
179          *    The case of both inputs quiet NaNs
180          */
181         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
182                 return x;
183
184         /*
185          *    The cases of exactly one input quiet NaN (numbers
186          *    are here preferred as returned values to NaNs)
187          */
188         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
189         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
190         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
191         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
192                 return x;
193
194         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
195         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
196         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
197         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
198                 return y;
199
200         /*
201          * Infinity and zero handling
202          */
203         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
204                 return ieee754dp_inf(xs & ys);
205
206         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
207         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
208         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
209         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
210         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
211                 return x;
212
213         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
214         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
215         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
216         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
217         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
218                 return y;
219
220         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
221                 return ieee754dp_zero(xs & ys);
222
223         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
224                 DPDNORMX;
225                 /* fall through */
226
227         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
228                 DPDNORMY;
229                 break;
230
231         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
232                 DPDNORMX;
233         }
234
235         /* Finally get to do some computation */
236
237         assert(xm & DP_HIDDEN_BIT);
238         assert(ym & DP_HIDDEN_BIT);
239
240         /* Compare exponent */
241         if (xe > ye)
242                 return x;
243         else if (xe < ye)
244                 return y;
245
246         /* Compare mantissa */
247         if (xm < ym)
248                 return y;
249         else if (xm > ym)
250                 return x;
251         else if (xs == 0)
252                 return x;
253         return y;
254 }