// SPDX-License-Identifier: GPL-2.0-or-later
/*

   fp_arith.c: floating-point math routines for the Linux-m68k
   floating point emulator.

   Copyright (c) 1998-1999 David Huggins-Daines.

   Somewhat based on the AlphaLinux floating point emulator, by David
   Mosberger-Tang.

 */

#include "fp_emu.h"
#include "multi_arith.h"
#include "fp_arith.h"

const struct fp_ext fp_QNaN =
{
	.exp = 0x7fff,
	.mant = { .m64 = ~0 }
};

const struct fp_ext fp_Inf =
{
	.exp = 0x7fff,
};

/* let's start with the easy ones */

struct fp_ext *fp_fabs(struct fp_ext *dest, struct fp_ext *src)
{
	dprint(PINSTR, "fabs\n");

	fp_monadic_check(dest, src);

	dest->sign = 0;

	return dest;
}

struct fp_ext *fp_fneg(struct fp_ext *dest, struct fp_ext *src)
{
	dprint(PINSTR, "fneg\n");

	fp_monadic_check(dest, src);

	dest->sign = !dest->sign;

	return dest;
}

/* Now, the slightly harder ones */

/* fp_fadd: Implements the kernel of the FADD, FSADD, FDADD, FSUB,
   FDSUB, and FCMP instructions. */

struct fp_ext *fp_fadd(struct fp_ext *dest, struct fp_ext *src)
{
	int diff;

	dprint(PINSTR, "fadd\n");

	fp_dyadic_check(dest, src);

	if (IS_INF(dest)) {
		/* infinity - infinity == NaN */
		if (IS_INF(src) && (src->sign != dest->sign))
			fp_set_nan(dest);
		return dest;
	}
	if (IS_INF(src)) {
		fp_copy_ext(dest, src);
		return dest;
	}

	if (IS_ZERO(dest)) {
		if (IS_ZERO(src)) {
			if (src->sign != dest->sign) {
				if (FPDATA->rnd == FPCR_ROUND_RM)
					dest->sign = 1;
				else
					dest->sign = 0;
			}
		} else
			fp_copy_ext(dest, src);
		return dest;
	}

	dest->lowmant = src->lowmant = 0;

	if ((diff = dest->exp - src->exp) > 0)
		fp_denormalize(src, diff);
	else if ((diff = -diff) > 0)
		fp_denormalize(dest, diff);

	if (dest->sign == src->sign) {
		if (fp_addmant(dest, src))
			if (!fp_addcarry(dest))
				return dest;
	} else {
		if (dest->mant.m64 < src->mant.m64) {
			fp_submant(dest, src, dest);
			dest->sign = !dest->sign;
		} else
			fp_submant(dest, dest, src);
	}

	return dest;
}

/* fp_fsub: Implements the kernel of the FSUB, FSSUB, and FDSUB
   instructions.

   Remember that the arguments are in assembler-syntax order! */

struct fp_ext *fp_fsub(struct fp_ext *dest, struct fp_ext *src)
{
	dprint(PINSTR, "fsub ");

	src->sign = !src->sign;
	return fp_fadd(dest, src);
}


struct fp_ext *fp_fcmp(struct fp_ext *dest, struct fp_ext *src)
{
	dprint(PINSTR, "fcmp ");

	FPDATA->temp[1] = *dest;
	src->sign = !src->sign;
	return fp_fadd(&FPDATA->temp[1], src);
}

struct fp_ext *fp_ftst(struct fp_ext *dest, struct fp_ext *src)
{
	dprint(PINSTR, "ftst\n");

	(void)dest;

	return src;
}

struct fp_ext *fp_fmul(struct fp_ext *dest, struct fp_ext *src)
{
	union fp_mant128 temp;
	int exp;

	dprint(PINSTR, "fmul\n");

	fp_dyadic_check(dest, src);

	/* calculate the correct sign now, as it's necessary for infinities */
	dest->sign = src->sign ^ dest->sign;

