// SPDX-License-Identifier: GPL-2.0
/*---------------------------------------------------------------------------+
 |  reg_ld_str.c                                                             |
 |                                                                           |
 | All of the functions which transfer data between user memory and FPU_REGs.|
 |                                                                           |
 | Copyright (C) 1992,1993,1994,1996,1997                                    |
 |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
 |                  E-mail   billm@suburbia.net                              |
 |                                                                           |
 |                                                                           |
 +---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------+
 | Note:                                                                     |
 |    The file contains code which accesses user memory.                     |
 |    Emulator static data may change when user memory is accessed, due to   |
 |    other processes using the emulator while swapping is in progress.      |
 +---------------------------------------------------------------------------*/

#include "fpu_emu.h"

#include <linux/uaccess.h>

#include "fpu_system.h"
#include "exception.h"
#include "reg_constant.h"
#include "control_w.h"
#include "status_w.h"

#define DOUBLE_Emax 1023	/* largest valid exponent */
#define DOUBLE_Ebias 1023
#define DOUBLE_Emin (-1022)	/* smallest valid exponent */

#define SINGLE_Emax 127		/* largest valid exponent */
#define SINGLE_Ebias 127
#define SINGLE_Emin (-126)	/* smallest valid exponent */

static u_char normalize_no_excep(FPU_REG *r, int exp, int sign)
{
	u_char tag;

	setexponent16(r, exp);

	tag = FPU_normalize_nuo(r);
	stdexp(r);
	if (sign)
		setnegative(r);

	return tag;
}

int FPU_tagof(FPU_REG *ptr)
{
	int exp;

	exp = exponent16(ptr) & 0x7fff;
	if (exp == 0) {
		if (!(ptr->sigh | ptr->sigl)) {
			return TAG_Zero;
		}
		/* The number is a de-normal or pseudodenormal. */
		return TAG_Special;
	}

	if (exp == 0x7fff) {
		/* Is an Infinity, a NaN, or an unsupported data type. */
		return TAG_Special;
	}

	if (!(ptr->sigh & 0x80000000)) {
		/* Unsupported data type. */
		/* Valid numbers have the ms bit set to 1. */
		/* Unnormal. */
		return TAG_Special;
	}

	return TAG_Valid;
}

/* Get a long double from user memory */
int FPU_load_extended(long double __user *s, int stnr)
{
	FPU_REG *sti_ptr = &st(stnr);

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(s, 10);
	__copy_from_user(sti_ptr, s, 10);
	RE_ENTRANT_CHECK_ON;

	return FPU_tagof(sti_ptr);
}

/* Get a double from user memory */
int FPU_load_double(double __user *dfloat, FPU_REG *loaded_data)
{
	int exp, tag, negative;
	unsigned m64, l64;

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(dfloat, 8);
	FPU_get_user(m64, 1 + (unsigned long __user *)dfloat);
	FPU_get_user(l64, (unsigned long __user *)dfloat);
	RE_ENTRANT_CHECK_ON;

	negative = (m64 & 0x80000000) ? SIGN_Negative : SIGN_Positive;
	exp = ((m64 & 0x7ff00000) >> 20) - DOUBLE_Ebias + EXTENDED_Ebias;
	m64 &= 0xfffff;
	if (exp > DOUBLE_Emax + EXTENDED_Ebias) {
		/* Infinity or NaN */
		if ((m64 == 0) && (l64 == 0)) {
			/* +- infinity */
			loaded_data->sigh = 0x80000000;
			loaded_data->sigl = 0x00000000;
			exp = EXP_Infinity + EXTENDED_Ebias;
			tag = TAG_Special;
		} else {
			/* Must be a signaling or quiet NaN */
			exp = EXP_NaN + EXTENDED_Ebias;
			loaded_data->sigh = (m64 << 11) | 0x80000000;
			loaded_data->sigh |= l64 >> 21;
			loaded_data->sigl = l64 << 11;
			tag = TAG_Special;	/* The calling function must look for NaNs */
		}
	} else if (exp < DOUBLE_Emin + EXTENDED_Ebias) {
		/* Zero or de-normal */
		if ((m64 == 0) && (l64 == 0)) {
			/* Zero */
			reg_copy(&CONST_Z, loaded_data);
			exp = 0;
			tag = TAG_Zero;
		} else {
			/* De-normal */
			loaded_data->sigh = m64 << 11;
			loaded_data->sigh |= l64 >> 21;
			loaded_data->sigl = l64 << 11;

			return normalize_no_excep(loaded_data, DOUBLE_Emin,
						  negative)
			    | (denormal_operand() < 0 ? FPU_Exception : 0);
		}
	} else {
		loaded_data->sigh = (m64 << 11) | 0x80000000;
		loaded_data->sigh |= l64 >> 21;
		loaded_data->sigl = l64 << 11;

		tag = TAG_Valid;
	}

	setexponent16(loaded_data, exp | negative);

	return tag;
}

