MIPS: Use fallthrough for arch/mips
[linux-2.6-microblaze.git] / arch / mips / math-emu / dp_fmin.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_fmin(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 ? x : y;
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 ? y : x;
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 x;
113         else if (xs < ys)
114                 return y;
115
116         /* Signs of inputs are the same, let's compare exponents */
117         if (xs == 0) {
118                 /* Inputs are both positive */
119                 if (xe > ye)
120                         return y;
121                 else if (xe < ye)
122                         return x;
123         } else {
124                 /* Inputs are both negative */
125                 if (xe > ye)
126                         return x;
127                 else if (xe < ye)
128                         return y;
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 x;
136                 return y;
137         }
138         /* Inputs are both negative, with equal signs and exponents */
139         if (xm <= ym)
140                 return y;
141         return x;
142 }
143
144 union ieee754dp ieee754dp_fmina(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 y;
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 x;
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 y;
241         else if (xe < ye)
242                 return x;
243
244         /* Compare mantissa */
245         if (xm < ym)
246                 return x;
247         else if (xm > ym)
248                 return y;
249         else if (xs == 1)
250                 return x;
251         return y;
252 }