	/* Handle infinities */
	if (IS_INF(dest)) {
		if (IS_ZERO(src))
			fp_set_nan(dest);
		return dest;
	}
	if (IS_INF(src)) {
		if (IS_ZERO(dest))
			fp_set_nan(dest);
		else
			fp_copy_ext(dest, src);
		return dest;
	}

	/* Of course, as we all know, zero * anything = zero.  You may
	   not have known that it might be a positive or negative
	   zero... */
	if (IS_ZERO(dest) || IS_ZERO(src)) {
		dest->exp = 0;
		dest->mant.m64 = 0;
		dest->lowmant = 0;

		return dest;
	}

	exp = dest->exp + src->exp - 0x3ffe;

	/* shift up the mantissa for denormalized numbers,
	   so that the highest bit is set, this makes the
	   shift of the result below easier */
	if ((long)dest->mant.m32[0] >= 0)
		exp -= fp_overnormalize(dest);
	if ((long)src->mant.m32[0] >= 0)
		exp -= fp_overnormalize(src);

	/* now, do a 64-bit multiply with expansion */
	fp_multiplymant(&temp, dest, src);

	/* normalize it back to 64 bits and stuff it back into the
	   destination struct */
	if ((long)temp.m32[0] > 0) {
		exp--;
		fp_putmant128(dest, &temp, 1);
	} else
		fp_putmant128(dest, &temp, 0);

	if (exp >= 0x7fff) {
		fp_set_ovrflw(dest);
		return dest;
	}
	dest->exp = exp;
	if (exp < 0) {
		fp_set_sr(FPSR_EXC_UNFL);
		fp_denormalize(dest, -exp);
	}

	return dest;
}

/* fp_fdiv: Implements the "kernel" of the FDIV, FSDIV, FDDIV and
   FSGLDIV instructions.

   Note that the order of the operands is counter-intuitive: instead
   of src / dest, the result is actually dest / src. */

struct fp_ext *fp_fdiv(struct fp_ext *dest, struct fp_ext *src)
{
	union fp_mant128 temp;
	int exp;

	dprint(PINSTR, "fdiv\n");

	fp_dyadic_check(dest, src);

	/* calculate the correct sign now, as it's necessary for infinities */
	dest->sign = src->sign ^ dest->sign;

	/* Handle infinities */
	if (IS_INF(dest)) {
		/* infinity / infinity = NaN (quiet, as always) */
		if (IS_INF(src))
			fp_set_nan(dest);
		/* infinity / anything else = infinity (with appropriate sign) */
		return dest;
	}
	if (IS_INF(src)) {
		/* anything / infinity = zero (with appropriate sign) */
		dest->exp = 0;
		dest->mant.m64 = 0;
		dest->lowmant = 0;

		return dest;
	}

	/* zeroes */
	if (IS_ZERO(dest)) {
		/* zero / zero = NaN */
		if (IS_ZERO(src))
			fp_set_nan(dest);
		/* zero / anything else = zero */
		return dest;
	}
	if (IS_ZERO(src)) {
		/* anything / zero = infinity (with appropriate sign) */
		fp_set_sr(FPSR_EXC_DZ);
		dest->exp = 0x7fff;
		dest->mant.m64 = 0;

		return dest;
	}

	exp = dest->exp - src->exp + 0x3fff;

	/* shift up the mantissa for denormalized numbers,
	   so that the highest bit is set, this makes lots
	   of things below easier */
	if ((long)dest->mant.m32[0] >= 0)
		exp -= fp_overnormalize(dest);
	if ((long)src->mant.m32[0] >= 0)
		exp -= fp_overnormalize(src);

	/* now, do the 64-bit divide */
	fp_dividemant(&temp, dest, src);

	/* normalize it back to 64 bits and stuff it back into the
	   destination struct */
	if (!temp.m32[0]) {
		exp--;
		fp_putmant128(dest, &temp, 32);
	} else
		fp_putmant128(dest, &temp, 31);