/* Get a float from user memory */
int FPU_load_single(float __user *single, FPU_REG *loaded_data)
{
	unsigned m32;
	int exp, tag, negative;

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(single, 4);
	FPU_get_user(m32, (unsigned long __user *)single);
	RE_ENTRANT_CHECK_ON;

	negative = (m32 & 0x80000000) ? SIGN_Negative : SIGN_Positive;

	if (!(m32 & 0x7fffffff)) {
		/* Zero */
		reg_copy(&CONST_Z, loaded_data);
		addexponent(loaded_data, negative);
		return TAG_Zero;
	}
	exp = ((m32 & 0x7f800000) >> 23) - SINGLE_Ebias + EXTENDED_Ebias;
	m32 = (m32 & 0x7fffff) << 8;
	if (exp < SINGLE_Emin + EXTENDED_Ebias) {
		/* De-normals */
		loaded_data->sigh = m32;
		loaded_data->sigl = 0;

		return normalize_no_excep(loaded_data, SINGLE_Emin, negative)
		    | (denormal_operand() < 0 ? FPU_Exception : 0);
	} else if (exp > SINGLE_Emax + EXTENDED_Ebias) {
		/* Infinity or NaN */
		if (m32 == 0) {
			/* +- infinity */
			loaded_data->sigh = 0x80000000;
			loaded_data->sigl = 0x00000000;
			exp = EXP_Infinity + EXTENDED_Ebias;
			tag = TAG_Special;
		} else {
			/* Must be a signaling or quiet NaN */
			exp = EXP_NaN + EXTENDED_Ebias;
			loaded_data->sigh = m32 | 0x80000000;
			loaded_data->sigl = 0;
			tag = TAG_Special;	/* The calling function must look for NaNs */
		}
	} else {
		loaded_data->sigh = m32 | 0x80000000;
		loaded_data->sigl = 0;
		tag = TAG_Valid;
	}

	setexponent16(loaded_data, exp | negative);	/* Set the sign. */

	return tag;
}

/* Get a long long from user memory */
int FPU_load_int64(long long __user *_s)
{
	long long s;
	int sign;
	FPU_REG *st0_ptr = &st(0);

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(_s, 8);
	if (copy_from_user(&s, _s, 8))
		FPU_abort;
	RE_ENTRANT_CHECK_ON;

	if (s == 0) {
		reg_copy(&CONST_Z, st0_ptr);
		return TAG_Zero;
	}

	if (s > 0)
		sign = SIGN_Positive;
	else {
		s = -s;
		sign = SIGN_Negative;
	}

	significand(st0_ptr) = s;

	return normalize_no_excep(st0_ptr, 63, sign);
}

/* Get a long from user memory */
int FPU_load_int32(long __user *_s, FPU_REG *loaded_data)
{
	long s;
	int negative;

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(_s, 4);
	FPU_get_user(s, _s);
	RE_ENTRANT_CHECK_ON;

	if (s == 0) {
		reg_copy(&CONST_Z, loaded_data);
		return TAG_Zero;
	}

	if (s > 0)
		negative = SIGN_Positive;
	else {
		s = -s;
		negative = SIGN_Negative;
	}

	loaded_data->sigh = s;
	loaded_data->sigl = 0;

	return normalize_no_excep(loaded_data, 31, negative);
}

/* Get a short from user memory */
int FPU_load_int16(short __user *_s, FPU_REG *loaded_data)
{
	int s, negative;

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(_s, 2);
	/* Cast as short to get the sign extended. */
	FPU_get_user(s, _s);
	RE_ENTRANT_CHECK_ON;

	if (s == 0) {
		reg_copy(&CONST_Z, loaded_data);
		return TAG_Zero;
	}

	if (s > 0)
		negative = SIGN_Positive;
	else {
		s = -s;
		negative = SIGN_Negative;
	}

	loaded_data->sigh = s << 16;
	loaded_data->sigl = 0;

	return normalize_no_excep(loaded_data, 15, negative);
}

/* Get a packed bcd array from user memory */
int FPU_load_bcd(u_char __user *s)
{
	FPU_REG *st0_ptr = &st(0);
	int pos;
	u_char bcd;
	long long l = 0;
	int sign;

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(s, 10);
	RE_ENTRANT_CHECK_ON;
	for (pos = 8; pos >= 0; pos--) {
		l *= 10;
		RE_ENTRANT_CHECK_OFF;
		FPU_get_user(bcd, s + pos);
		RE_ENTRANT_CHECK_ON;
		l += bcd >> 4;
		l *= 10;
		l += bcd & 0x0f;
	}

	RE_ENTRANT_CHECK_OFF;
	FPU_get_user(sign, s + 9);
	sign = sign & 0x80 ? SIGN_Negative : SIGN_Positive;
	RE_ENTRANT_CHECK_ON;

	if (l == 0) {
		reg_copy(&CONST_Z, st0_ptr);
		addexponent(st0_ptr, sign);	/* Set the sign. */
		return TAG_Zero;
	} else {
		significand(st0_ptr) = l;
		return normalize_no_excep(st0_ptr, 63, sign);
	}
}

/*===========================================================================*/

