text: /*
   * IEEE754 floating point arithmetic
   * double precision: MIN{,A}.f
   * MIN : Scalar Floating-Point Minimum
   * MINA: Scalar Floating-Point argument with Minimum Absolute Value
   *
   * MIN.D : FPR[fd] = minNum(FPR[fs],FPR[ft])
   * MINA.D: FPR[fd] = maxNumMag(FPR[fs],FPR[ft])
   *
   * MIPS floating point support
   * Copyright (C) 2015 Imagination Technologies, Ltd.
   * Author: Markos Chandras <markos.chandras@imgtec.com>
   *
   *  This program is free software; you can distribute it and/or modify it
   *  under the terms of the GNU General Public License as published by the
   *  Free Software Foundation; version 2 of the License.
   */
  
  #include "ieee754dp.h"
  
  union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y)
  {
  	COMPXDP;
  	COMPYDP;
  
  	EXPLODEXDP;
  	EXPLODEYDP;
  
  	FLUSHXDP;
  	FLUSHYDP;
  
  	ieee754_clearcx();
  
  	switch (CLPAIR(xc, yc)) {
  	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  		return ieee754dp_nanxcpt(y);
  
  	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  		return ieee754dp_nanxcpt(x);
  
  	/*
  	 * Quiet NaN handling
  	 */
  
  	/*
  	 *    The case of both inputs quiet NaNs
  	 */
  	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  		return x;
  
  	/*
  	 *    The cases of exactly one input quiet NaN (numbers
  	 *    are here preferred as returned values to NaNs)
  	 */
  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  		return x;
  
  	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  		return y;
  
  	/*
  	 * Infinity and zero handling
  	 */
  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  		return xs ? y : x;
  
  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  		return ys ? x : y;
  
  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  		return ieee754dp_zero(xs & ys);
  
  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  		DPDNORMX;
  		/* fall through */
  
  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  		DPDNORMY;
  		break;
  
  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  		DPDNORMX;
  	}
  
  	/* Finally get to do some computation */
  
  	assert(xm & DP_HIDDEN_BIT);
  	assert(ym & DP_HIDDEN_BIT);
  
  	/* Compare signs */
  	if (xs > ys)
  		return y;
  	else if (xs < ys)
  		return x;
  
  	/* Signs of inputs are equal, let's compare exponents */
  	if (xs == 0) {
  		/* Inputs are both positive */
  		if (xe > ye)
  			return x;
  		else if (xe < ye)
  			return y;
  	} else {
  		/* Inputs are both negative */
  		if (xe > ye)
  			return y;
  		else if (xe < ye)
  			return x;
  	}
  
  	/* Signs and exponents of inputs are equal, let's compare mantissas */
  	if (xs == 0) {
  		/* Inputs are both positive, with equal signs and exponents */
  		if (xm <= ym)
  			return y;
  		return x;
  	}
  	/* Inputs are both negative, with equal signs and exponents */
  	if (xm <= ym)
  		return x;
  	return y;
  }
  
  union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y)
  {
  	COMPXDP;
  	COMPYDP;
  
  	EXPLODEXDP;
  	EXPLODEYDP;
  
  	FLUSHXDP;
  	FLUSHYDP;
  
  	ieee754_clearcx();
  
  	switch (CLPAIR(xc, yc)) {
  	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN):
  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN):
  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN):
  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN):
  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN):
  		return ieee754dp_nanxcpt(y);
  
  	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN):
  	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN):
  	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO):
  	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM):
  	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM):
  	case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF):
  		return ieee754dp_nanxcpt(x);
  
  	/*
  	 * Quiet NaN handling
  	 */
  
  	/*
  	 *    The case of both inputs quiet NaNs
  	 */
  	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN):
  		return x;
  
  	/*
  	 *    The cases of exactly one input quiet NaN (numbers
  	 *    are here preferred as returned values to NaNs)
  	 */
  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN):
  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN):
  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN):
  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN):
  		return x;
  
  	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO):
  	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM):
  	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM):
  	case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF):
  		return y;
  
  	/*
  	 * Infinity and zero handling
  	 */
  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF):
  		return ieee754dp_inf(xs & ys);
  
  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO):
  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM):
  	case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM):
  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO):
  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO):
  		return x;
  
  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF):
  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF):
  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF):
  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM):
  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM):
  		return y;
  
  	case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO):
  		return ieee754dp_zero(xs & ys);
  
  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM):
  		DPDNORMX;
  		/* fall through */
  
  	case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM):
  		DPDNORMY;
  		break;
  
  	case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM):
  		DPDNORMX;
  	}
  
  	/* Finally get to do some computation */
  
  	assert(xm & DP_HIDDEN_BIT);
  	assert(ym & DP_HIDDEN_BIT);
  
  	/* Compare exponent */
  	if (xe > ye)
  		return x;
  	else if (xe < ye)
  		return y;
  
  	/* Compare mantissa */
  	if (xm < ym)
  		return y;
  	else if (xm > ym)
  		return x;
  	else if (xs == 0)
  		return x;
  	return y;
  }
  