	if (exp >= 0x7fff) {
		fp_set_ovrflw(dest);
		return dest;
	}
	dest->exp = exp;
	if (exp < 0) {
		fp_set_sr(FPSR_EXC_UNFL);
		fp_denormalize(dest, -exp);
	}

	return dest;
}

struct fp_ext *fp_fsglmul(struct fp_ext *dest, struct fp_ext *src)
{
	int exp;

	dprint(PINSTR, "fsglmul\n");

	fp_dyadic_check(dest, src);

	/* calculate the correct sign now, as it's necessary for infinities */
	dest->sign = src->sign ^ dest->sign;

	/* Handle infinities */
	if (IS_INF(dest)) {
		if (IS_ZERO(src))
			fp_set_nan(dest);
		return dest;
	}
	if (IS_INF(src)) {
		if (IS_ZERO(dest))
			fp_set_nan(dest);
		else
			fp_copy_ext(dest, src);
		return dest;
	}

	/* Of course, as we all know, zero * anything = zero.  You may
	   not have known that it might be a positive or negative
	   zero... */
	if (IS_ZERO(dest) || IS_ZERO(src)) {
		dest->exp = 0;
		dest->mant.m64 = 0;
		dest->lowmant = 0;

		return dest;
	}

	exp = dest->exp + src->exp - 0x3ffe;

	/* do a 32-bit multiply */
	fp_mul64(dest->mant.m32[0], dest->mant.m32[1],
		 dest->mant.m32[0] & 0xffffff00,
		 src->mant.m32[0] & 0xffffff00);

	if (exp >= 0x7fff) {
		fp_set_ovrflw(dest);
		return dest;
	}
	dest->exp = exp;
	if (exp < 0) {
		fp_set_sr(FPSR_EXC_UNFL);
		fp_denormalize(dest, -exp);
	}

	return dest;
}

struct fp_ext *fp_fsgldiv(struct fp_ext *dest, struct fp_ext *src)
{
	int exp;
	unsigned long quot, rem;

	dprint(PINSTR, "fsgldiv\n");

	fp_dyadic_check(dest, src);

	/* calculate the correct sign now, as it's necessary for infinities */
	dest->sign = src->sign ^ dest->sign;

	/* Handle infinities */
	if (IS_INF(dest)) {
		/* infinity / infinity = NaN (quiet, as always) */
		if (IS_INF(src))
			fp_set_nan(dest);
		/* infinity / anything else = infinity (with approprate sign) */
		return dest;
	}
	if (IS_INF(src)) {
		/* anything / infinity = zero (with appropriate sign) */
		dest->exp = 0;
		dest->mant.m64 = 0;
		dest->lowmant = 0;

		return dest;
	}

	/* zeroes */
	if (IS_ZERO(dest)) {
		/* zero / zero = NaN */
		if (IS_ZERO(src))
			fp_set_nan(dest);
		/* zero / anything else = zero */
		return dest;
	}
	if (IS_ZERO(src)) {
		/* anything / zero = infinity (with appropriate sign) */
		fp_set_sr(FPSR_EXC_DZ);
		dest->exp = 0x7fff;
		dest->mant.m64 = 0;

		return dest;
	}

	exp = dest->exp - src->exp + 0x3fff;

	dest->mant.m32[0] &= 0xffffff00;
	src->mant.m32[0] &= 0xffffff00;

	/* do the 32-bit divide */
	if (dest->mant.m32[0] >= src->mant.m32[0]) {
		fp_sub64(dest->mant, src->mant);
		fp_div64(quot, rem, dest->mant.m32[0], 0, src->mant.m32[0]);
		dest->mant.m32[0] = 0x80000000 | (quot >> 1);
		dest->mant.m32[1] = (quot & 1) | rem;	/* only for rounding */
	} else {
		fp_div64(quot, rem, dest->mant.m32[0], 0, src->mant.m32[0]);
		dest->mant.m32[0] = quot;
		dest->mant.m32[1] = rem;		/* only for rounding */
		exp--;
	}