/* Put a long double into user memory */
int FPU_store_extended(FPU_REG *st0_ptr, u_char st0_tag,
		       long double __user * d)
{
	/*
	   The only exception raised by an attempt to store to an
	   extended format is the Invalid Stack exception, i.e.
	   attempting to store from an empty register.
	 */

	if (st0_tag != TAG_Empty) {
		RE_ENTRANT_CHECK_OFF;
		FPU_access_ok(d, 10);

		FPU_put_user(st0_ptr->sigl, (unsigned long __user *)d);
		FPU_put_user(st0_ptr->sigh,
			     (unsigned long __user *)((u_char __user *) d + 4));
		FPU_put_user(exponent16(st0_ptr),
			     (unsigned short __user *)((u_char __user *) d +
						       8));
		RE_ENTRANT_CHECK_ON;

		return 1;
	}

	/* Empty register (stack underflow) */
	EXCEPTION(EX_StackUnder);
	if (control_word & CW_Invalid) {
		/* The masked response */
		/* Put out the QNaN indefinite */
		RE_ENTRANT_CHECK_OFF;
		FPU_access_ok(d, 10);
		FPU_put_user(0, (unsigned long __user *)d);
		FPU_put_user(0xc0000000, 1 + (unsigned long __user *)d);
		FPU_put_user(0xffff, 4 + (short __user *)d);
		RE_ENTRANT_CHECK_ON;
		return 1;
	} else
		return 0;

}

/* Put a double into user memory */
int FPU_store_double(FPU_REG *st0_ptr, u_char st0_tag, double __user *dfloat)
{
	unsigned long l[2];
	unsigned long increment = 0;	/* avoid gcc warnings */
	int precision_loss;
	int exp;
	FPU_REG tmp;

	l[0] = 0;
	l[1] = 0;
	if (st0_tag == TAG_Valid) {
		reg_copy(st0_ptr, &tmp);
		exp = exponent(&tmp);

		if (exp < DOUBLE_Emin) {	/* It may be a denormal */
			addexponent(&tmp, -DOUBLE_Emin + 52);	/* largest exp to be 51 */
denormal_arg:
			if ((precision_loss = FPU_round_to_int(&tmp, st0_tag))) {
#ifdef PECULIAR_486
				/* Did it round to a non-denormal ? */
				/* This behaviour might be regarded as peculiar, it appears
				   that the 80486 rounds to the dest precision, then
				   converts to decide underflow. */
				if (!
				    ((tmp.sigh == 0x00100000) && (tmp.sigl == 0)
				     && (st0_ptr->sigl & 0x000007ff)))
#endif /* PECULIAR_486 */
				{
					EXCEPTION(EX_Underflow);
					/* This is a special case: see sec 16.2.5.1 of
					   the 80486 book */
					if (!(control_word & CW_Underflow))
						return 0;
				}
				EXCEPTION(precision_loss);
				if (!(control_word & CW_Precision))
					return 0;
			}
			l[0] = tmp.sigl;
			l[1] = tmp.sigh;
		} else {
			if (tmp.sigl & 0x000007ff) {
				precision_loss = 1;
				switch (control_word & CW_RC) {
				case RC_RND:
					/* Rounding can get a little messy.. */
					increment = ((tmp.sigl & 0x7ff) > 0x400) |	/* nearest */
					    ((tmp.sigl & 0xc00) == 0xc00);	/* odd -> even */
					break;
				case RC_DOWN:	/* towards -infinity */
					increment =
					    signpositive(&tmp) ? 0 : tmp.
					    sigl & 0x7ff;
					break;
				case RC_UP:	/* towards +infinity */
					increment =
					    signpositive(&tmp) ? tmp.
					    sigl & 0x7ff : 0;
					break;
				case RC_CHOP:
					increment = 0;
					break;
				}

				/* Truncate the mantissa */
				tmp.sigl &= 0xfffff800;

				if (increment) {
					if (tmp.sigl >= 0xfffff800) {
						/* the sigl part overflows */
						if (tmp.sigh == 0xffffffff) {
							/* The sigh part overflows */
							tmp.sigh = 0x80000000;
							exp++;
							if (exp >= EXP_OVER)
								goto overflow;
						} else {
							tmp.sigh++;
						}
						tmp.sigl = 0x00000000;
					} else {
						/* We only need to increment sigl */
						tmp.sigl += 0x00000800;
					}
				}
			} else
				precision_loss = 0;

			l[0] = (tmp.sigl >> 11) | (tmp.sigh << 21);
			l[1] = ((tmp.sigh >> 11) & 0xfffff);

			if (exp > DOUBLE_Emax) {
			      overflow:
				EXCEPTION(EX_Overflow);
				if (!(control_word & CW_Overflow))
					return 0;
				set_precision_flag_up();
				if (!(control_word & CW_Precision))
					return 0;

				/* This is a special case: see sec 16.2.5.1 of the 80486 book */
				/* Overflow to infinity */
				l[1] = 0x7ff00000;	/* Set to + INF */
			} else {
				if (precision_loss) {
					if (increment)
						set_precision_flag_up();
					else
						set_precision_flag_down();
				}
				/* Add the exponent */
				l[1] |= (((exp + DOUBLE_Ebias) & 0x7ff) << 20);
			}
		}
	} else if (st0_tag == TAG_Zero) {
		/* Number is zero */
	} else if (st0_tag == TAG_Special) {
		st0_tag = FPU_Special(st0_ptr);
		if (st0_tag == TW_Denormal) {
			/* A denormal will always underflow. */
#ifndef PECULIAR_486
			/* An 80486 is supposed to be able to generate
			   a denormal exception here, but... */
			/* Underflow has priority. */
			if (control_word & CW_Underflow)
				denormal_operand();
#endif /* PECULIAR_486 */
			reg_copy(st0_ptr, &tmp);
			goto denormal_arg;
		} else if (st0_tag == TW_Infinity) {
			l[1] = 0x7ff00000;
		} else if (st0_tag == TW_NaN) {
			/* Is it really a NaN ? */
			if ((exponent(st0_ptr) == EXP_OVER)
			    && (st0_ptr->sigh & 0x80000000)) {
				/* See if we can get a valid NaN from the FPU_REG */
				l[0] =
				    (st0_ptr->sigl >> 11) | (st0_ptr->
							     sigh << 21);
				l[1] = ((st0_ptr->sigh >> 11) & 0xfffff);
				if (!(st0_ptr->sigh & 0x40000000)) {
					/* It is a signalling NaN */
					EXCEPTION(EX_Invalid);
					if (!(control_word & CW_Invalid))
						return 0;
					l[1] |= (0x40000000 >> 11);
				}
				l[1] |= 0x7ff00000;
			} else {
				/* It is an unsupported data type */
				EXCEPTION(EX_Invalid);
				if (!(control_word & CW_Invalid))
					return 0;
				l[1] = 0xfff80000;
			}
		}
	} else if (st0_tag == TAG_Empty) {
		/* Empty register (stack underflow) */
		EXCEPTION(EX_StackUnder);
		if (control_word & CW_Invalid) {
			/* The masked response */
			/* Put out the QNaN indefinite */
			RE_ENTRANT_CHECK_OFF;
			FPU_access_ok(dfloat, 8);
			FPU_put_user(0, (unsigned long __user *)dfloat);
			FPU_put_user(0xfff80000,
				     1 + (unsigned long __user *)dfloat);
			RE_ENTRANT_CHECK_ON;
			return 1;
		} else
			return 0;
	}
	if (getsign(st0_ptr))
		l[1] |= 0x80000000;

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(dfloat, 8);
	FPU_put_user(l[0], (unsigned long __user *)dfloat);
	FPU_put_user(l[1], 1 + (unsigned long __user *)dfloat);
	RE_ENTRANT_CHECK_ON;

	return 1;
}

