Merge tag 'docs-4.16-2' of git://git.lwn.net/linux
[sfrench/cifs-2.6.git] / arch / mips / math-emu / sp_fmax.c
1 /*
2  * IEEE754 floating point arithmetic
3  * single precision: MAX{,A}.f
4  * MAX : Scalar Floating-Point Maximum
5  * MAXA: Scalar Floating-Point argument with Maximum Absolute Value
6  *
7  * MAX.S : FPR[fd] = maxNum(FPR[fs],FPR[ft])
8  * MAXA.S: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
9  *
10  * MIPS floating point support
11  * Copyright (C) 2015 Imagination Technologies, Ltd.
12  * Author: Markos Chandras <markos.chandras@imgtec.com>
13  *
14  *  This program is free software; you can distribute it and/or modify it
15  *  under the terms of the GNU General Public License as published by the
16  *  Free Software Foundation; version 2 of the License.
17  */
18
19 #include "ieee754sp.h"
20
21 union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y)
22 {
23         COMPXSP;
24         COMPYSP;
25
26         EXPLODEXSP;
27         EXPLODEYSP;
28
29         FLUSHXSP;
30         FLUSHYSP;
31
32         ieee754_clearcx();
33
34         switch (CLPAIR(xc, yc)) {
35         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
36         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
37         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
38         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
39         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
40                 return ieee754sp_nanxcpt(y);
41
42         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
43         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
44         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
45         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
46         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
47         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
48                 return ieee754sp_nanxcpt(x);
49
50         /*
51          * Quiet NaN handling
52          */
53
54         /*
55          *    The case of both inputs quiet NaNs
56          */
57         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58                 return x;
59
60         /*
61          *    The cases of exactly one input quiet NaN (numbers
62          *    are here preferred as returned values to NaNs)
63          */
64         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
65         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
66         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
67         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
68                 return x;
69
70         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
71         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
72         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
73         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
74                 return y;
75
76         /*
77          * Infinity and zero handling
78          */
79         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
80         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
81         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
82         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
83         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
84                 return xs ? y : x;
85
86         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
87         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
88         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
89         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
90         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
91         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
92                 return ys ? x : y;
93
94         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
95                 return ieee754sp_zero(xs & ys);
96
97         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
98                 SPDNORMX;
99
100         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
101                 SPDNORMY;
102                 break;
103
104         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
105                 SPDNORMX;
106         }
107
108         /* Finally get to do some computation */
109
110         assert(xm & SP_HIDDEN_BIT);
111         assert(ym & SP_HIDDEN_BIT);
112
113         /* Compare signs */
114         if (xs > ys)
115                 return y;
116         else if (xs < ys)
117                 return x;
118
119         /* Signs of inputs are equal, let's compare exponents */
120         if (xs == 0) {
121                 /* Inputs are both positive */
122                 if (xe > ye)
123                         return x;
124                 else if (xe < ye)
125                         return y;
126         } else {
127                 /* Inputs are both negative */
128                 if (xe > ye)
129                         return y;
130                 else if (xe < ye)
131                         return x;
132         }
133
134         /* Signs and exponents of inputs are equal, let's compare mantissas */
135         if (xs == 0) {
136                 /* Inputs are both positive, with equal signs and exponents */
137                 if (xm <= ym)
138                         return y;
139                 return x;
140         }
141         /* Inputs are both negative, with equal signs and exponents */
142         if (xm <= ym)
143                 return x;
144         return y;
145 }
146
147 union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
148 {
149         COMPXSP;
150         COMPYSP;
151
152         EXPLODEXSP;
153         EXPLODEYSP;
154
155         FLUSHXSP;
156         FLUSHYSP;
157
158         ieee754_clearcx();
159
160         switch (CLPAIR(xc, yc)) {
161         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
162         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
163         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
164         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
165         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
166                 return ieee754sp_nanxcpt(y);
167
168         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
169         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
170         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
171         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
172         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
173         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
174                 return ieee754sp_nanxcpt(x);
175
176         /*
177          * Quiet NaN handling
178          */
179
180         /*
181          *    The case of both inputs quiet NaNs
182          */
183         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
184                 return x;
185
186         /*
187          *    The cases of exactly one input quiet NaN (numbers
188          *    are here preferred as returned values to NaNs)
189          */
190         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
191         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
192         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
193         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
194                 return x;
195
196         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
197         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
198         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
199         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
200                 return y;
201
202         /*
203          * Infinity and zero handling
204          */
205         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
206                 return ieee754sp_inf(xs & ys);
207
208         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
209         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
210         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
211         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
212         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
213                 return x;
214
215         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
216         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
217         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
218         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
219         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
220                 return y;
221
222         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
223                 return ieee754sp_zero(xs & ys);
224
225         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
226                 SPDNORMX;
227
228         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
229                 SPDNORMY;
230                 break;
231
232         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
233                 SPDNORMX;
234         }
235
236         /* Finally get to do some computation */
237
238         assert(xm & SP_HIDDEN_BIT);
239         assert(ym & SP_HIDDEN_BIT);
240
241         /* Compare exponent */
242         if (xe > ye)
243                 return x;
244         else if (xe < ye)
245                 return y;
246
247         /* Compare mantissa */
248         if (xm < ym)
249                 return y;
250         else if (xm > ym)
251                 return x;
252         else if (xs == 0)
253                 return x;
254         return y;
255 }