	if (exp >= 0x7fff) {
		fp_set_ovrflw(dest);
		return dest;
	}
	dest->exp = exp;
	if (exp < 0) {
		fp_set_sr(FPSR_EXC_UNFL);
		fp_denormalize(dest, -exp);
	}

	return dest;
}

/* fp_roundint: Internal rounding function for use by several of these
   emulated instructions.

   This one rounds off the fractional part using the rounding mode
   specified. */

static void fp_roundint(struct fp_ext *dest, int mode)
{
	union fp_mant64 oldmant;
	unsigned long mask;

	if (!fp_normalize_ext(dest))
		return;

	/* infinities and zeroes */
	if (IS_INF(dest) || IS_ZERO(dest))
		return;

	/* first truncate the lower bits */
	oldmant = dest->mant;
	switch (dest->exp) {
	case 0 ... 0x3ffe:
		dest->mant.m64 = 0;
		break;
	case 0x3fff ... 0x401e:
		dest->mant.m32[0] &= 0xffffffffU << (0x401e - dest->exp);
		dest->mant.m32[1] = 0;
		if (oldmant.m64 == dest->mant.m64)
			return;
		break;
	case 0x401f ... 0x403e:
		dest->mant.m32[1] &= 0xffffffffU << (0x403e - dest->exp);
		if (oldmant.m32[1] == dest->mant.m32[1])
			return;
		break;
	default:
		return;
	}
	fp_set_sr(FPSR_EXC_INEX2);

	/* We might want to normalize upwards here... however, since
	   we know that this is only called on the output of fp_fdiv,
	   or with the input to fp_fint or fp_fintrz, and the inputs
	   to all these functions are either normal or denormalized
	   (no subnormals allowed!), there's really no need.

	   In the case of fp_fdiv, observe that 0x80000000 / 0xffff =
	   0xffff8000, and the same holds for 128-bit / 64-bit. (i.e. the
	   smallest possible normal dividend and the largest possible normal
	   divisor will still produce a normal quotient, therefore, (normal
	   << 64) / normal is normal in all cases) */

	switch (mode) {
	case FPCR_ROUND_RN:
		switch (dest->exp) {
		case 0 ... 0x3ffd:
			return;
		case 0x3ffe:
			/* As noted above, the input is always normal, so the
			   guard bit (bit 63) is always set.  therefore, the
			   only case in which we will NOT round to 1.0 is when
			   the input is exactly 0.5. */
			if (oldmant.m64 == (1ULL << 63))
				return;
			break;
		case 0x3fff ... 0x401d:
			mask = 1 << (0x401d - dest->exp);
			if (!(oldmant.m32[0] & mask))
				return;
			if (oldmant.m32[0] & (mask << 1))
				break;
			if (!(oldmant.m32[0] << (dest->exp - 0x3ffd)) &&
					!oldmant.m32[1])
				return;
			break;
		case 0x401e:
			if (oldmant.m32[1] & 0x80000000)
				return;
			if (oldmant.m32[0] & 1)
				break;
			if (!(oldmant.m32[1] << 1))
				return;
			break;
		case 0x401f ... 0x403d:
			mask = 1 << (0x403d - dest->exp);
			if (!(oldmant.m32[1] & mask))
				return;
			if (oldmant.m32[1] & (mask << 1))
				break;
			if (!(oldmant.m32[1] << (dest->exp - 0x401d)))
				return;
			break;
		default:
			return;
		}
		break;
	case FPCR_ROUND_RZ:
		return;
	default:
		if (dest->sign ^ (mode - FPCR_ROUND_RM))
			break;
		return;
	}

	switch (dest->exp) {
	case 0 ... 0x3ffe:
		dest->exp = 0x3fff;
		dest->mant.m64 = 1ULL << 63;
		break;
	case 0x3fff ... 0x401e:
		mask = 1 << (0x401e - dest->exp);
		if (dest->mant.m32[0] += mask)
			break;
		dest->mant.m32[0] = 0x80000000;
		dest->exp++;
		break;
	case 0x401f ... 0x403e:
		mask = 1 << (0x403e - dest->exp);
		if (dest->mant.m32[1] += mask)
			break;
		if (dest->mant.m32[0] += 1)
                        break;
		dest->mant.m32[0] = 0x80000000;
                dest->exp++;
		break;
	}
}