/* Put a float into user memory */
int FPU_store_single(FPU_REG *st0_ptr, u_char st0_tag, float __user *single)
{
	long templ = 0;
	unsigned long increment = 0;	/* avoid gcc warnings */
	int precision_loss;
	int exp;
	FPU_REG tmp;

	if (st0_tag == TAG_Valid) {

		reg_copy(st0_ptr, &tmp);
		exp = exponent(&tmp);

		if (exp < SINGLE_Emin) {
			addexponent(&tmp, -SINGLE_Emin + 23);	/* largest exp to be 22 */

		      denormal_arg:

			if ((precision_loss = FPU_round_to_int(&tmp, st0_tag))) {
#ifdef PECULIAR_486
				/* Did it round to a non-denormal ? */
				/* This behaviour might be regarded as peculiar, it appears
				   that the 80486 rounds to the dest precision, then
				   converts to decide underflow. */
				if (!((tmp.sigl == 0x00800000) &&
				      ((st0_ptr->sigh & 0x000000ff)
				       || st0_ptr->sigl)))
#endif /* PECULIAR_486 */
				{
					EXCEPTION(EX_Underflow);
					/* This is a special case: see sec 16.2.5.1 of
					   the 80486 book */
					if (!(control_word & CW_Underflow))
						return 0;
				}
				EXCEPTION(precision_loss);
				if (!(control_word & CW_Precision))
					return 0;
			}
			templ = tmp.sigl;
		} else {
			if (tmp.sigl | (tmp.sigh & 0x000000ff)) {
				unsigned long sigh = tmp.sigh;
				unsigned long sigl = tmp.sigl;

				precision_loss = 1;
				switch (control_word & CW_RC) {
				case RC_RND:
					increment = ((sigh & 0xff) > 0x80)	/* more than half */
					    ||(((sigh & 0xff) == 0x80) && sigl)	/* more than half */
					    ||((sigh & 0x180) == 0x180);	/* round to even */
					break;
				case RC_DOWN:	/* towards -infinity */
					increment = signpositive(&tmp)
					    ? 0 : (sigl | (sigh & 0xff));
					break;
				case RC_UP:	/* towards +infinity */
					increment = signpositive(&tmp)
					    ? (sigl | (sigh & 0xff)) : 0;
					break;
				case RC_CHOP:
					increment = 0;
					break;
				}

				/* Truncate part of the mantissa */
				tmp.sigl = 0;

				if (increment) {
					if (sigh >= 0xffffff00) {
						/* The sigh part overflows */
						tmp.sigh = 0x80000000;
						exp++;
						if (exp >= EXP_OVER)
							goto overflow;
					} else {
						tmp.sigh &= 0xffffff00;
						tmp.sigh += 0x100;
					}
				} else {
					tmp.sigh &= 0xffffff00;	/* Finish the truncation */
				}
			} else
				precision_loss = 0;

			templ = (tmp.sigh >> 8) & 0x007fffff;

			if (exp > SINGLE_Emax) {
			      overflow:
				EXCEPTION(EX_Overflow);
				if (!(control_word & CW_Overflow))
					return 0;
				set_precision_flag_up();
				if (!(control_word & CW_Precision))
					return 0;

				/* This is a special case: see sec 16.2.5.1 of the 80486 book. */
				/* Masked response is overflow to infinity. */
				templ = 0x7f800000;
			} else {
				if (precision_loss) {
					if (increment)
						set_precision_flag_up();
					else
						set_precision_flag_down();
				}
				/* Add the exponent */
				templ |= ((exp + SINGLE_Ebias) & 0xff) << 23;
			}
		}
	} else if (st0_tag == TAG_Zero) {
		templ = 0;
	} else if (st0_tag == TAG_Special) {
		st0_tag = FPU_Special(st0_ptr);
		if (st0_tag == TW_Denormal) {
			reg_copy(st0_ptr, &tmp);

			/* A denormal will always underflow. */
#ifndef PECULIAR_486
			/* An 80486 is supposed to be able to generate
			   a denormal exception here, but... */
			/* Underflow has priority. */
			if (control_word & CW_Underflow)
				denormal_operand();
#endif /* PECULIAR_486 */
			goto denormal_arg;
		} else if (st0_tag == TW_Infinity) {
			templ = 0x7f800000;
		} else if (st0_tag == TW_NaN) {
			/* Is it really a NaN ? */
			if ((exponent(st0_ptr) == EXP_OVER)
			    && (st0_ptr->sigh & 0x80000000)) {
				/* See if we can get a valid NaN from the FPU_REG */
				templ = st0_ptr->sigh >> 8;
				if (!(st0_ptr->sigh & 0x40000000)) {
					/* It is a signalling NaN */
					EXCEPTION(EX_Invalid);
					if (!(control_word & CW_Invalid))
						return 0;
					templ |= (0x40000000 >> 8);
				}
				templ |= 0x7f800000;
			} else {
				/* It is an unsupported data type */
				EXCEPTION(EX_Invalid);
				if (!(control_word & CW_Invalid))
					return 0;
				templ = 0xffc00000;
			}
		}
#ifdef PARANOID
		else {
			EXCEPTION(EX_INTERNAL | 0x164);
			return 0;
		}
#endif
	} else if (st0_tag == TAG_Empty) {
		/* Empty register (stack underflow) */
		EXCEPTION(EX_StackUnder);
		if (control_word & EX_Invalid) {
			/* The masked response */
			/* Put out the QNaN indefinite */
			RE_ENTRANT_CHECK_OFF;
			FPU_access_ok(single, 4);
			FPU_put_user(0xffc00000,
				     (unsigned long __user *)single);
			RE_ENTRANT_CHECK_ON;
			return 1;
		} else
			return 0;
	}
#ifdef PARANOID
	else {
		EXCEPTION(EX_INTERNAL | 0x163);
		return 0;
	}
#endif
	if (getsign(st0_ptr))
		templ |= 0x80000000;

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(single, 4);
	FPU_put_user(templ, (unsigned long __user *)single);
	RE_ENTRANT_CHECK_ON;

	return 1;
}

