/*
 * Borrowed from GCC 4.2.2 (which still was GPL v2+)
 */
/* 128-bit long double support routines for Darwin.
   Copyright (C) 1993, 2003, 2004, 2005, 2006, 2007
   Free Software Foundation, Inc.

This file is part of GCC.

 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * Implementations of floating-point long double basic arithmetic
 * functions called by the IBM C compiler when generating code for
 * PowerPC platforms.  In particular, the following functions are
 * implemented: __gcc_qadd, __gcc_qsub, __gcc_qmul, and __gcc_qdiv.
 * Double-double algorithms are based on the paper "Doubled-Precision
 * IEEE Standard 754 Floating-Point Arithmetic" by W. Kahan, February 26,
 * 1987.  An alternative published reference is "Software for
 * Doubled-Precision Floating-Point Computations", by Seppo Linnainmaa,
 * ACM TOMS vol 7 no 3, September 1981, pages 272-283.
 */

/*
 * Each long double is made up of two IEEE doubles.  The value of the
 * long double is the sum of the values of the two parts.  The most
 * significant part is required to be the value of the long double
 * rounded to the nearest double, as specified by IEEE.  For Inf
 * values, the least significant part is required to be one of +0.0 or
 * -0.0.  No other requirements are made; so, for example, 1.0 may be
 * represented as (1.0, +0.0) or (1.0, -0.0), and the low part of a
 * NaN is don't-care.
 *
 * This code currently assumes big-endian.
 */

#define fabs(x) __builtin_fabs(x)
#define isless(x, y) __builtin_isless(x, y)
#define inf() __builtin_inf()
#define unlikely(x) __builtin_expect((x), 0)
#define nonfinite(a) unlikely(!isless(fabs(a), inf()))

typedef union {
	long double ldval;
	double dval[2];
} longDblUnion;

/* Add two 'long double' values and return the result.	*/
long double __gcc_qadd(double a, double aa, double c, double cc)
{
	longDblUnion x;
	double z, q, zz, xh;

	z = a + c;

	if (nonfinite(z)) {
		z = cc + aa + c + a;
		if (nonfinite(z))
			return z;
		x.dval[0] = z;	/* Will always be DBL_MAX.  */
		zz = aa + cc;
		if (fabs(a) > fabs(c))
			x.dval[1] = a - z + c + zz;
		else
			x.dval[1] = c - z + a + zz;
	} else {
		q = a - z;
		zz = q + c + (a - (q + z)) + aa + cc;

		/* Keep -0 result.  */
		if (zz == 0.0)
			return z;

		xh = z + zz;
		if (nonfinite(xh))
			return xh;

		x.dval[0] = xh;
		x.dval[1] = z - xh + zz;
	}
	return x.ldval;
}

long double __gcc_qsub(double a, double b, double c, double d)
{
	return __gcc_qadd(a, b, -c, -d);
}

long double __gcc_qmul(double a, double b, double c, double d)
{
	longDblUnion z;
	double t, tau, u, v, w;

	t = a * c;		/* Highest order double term.  */

	if (unlikely(t == 0)	/* Preserve -0.  */
	    || nonfinite(t))
		return t;

	/* Sum terms of two highest orders. */

	/* Use fused multiply-add to get low part of a * c.  */
#ifndef __NO_FPRS__
	asm("fmsub %0,%1,%2,%3" : "=f"(tau) : "f"(a), "f"(c), "f"(t));
#else
	tau = fmsub(a, c, t);
#endif
	v = a * d;
	w = b * c;
	tau += v + w;		/* Add in other second-order terms.  */
	u = t + tau;

	/* Construct long double result.  */
	if (nonfinite(u))
		return u;
	z.dval[0] = u;
	z.dval[1] = (t - u) + tau;
	return z.ldval;
}