/* modrem_kernel: Implementation of the FREM and FMOD instructions
   (which are exactly the same, except for the rounding used on the
   intermediate value) */

static struct fp_ext *modrem_kernel(struct fp_ext *dest, struct fp_ext *src,
				    int mode)
{
	struct fp_ext tmp;

	fp_dyadic_check(dest, src);

	/* Infinities and zeros */
	if (IS_INF(dest) || IS_ZERO(src)) {
		fp_set_nan(dest);
		return dest;
	}
	if (IS_ZERO(dest) || IS_INF(src))
		return dest;

	/* FIXME: there is almost certainly a smarter way to do this */
	fp_copy_ext(&tmp, dest);
	fp_fdiv(&tmp, src);		/* NOTE: src might be modified */
	fp_roundint(&tmp, mode);
	fp_fmul(&tmp, src);
	fp_fsub(dest, &tmp);

	/* set the quotient byte */
	fp_set_quotient((dest->mant.m64 & 0x7f) | (dest->sign << 7));
	return dest;
}

/* fp_fmod: Implements the kernel of the FMOD instruction.

   Again, the argument order is backwards.  The result, as defined in
   the Motorola manuals, is:

   fmod(src,dest) = (dest - (src * floor(dest / src))) */

struct fp_ext *fp_fmod(struct fp_ext *dest, struct fp_ext *src)
{
	dprint(PINSTR, "fmod\n");
	return modrem_kernel(dest, src, FPCR_ROUND_RZ);
}

/* fp_frem: Implements the kernel of the FREM instruction.

   frem(src,dest) = (dest - (src * round(dest / src)))
 */

struct fp_ext *fp_frem(struct fp_ext *dest, struct fp_ext *src)
{
	dprint(PINSTR, "frem\n");
	return modrem_kernel(dest, src, FPCR_ROUND_RN);
}

struct fp_ext *fp_fint(struct fp_ext *dest, struct fp_ext *src)
{
	dprint(PINSTR, "fint\n");

	fp_copy_ext(dest, src);

	fp_roundint(dest, FPDATA->rnd);

	return dest;
}

struct fp_ext *fp_fintrz(struct fp_ext *dest, struct fp_ext *src)
{
	dprint(PINSTR, "fintrz\n");

	fp_copy_ext(dest, src);

	fp_roundint(dest, FPCR_ROUND_RZ);

	return dest;
}

struct fp_ext *fp_fscale(struct fp_ext *dest, struct fp_ext *src)
{
	int scale, oldround;

	dprint(PINSTR, "fscale\n");

	fp_dyadic_check(dest, src);

	/* Infinities */
	if (IS_INF(src)) {
		fp_set_nan(dest);
		return dest;
	}
	if (IS_INF(dest))
		return dest;

	/* zeroes */
	if (IS_ZERO(src) || IS_ZERO(dest))
		return dest;

	/* Source exponent out of range */
	if (src->exp >= 0x400c) {
		fp_set_ovrflw(dest);
		return dest;
	}

	/* src must be rounded with round to zero. */
	oldround = FPDATA->rnd;
	FPDATA->rnd = FPCR_ROUND_RZ;
	scale = fp_conv_ext2long(src);
	FPDATA->rnd = oldround;

	/* new exponent */
	scale += dest->exp;

	if (scale >= 0x7fff) {
		fp_set_ovrflw(dest);
	} else if (scale <= 0) {
		fp_set_sr(FPSR_EXC_UNFL);
		fp_denormalize(dest, -scale);
	} else
		dest->exp = scale;

	return dest;
}