/* Put a long long into user memory */
int FPU_store_int64(FPU_REG *st0_ptr, u_char st0_tag, long long __user *d)
{
	FPU_REG t;
	long long tll;
	int precision_loss;

	if (st0_tag == TAG_Empty) {
		/* Empty register (stack underflow) */
		EXCEPTION(EX_StackUnder);
		goto invalid_operand;
	} else if (st0_tag == TAG_Special) {
		st0_tag = FPU_Special(st0_ptr);
		if ((st0_tag == TW_Infinity) || (st0_tag == TW_NaN)) {
			EXCEPTION(EX_Invalid);
			goto invalid_operand;
		}
	}

	reg_copy(st0_ptr, &t);
	precision_loss = FPU_round_to_int(&t, st0_tag);
	((long *)&tll)[0] = t.sigl;
	((long *)&tll)[1] = t.sigh;
	if ((precision_loss == 1) ||
	    ((t.sigh & 0x80000000) &&
	     !((t.sigh == 0x80000000) && (t.sigl == 0) && signnegative(&t)))) {
		EXCEPTION(EX_Invalid);
		/* This is a special case: see sec 16.2.5.1 of the 80486 book */
	      invalid_operand:
		if (control_word & EX_Invalid) {
			/* Produce something like QNaN "indefinite" */
			tll = 0x8000000000000000LL;
		} else
			return 0;
	} else {
		if (precision_loss)
			set_precision_flag(precision_loss);
		if (signnegative(&t))
			tll = -tll;
	}

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(d, 8);
	if (copy_to_user(d, &tll, 8))
		FPU_abort;
	RE_ENTRANT_CHECK_ON;

	return 1;
}

