Loading...
1/*
2 * IEEE754 floating point arithmetic
3 * double precision: MIN{,A}.f
4 * MIN : Scalar Floating-Point Minimum
5 * MINA: Scalar Floating-Point argument with Minimum Absolute Value
6 *
7 * MIN.D : FPR[fd] = minNum(FPR[fs],FPR[ft])
8 * MINA.D: 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 "ieee754dp.h"
20
21union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y)
22{
23 COMPXDP;
24 COMPYDP;
25
26 EXPLODEXDP;
27 EXPLODEYDP;
28
29 FLUSHXDP;
30 FLUSHYDP;
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 ieee754dp_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 ieee754dp_nanxcpt(x);
49
50 /* numbers are preferred to NaNs */
51 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
52 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
53 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
54 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
55 return x;
56
57 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
58 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
59 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
60 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
61 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
62 return y;
63
64 /*
65 * Infinity and zero handling
66 */
67 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
68 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
69 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
70 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
71 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
72 return xs ? x : y;
73
74 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
75 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
76 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
77 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
78 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
79 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
80 return ys ? y : x;
81
82 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
83 if (xs == ys)
84 return x;
85 return ieee754dp_zero(1);
86
87 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
88 DPDNORMX;
89
90 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
91 DPDNORMY;
92 break;
93
94 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
95 DPDNORMX;
96 }
97
98 /* Finally get to do some computation */
99
100 assert(xm & DP_HIDDEN_BIT);
101 assert(ym & DP_HIDDEN_BIT);
102
103 /* Compare signs */
104 if (xs > ys)
105 return x;
106 else if (xs < ys)
107 return y;
108
109 /* Compare exponent */
110 if (xe > ye)
111 return y;
112 else if (xe < ye)
113 return x;
114
115 /* Compare mantissa */
116 if (xm <= ym)
117 return x;
118 return y;
119}
120
121union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y)
122{
123 COMPXDP;
124 COMPYDP;
125
126 EXPLODEXDP;
127 EXPLODEYDP;
128
129 FLUSHXDP;
130 FLUSHYDP;
131
132 ieee754_clearcx();
133
134 switch (CLPAIR(xc, yc)) {
135 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
136 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
137 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
138 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
139 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
140 return ieee754dp_nanxcpt(y);
141
142 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
143 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
144 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
145 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
146 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
147 case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
148 return ieee754dp_nanxcpt(x);
149
150 /* numbers are preferred to NaNs */
151 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
152 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
153 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
154 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
155 return x;
156
157 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
158 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
159 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
160 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
161 case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
162 return y;
163
164 /*
165 * Infinity and zero handling
166 */
167 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
168 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
169 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
170 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
171 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
172 return x;
173
174 case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
175 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
176 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
177 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
178 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
179 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
180 return y;
181
182 case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
183 if (xs == ys)
184 return x;
185 return ieee754dp_zero(1);
186
187 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
188 DPDNORMX;
189
190 case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
191 DPDNORMY;
192 break;
193
194 case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
195 DPDNORMX;
196 }
197
198 /* Finally get to do some computation */
199
200 assert(xm & DP_HIDDEN_BIT);
201 assert(ym & DP_HIDDEN_BIT);
202
203 /* Compare exponent */
204 if (xe > ye)
205 return y;
206 else if (xe < ye)
207 return x;
208
209 /* Compare mantissa */
210 if (xm <= ym)
211 return x;
212 return y;
213}
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
18union 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
144union 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}