GNU Linux-libre 4.19.286-gnu1
[releases.git] / arch / mips / math-emu / sp_fmin.c
1 /*
2  * IEEE754 floating point arithmetic
3  * single precision: MIN{,A}.f
4  * MIN : Scalar Floating-Point Minimum
5  * MINA: Scalar Floating-Point argument with Minimum Absolute Value
6  *
7  * MIN.S : FPR[fd] = minNum(FPR[fs],FPR[ft])
8  * MINA.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_fmin(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 ? x : y;
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 ? y : x;
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                 /* fall through */
100
101         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
102                 SPDNORMY;
103                 break;
104
105         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
106                 SPDNORMX;
107         }
108
109         /* Finally get to do some computation */
110
111         assert(xm & SP_HIDDEN_BIT);
112         assert(ym & SP_HIDDEN_BIT);
113
114         /* Compare signs */
115         if (xs > ys)
116                 return x;
117         else if (xs < ys)
118                 return y;
119
120         /* Signs of inputs are the same, let's compare exponents */
121         if (xs == 0) {
122                 /* Inputs are both positive */
123                 if (xe > ye)
124                         return y;
125                 else if (xe < ye)
126                         return x;
127         } else {
128                 /* Inputs are both negative */
129                 if (xe > ye)
130                         return x;
131                 else if (xe < ye)
132                         return y;
133         }
134
135         /* Signs and exponents of inputs are equal, let's compare mantissas */
136         if (xs == 0) {
137                 /* Inputs are both positive, with equal signs and exponents */
138                 if (xm <= ym)
139                         return x;
140                 return y;
141         }
142         /* Inputs are both negative, with equal signs and exponents */
143         if (xm <= ym)
144                 return y;
145         return x;
146 }
147
148 union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y)
149 {
150         COMPXSP;
151         COMPYSP;
152
153         EXPLODEXSP;
154         EXPLODEYSP;
155
156         FLUSHXSP;
157         FLUSHYSP;
158
159         ieee754_clearcx();
160
161         switch (CLPAIR(xc, yc)) {
162         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
163         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
164         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
165         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
166         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
167                 return ieee754sp_nanxcpt(y);
168
169         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
170         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
171         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
172         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
173         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
174         case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
175                 return ieee754sp_nanxcpt(x);
176
177         /*
178          * Quiet NaN handling
179          */
180
181         /*
182          *    The case of both inputs quiet NaNs
183          */
184         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
185                 return x;
186
187         /*
188          *    The cases of exactly one input quiet NaN (numbers
189          *    are here preferred as returned values to NaNs)
190          */
191         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
192         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
193         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
194         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
195                 return x;
196
197         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
198         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
199         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
200         case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
201                 return y;
202
203         /*
204          * Infinity and zero handling
205          */
206         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
207                 return ieee754sp_inf(xs | ys);
208
209         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
210         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
211         case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
212         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
213         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
214                 return y;
215
216         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
217         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
218         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
219         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
220         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
221                 return x;
222
223         case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
224                 return ieee754sp_zero(xs | ys);
225
226         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
227                 SPDNORMX;
228                 /* fall through */
229
230         case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
231                 SPDNORMY;
232                 break;
233
234         case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
235                 SPDNORMX;
236         }
237
238         /* Finally get to do some computation */
239
240         assert(xm & SP_HIDDEN_BIT);
241         assert(ym & SP_HIDDEN_BIT);
242
243         /* Compare exponent */
244         if (xe > ye)
245                 return y;
246         else if (xe < ye)
247                 return x;
248
249         /* Compare mantissa */
250         if (xm < ym)
251                 return x;
252         else if (xm > ym)
253                 return y;
254         else if (xs == 1)
255                 return x;
256         return y;
257 }