/* Put a long into user memory */
int FPU_store_int32(FPU_REG *st0_ptr, u_char st0_tag, long __user *d)
{
	FPU_REG t;
	int precision_loss;

	if (st0_tag == TAG_Empty) {
		/* Empty register (stack underflow) */
		EXCEPTION(EX_StackUnder);
		goto invalid_operand;
	} else if (st0_tag == TAG_Special) {
		st0_tag = FPU_Special(st0_ptr);
		if ((st0_tag == TW_Infinity) || (st0_tag == TW_NaN)) {
			EXCEPTION(EX_Invalid);
			goto invalid_operand;
		}
	}

	reg_copy(st0_ptr, &t);
	precision_loss = FPU_round_to_int(&t, st0_tag);
	if (t.sigh ||
	    ((t.sigl & 0x80000000) &&
	     !((t.sigl == 0x80000000) && signnegative(&t)))) {
		EXCEPTION(EX_Invalid);
		/* This is a special case: see sec 16.2.5.1 of the 80486 book */
	      invalid_operand:
		if (control_word & EX_Invalid) {
			/* Produce something like QNaN "indefinite" */
			t.sigl = 0x80000000;
		} else
			return 0;
	} else {
		if (precision_loss)
			set_precision_flag(precision_loss);
		if (signnegative(&t))
			t.sigl = -(long)t.sigl;
	}

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(d, 4);
	FPU_put_user(t.sigl, (unsigned long __user *)d);
	RE_ENTRANT_CHECK_ON;

	return 1;
}

/* Put a short into user memory */
int FPU_store_int16(FPU_REG *st0_ptr, u_char st0_tag, short __user *d)
{
	FPU_REG t;
	int precision_loss;

	if (st0_tag == TAG_Empty) {
		/* Empty register (stack underflow) */
		EXCEPTION(EX_StackUnder);
		goto invalid_operand;
	} else if (st0_tag == TAG_Special) {
		st0_tag = FPU_Special(st0_ptr);
		if ((st0_tag == TW_Infinity) || (st0_tag == TW_NaN)) {
			EXCEPTION(EX_Invalid);
			goto invalid_operand;
		}
	}

	reg_copy(st0_ptr, &t);
	precision_loss = FPU_round_to_int(&t, st0_tag);
	if (t.sigh ||
	    ((t.sigl & 0xffff8000) &&
	     !((t.sigl == 0x8000) && signnegative(&t)))) {
		EXCEPTION(EX_Invalid);
		/* This is a special case: see sec 16.2.5.1 of the 80486 book */
	      invalid_operand:
		if (control_word & EX_Invalid) {
			/* Produce something like QNaN "indefinite" */
			t.sigl = 0x8000;
		} else
			return 0;
	} else {
		if (precision_loss)
			set_precision_flag(precision_loss);
		if (signnegative(&t))
			t.sigl = -t.sigl;
	}

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(d, 2);
	FPU_put_user((short)t.sigl, d);
	RE_ENTRANT_CHECK_ON;

	return 1;
}

/* Put a packed bcd array into user memory */
int FPU_store_bcd(FPU_REG *st0_ptr, u_char st0_tag, u_char __user *d)
{
	FPU_REG t;
	unsigned long long ll;
	u_char b;
	int i, precision_loss;
	u_char sign = (getsign(st0_ptr) == SIGN_NEG) ? 0x80 : 0;

	if (st0_tag == TAG_Empty) {
		/* Empty register (stack underflow) */
		EXCEPTION(EX_StackUnder);
		goto invalid_operand;
	} else if (st0_tag == TAG_Special) {
		st0_tag = FPU_Special(st0_ptr);
		if ((st0_tag == TW_Infinity) || (st0_tag == TW_NaN)) {
			EXCEPTION(EX_Invalid);
			goto invalid_operand;
		}
	}

	reg_copy(st0_ptr, &t);
	precision_loss = FPU_round_to_int(&t, st0_tag);
	ll = significand(&t);

	/* Check for overflow, by comparing with 999999999999999999 decimal. */
	if ((t.sigh > 0x0de0b6b3) ||
	    ((t.sigh == 0x0de0b6b3) && (t.sigl > 0xa763ffff))) {
		EXCEPTION(EX_Invalid);
		/* This is a special case: see sec 16.2.5.1 of the 80486 book */
	      invalid_operand:
		if (control_word & CW_Invalid) {
			/* Produce the QNaN "indefinite" */
			RE_ENTRANT_CHECK_OFF;
			FPU_access_ok(d, 10);
			for (i = 0; i < 7; i++)
				FPU_put_user(0, d + i);	/* These bytes "undefined" */
			FPU_put_user(0xc0, d + 7);	/* This byte "undefined" */
			FPU_put_user(0xff, d + 8);
			FPU_put_user(0xff, d + 9);
			RE_ENTRANT_CHECK_ON;
			return 1;
		} else
			return 0;
	} else if (precision_loss) {
		/* Precision loss doesn't stop the data transfer */
		set_precision_flag(precision_loss);
	}

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(d, 10);
	RE_ENTRANT_CHECK_ON;
	for (i = 0; i < 9; i++) {
		b = FPU_div_small(&ll, 10);
		b |= (FPU_div_small(&ll, 10)) << 4;
		RE_ENTRANT_CHECK_OFF;
		FPU_put_user(b, d + i);
		RE_ENTRANT_CHECK_ON;
	}
	RE_ENTRANT_CHECK_OFF;
	FPU_put_user(sign, d + 9);
	RE_ENTRANT_CHECK_ON;

	return 1;
}

