xref: /linux/arch/mips/math-emu/sp_fmax.c (revision 56d06fa29edd58c448766014afd833b7ff51247b)
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 	/* 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 ieee754sp_zero(1);
86 
87 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
88 		SPDNORMX;
89 
90 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
91 		SPDNORMY;
92 		break;
93 
94 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
95 		SPDNORMX;
96 	}
97 
98 	/* Finally get to do some computation */
99 
100 	assert(xm & SP_HIDDEN_BIT);
101 	assert(ym & SP_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 ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y)
122 {
123 	COMPXSP;
124 	COMPYSP;
125 
126 	EXPLODEXSP;
127 	EXPLODEYSP;
128 
129 	FLUSHXSP;
130 	FLUSHYSP;
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 ieee754sp_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 ieee754sp_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 ieee754sp_zero(1);
186 
187 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
188 		SPDNORMX;
189 
190 	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
191 		SPDNORMY;
192 		break;
193 
194 	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
195 		SPDNORMX;
196 	}
197 
198 	/* Finally get to do some computation */
199 
200 	assert(xm & SP_HIDDEN_BIT);
201 	assert(ym & SP_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