xref: /linux/arch/mips/math-emu/dp_fmax.c (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
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 
21 union ieee754dp ieee754dp_fmax(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 ? y : x;
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 ? x : y;
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 y;
106 	else if (xs < ys)
107 		return x;
108 
109 	/* Compare exponent */
110 	if (xe > ye)
111 		return x;
112 	else if (xe < ye)
113 		return y;
114 
115 	/* Compare mantissa */
116 	if (xm <= ym)
117 		return y;
118 	return x;
119 }
120 
121 union ieee754dp ieee754dp_fmaxa(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 x;
206 	else if (xe < ye)
207 		return y;
208 
209 	/* Compare mantissa */
210 	if (xm <= ym)
211 		return y;
212 	return x;
213 }
214