/*===========================================================================*/

/* r gets mangled such that sig is int, sign: 
   it is NOT normalized */
/* The return value (in eax) is zero if the result is exact,
   if bits are changed due to rounding, truncation, etc, then
   a non-zero value is returned */
/* Overflow is signalled by a non-zero return value (in eax).
   In the case of overflow, the returned significand always has the
   largest possible value */
int FPU_round_to_int(FPU_REG *r, u_char tag)
{
	u_char very_big;
	unsigned eax;

	if (tag == TAG_Zero) {
		/* Make sure that zero is returned */
		significand(r) = 0;
		return 0;	/* o.k. */
	}

	if (exponent(r) > 63) {
		r->sigl = r->sigh = ~0;	/* The largest representable number */
		return 1;	/* overflow */
	}

	eax = FPU_shrxs(&r->sigl, 63 - exponent(r));
	very_big = !(~(r->sigh) | ~(r->sigl));	/* test for 0xfff...fff */
#define	half_or_more	(eax & 0x80000000)
#define	frac_part	(eax)
#define more_than_half  ((eax & 0x80000001) == 0x80000001)
	switch (control_word & CW_RC) {
	case RC_RND:
		if (more_than_half	/* nearest */
		    || (half_or_more && (r->sigl & 1))) {	/* odd -> even */
			if (very_big)
				return 1;	/* overflow */
			significand(r)++;
			return PRECISION_LOST_UP;
		}
		break;
	case RC_DOWN:
		if (frac_part && getsign(r)) {
			if (very_big)
				return 1;	/* overflow */
			significand(r)++;
			return PRECISION_LOST_UP;
		}
		break;
	case RC_UP:
		if (frac_part && !getsign(r)) {
			if (very_big)
				return 1;	/* overflow */
			significand(r)++;
			return PRECISION_LOST_UP;
		}
		break;
	case RC_CHOP:
		break;
	}

	return eax ? PRECISION_LOST_DOWN : 0;

}

/*===========================================================================*/

u_char __user *fldenv(fpu_addr_modes addr_modes, u_char __user *s)
{
	unsigned short tag_word = 0;
	u_char tag;
	int i;

	if ((addr_modes.default_mode == VM86) ||
	    ((addr_modes.default_mode == PM16)
	     ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX))) {
		RE_ENTRANT_CHECK_OFF;
		FPU_access_ok(s, 0x0e);
		FPU_get_user(control_word, (unsigned short __user *)s);
		FPU_get_user(partial_status, (unsigned short __user *)(s + 2));
		FPU_get_user(tag_word, (unsigned short __user *)(s + 4));
		FPU_get_user(instruction_address.offset,
			     (unsigned short __user *)(s + 6));
		FPU_get_user(instruction_address.selector,
			     (unsigned short __user *)(s + 8));
		FPU_get_user(operand_address.offset,
			     (unsigned short __user *)(s + 0x0a));
		FPU_get_user(operand_address.selector,
			     (unsigned short __user *)(s + 0x0c));
		RE_ENTRANT_CHECK_ON;
		s += 0x0e;
		if (addr_modes.default_mode == VM86) {
			instruction_address.offset
			    += (instruction_address.selector & 0xf000) << 4;
			operand_address.offset +=
			    (operand_address.selector & 0xf000) << 4;
		}
	} else {
		RE_ENTRANT_CHECK_OFF;
		FPU_access_ok(s, 0x1c);
		FPU_get_user(control_word, (unsigned short __user *)s);
		FPU_get_user(partial_status, (unsigned short __user *)(s + 4));
		FPU_get_user(tag_word, (unsigned short __user *)(s + 8));
		FPU_get_user(instruction_address.offset,
			     (unsigned long __user *)(s + 0x0c));
		FPU_get_user(instruction_address.selector,
			     (unsigned short __user *)(s + 0x10));
		FPU_get_user(instruction_address.opcode,
			     (unsigned short __user *)(s + 0x12));
		FPU_get_user(operand_address.offset,
			     (unsigned long __user *)(s + 0x14));
		FPU_get_user(operand_address.selector,
			     (unsigned long __user *)(s + 0x18));
		RE_ENTRANT_CHECK_ON;
		s += 0x1c;
	}

#ifdef PECULIAR_486
	control_word &= ~0xe080;
