Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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_fmax(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 ? y : x;
 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 ? x : y;
 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		/* fall through */
 97
 98	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
 99		DPDNORMY;
100		break;
101
102	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
103		DPDNORMX;
104	}
105
106	/* Finally get to do some computation */
107
108	assert(xm & DP_HIDDEN_BIT);
109	assert(ym & DP_HIDDEN_BIT);
110
111	/* Compare signs */
112	if (xs > ys)
113		return y;
114	else if (xs < ys)
115		return x;
116
117	/* Signs of inputs are equal, let's compare exponents */
118	if (xs == 0) {
119		/* Inputs are both positive */
120		if (xe > ye)
121			return x;
122		else if (xe < ye)
123			return y;
124	} else {
125		/* Inputs are both negative */
126		if (xe > ye)
127			return y;
128		else if (xe < ye)
129			return x;
130	}
131
132	/* Signs and exponents of inputs are equal, let's compare mantissas */
133	if (xs == 0) {
134		/* Inputs are both positive, with equal signs and exponents */
135		if (xm <= ym)
136			return y;
137		return x;
138	}
139	/* Inputs are both negative, with equal signs and exponents */
140	if (xm <= ym)
141		return x;
142	return y;
143}
144
145union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
146{
147	COMPXDP;
148	COMPYDP;
149
150	EXPLODEXDP;
151	EXPLODEYDP;
152
153	FLUSHXDP;
154	FLUSHYDP;
155
156	ieee754_clearcx();
157
158	switch (CLPAIR(xc, yc)) {
159	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
160	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
161	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
162	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
163	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
164		return ieee754dp_nanxcpt(y);
165
166	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
167	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
168	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
169	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
170	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
171	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
172		return ieee754dp_nanxcpt(x);
173
174	/*
175	 * Quiet NaN handling
176	 */
177
178	/*
179	 *    The case of both inputs quiet NaNs
180	 */
181	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
182		return x;
183
184	/*
185	 *    The cases of exactly one input quiet NaN (numbers
186	 *    are here preferred as returned values to NaNs)
187	 */
188	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
189	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
190	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
191	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
192		return x;
193
194	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
195	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
196	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
197	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
198		return y;
199
200	/*
201	 * Infinity and zero handling
202	 */
203	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
204		return ieee754dp_inf(xs & ys);
205
206	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
207	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
208	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
209	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
210	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
211		return x;
212
213	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
214	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
215	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
216	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
217	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
218		return y;
219
220	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
221		return ieee754dp_zero(xs & ys);
222
223	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
224		DPDNORMX;
225		/* fall through */
226
227	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
228		DPDNORMY;
229		break;
230
231	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
232		DPDNORMX;
233	}
234
235	/* Finally get to do some computation */
236
237	assert(xm & DP_HIDDEN_BIT);
238	assert(ym & DP_HIDDEN_BIT);
239
240	/* Compare exponent */
241	if (xe > ye)
242		return x;
243	else if (xe < ye)
244		return y;
245
246	/* Compare mantissa */
247	if (xm < ym)
248		return y;
249	else if (xm > ym)
250		return x;
251	else if (xs == 0)
252		return x;
253	return y;
254}