#endif /* PECULIAR_486 */

	top = (partial_status >> SW_Top_Shift) & 7;

	if (partial_status & ~control_word & CW_Exceptions)
		partial_status |= (SW_Summary | SW_Backward);
	else
		partial_status &= ~(SW_Summary | SW_Backward);

	for (i = 0; i < 8; i++) {
		tag = tag_word & 3;
		tag_word >>= 2;

		if (tag == TAG_Empty)
			/* New tag is empty.  Accept it */
			FPU_settag(i, TAG_Empty);
		else if (FPU_gettag(i) == TAG_Empty) {
			/* Old tag is empty and new tag is not empty.  New tag is determined
			   by old reg contents */
			if (exponent(&fpu_register(i)) == -EXTENDED_Ebias) {
				if (!
				    (fpu_register(i).sigl | fpu_register(i).
				     sigh))
					FPU_settag(i, TAG_Zero);
				else
					FPU_settag(i, TAG_Special);
			} else if (exponent(&fpu_register(i)) ==
				   0x7fff - EXTENDED_Ebias) {
				FPU_settag(i, TAG_Special);
			} else if (fpu_register(i).sigh & 0x80000000)
				FPU_settag(i, TAG_Valid);
			else
				FPU_settag(i, TAG_Special);	/* An Un-normal */
		}
		/* Else old tag is not empty and new tag is not empty.  Old tag
		   remains correct */
	}

	return s;
}

void frstor(fpu_addr_modes addr_modes, u_char __user *data_address)
{
	int i, regnr;
	u_char __user *s = fldenv(addr_modes, data_address);
	int offset = (top & 7) * 10, other = 80 - offset;

	/* Copy all registers in stack order. */
	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(s, 80);
	__copy_from_user(register_base + offset, s, other);
	if (offset)
		__copy_from_user(register_base, s + other, offset);
	RE_ENTRANT_CHECK_ON;

	for (i = 0; i < 8; i++) {
		regnr = (i + top) & 7;
		if (FPU_gettag(regnr) != TAG_Empty)
			/* The loaded data over-rides all other cases. */
			FPU_settag(regnr, FPU_tagof(&st(i)));
	}

}

u_char __user *fstenv(fpu_addr_modes addr_modes, u_char __user *d)
{
	if ((addr_modes.default_mode == VM86) ||
	    ((addr_modes.default_mode == PM16)
	     ^ (addr_modes.override.operand_size == OP_SIZE_PREFIX))) {
		RE_ENTRANT_CHECK_OFF;
		FPU_access_ok(d, 14);
#ifdef PECULIAR_486
		FPU_put_user(control_word & ~0xe080, (unsigned long __user *)d);
#else
		FPU_put_user(control_word, (unsigned short __user *)d);
#endif /* PECULIAR_486 */
		FPU_put_user(status_word(), (unsigned short __user *)(d + 2));
		FPU_put_user(fpu_tag_word, (unsigned short __user *)(d + 4));
		FPU_put_user(instruction_address.offset,
			     (unsigned short __user *)(d + 6));
		FPU_put_user(operand_address.offset,
			     (unsigned short __user *)(d + 0x0a));
		if (addr_modes.default_mode == VM86) {
			FPU_put_user((instruction_address.
				      offset & 0xf0000) >> 4,
				     (unsigned short __user *)(d + 8));
			FPU_put_user((operand_address.offset & 0xf0000) >> 4,
				     (unsigned short __user *)(d + 0x0c));
		} else {
			FPU_put_user(instruction_address.selector,
				     (unsigned short __user *)(d + 8));
			FPU_put_user(operand_address.selector,
				     (unsigned short __user *)(d + 0x0c));
		}
		RE_ENTRANT_CHECK_ON;
		d += 0x0e;
	} else {
		RE_ENTRANT_CHECK_OFF;
		FPU_access_ok(d, 7 * 4);
#ifdef PECULIAR_486
		control_word &= ~0xe080;
		/* An 80486 sets nearly all of the reserved bits to 1. */
		control_word |= 0xffff0040;
		partial_status = status_word() | 0xffff0000;
		fpu_tag_word |= 0xffff0000;
		I387->soft.fcs &= ~0xf8000000;
		I387->soft.fos |= 0xffff0000;
#endif /* PECULIAR_486 */
		if (__copy_to_user(d, &control_word, 7 * 4))
			FPU_abort;
		RE_ENTRANT_CHECK_ON;
		d += 0x1c;
	}

	control_word |= CW_Exceptions;
	partial_status &= ~(SW_Summary | SW_Backward);

	return d;
}

void fsave(fpu_addr_modes addr_modes, u_char __user *data_address)
{
	u_char __user *d;
	int offset = (top & 7) * 10, other = 80 - offset;

	d = fstenv(addr_modes, data_address);

	RE_ENTRANT_CHECK_OFF;
	FPU_access_ok(d, 80);

	/* Copy all registers in stack order. */
	if (__copy_to_user(d, register_base + offset, other))
		FPU_abort;
	if (offset)
		if (__copy_to_user(d + other, register_base, offset))
			FPU_abort;
	RE_ENTRANT_CHECK_ON;

	finit();
}

/*===========================================================================*/
