#if __mips64 && !defined(SINGLE_ONLY_FPU) 
#if defined(__mips64) && !defined(SINGLE_ONLY_FPU) 
static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_soft_struct *ctx,	mips_instruction ir){	int rfmt;		/* resulting format */	unsigned rcsr = 0;	/* resulting csr */	unsigned cond;	union {		ieee754dp d;		ieee754sp s;		int w;#if __mips64		s64 l;#endif	} rv;			/* resulting value */	fpuemuprivate.stats.cp1ops++;	switch (rfmt = (MIPSInst_FFMT(ir) & 0xf)) {	case s_fmt:{		/* 0 */		union {			ieee754sp(*b) (ieee754sp, ieee754sp);			ieee754sp(*u) (ieee754sp);		} handler;		switch (MIPSInst_FUNC(ir)) {			/* binary ops */		case fadd_op:			handler.b = ieee754sp_add;			goto scopbop;		case fsub_op:			handler.b = ieee754sp_sub;			goto scopbop;		case fmul_op:			handler.b = ieee754sp_mul;			goto scopbop;		case fdiv_op:			handler.b = ieee754sp_div;			goto scopbop;			/* unary  ops */#if __mips >= 2 || __mips64		case fsqrt_op:			handler.u = ieee754sp_sqrt;			goto scopuop;#endif#if __mips >= 4 && __mips != 32		case frsqrt_op:			handler.u = fpemu_sp_rsqrt;			goto scopuop;		case frecip_op:			handler.u = fpemu_sp_recip;			goto scopuop;#endif#if __mips >= 4		case fmovc_op:			cond = fpucondbit[MIPSInst_FT(ir) >> 2];			if (((ctx->fcr31 & cond) != 0) !=				((MIPSInst_FT(ir) & 1) != 0))				return 0;			SPFROMREG(rv.s, MIPSInst_FS(ir));			break;		case fmovz_op:			if (xcp->regs[MIPSInst_FT(ir)] != 0)				return 0;			SPFROMREG(rv.s, MIPSInst_FS(ir));			break;		case fmovn_op:			if (xcp->regs[MIPSInst_FT(ir)] == 0)				return 0;			SPFROMREG(rv.s, MIPSInst_FS(ir));			break;#endif		case fabs_op:			handler.u = ieee754sp_abs;			goto scopuop;		case fneg_op:			handler.u = ieee754sp_neg;			goto scopuop;		case fmov_op:			/* an easy one */			SPFROMREG(rv.s, MIPSInst_FS(ir));			goto copcsr;			/* binary op on handler */		      scopbop:			{				ieee754sp fs, ft;				SPFROMREG(fs, MIPSInst_FS(ir));				SPFROMREG(ft, MIPSInst_FT(ir));				rv.s = (*handler.b) (fs, ft);				goto copcsr;			}		      scopuop:			{				ieee754sp fs;				SPFROMREG(fs, MIPSInst_FS(ir));				rv.s = (*handler.u) (fs);				goto copcsr;			}		      copcsr:			if (ieee754_cxtest(IEEE754_INEXACT))				rcsr |= FPU_CSR_INE_X | FPU_CSR_INE_S;			if (ieee754_cxtest(IEEE754_UNDERFLOW))				rcsr |= FPU_CSR_UDF_X | FPU_CSR_UDF_S;			if (ieee754_cxtest(IEEE754_OVERFLOW))				rcsr |= FPU_CSR_OVF_X | FPU_CSR_OVF_S;			if (ieee754_cxtest(IEEE754_ZERO_DIVIDE))				rcsr |= FPU_CSR_DIV_X | FPU_CSR_DIV_S;			if (ieee754_cxtest(IEEE754_INVALID_OPERATION))				rcsr |= FPU_CSR_INV_X | FPU_CSR_INV_S;			break;			/* unary conv ops */		case fcvts_op:			return SIGILL;	/* not defined */		case fcvtd_op:{#ifdef SINGLE_ONLY_FPU			return SIGILL;	/* not defined */#else			ieee754sp fs;			SPFROMREG(fs, MIPSInst_FS(ir));			rv.d = ieee754dp_fsp(fs);			rfmt = d_fmt;			goto copcsr;		}#endif		case fcvtw_op:{			ieee754sp fs;			SPFROMREG(fs, MIPSInst_FS(ir));			rv.w = ieee754sp_tint(fs);			rfmt = w_fmt;			goto copcsr;		}#if __mips >= 2 || __mips64		case fround_op:		case ftrunc_op:		case fceil_op:		case ffloor_op:{			unsigned int oldrm = ieee754_csr.rm;			ieee754sp fs;			SPFROMREG(fs, MIPSInst_FS(ir));			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];			rv.w = ieee754sp_tint(fs);			ieee754_csr.rm = oldrm;			rfmt = w_fmt;			goto copcsr;		}#endif /* __mips >= 2 */#if __mips64 && !defined(SINGLE_ONLY_FPU)		case fcvtl_op:{			ieee754sp fs;			SPFROMREG(fs, MIPSInst_FS(ir));			rv.l = ieee754sp_tlong(fs);			rfmt = l_fmt;			goto copcsr;		}		case froundl_op:		case ftruncl_op:		case fceill_op:		case ffloorl_op:{			unsigned int oldrm = ieee754_csr.rm;			ieee754sp fs;			SPFROMREG(fs, MIPSInst_FS(ir));			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];			rv.l = ieee754sp_tlong(fs);			ieee754_csr.rm = oldrm;			rfmt = l_fmt;			goto copcsr;		}#endif /* __mips64 && !fpu(single) */		default:			if (MIPSInst_FUNC(ir) >= fcmp_op) {				unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;				ieee754sp fs, ft;				SPFROMREG(fs, MIPSInst_FS(ir));				SPFROMREG(ft, MIPSInst_FT(ir));				rv.w = ieee754sp_cmp(fs, ft,					cmptab[cmpop & 0x7], cmpop & 0x8);				rfmt = -1;				if ((cmpop & 0x8) && ieee754_cxtest					(IEEE754_INVALID_OPERATION))					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;				else					goto copcsr;			}			else {				return SIGILL;			}			break;		}		break;	}#ifndef SINGLE_ONLY_FPU	case d_fmt:{		union {			ieee754dp(*b) (ieee754dp, ieee754dp);			ieee754dp(*u) (ieee754dp);		} handler;		switch (MIPSInst_FUNC(ir)) {			/* binary ops */		case fadd_op:			handler.b = ieee754dp_add;			goto dcopbop;		case fsub_op:			handler.b = ieee754dp_sub;			goto dcopbop;		case fmul_op:			handler.b = ieee754dp_mul;			goto dcopbop;		case fdiv_op:			handler.b = ieee754dp_div;			goto dcopbop;			/* unary  ops */#if __mips >= 2 || __mips64		case fsqrt_op:			handler.u = ieee754dp_sqrt;			goto dcopuop;#endif#if __mips >= 4 && __mips != 32		case frsqrt_op:			handler.u = fpemu_dp_rsqrt;			goto dcopuop;		case frecip_op:			handler.u = fpemu_dp_recip;			goto dcopuop;#endif#if __mips >= 4		case fmovc_op:			cond = fpucondbit[MIPSInst_FT(ir) >> 2];			if (((ctx->fcr31 & cond) != 0) !=				((MIPSInst_FT(ir) & 1) != 0))				return 0;			DPFROMREG(rv.d, MIPSInst_FS(ir));			break;		case fmovz_op:			if (xcp->regs[MIPSInst_FT(ir)] != 0)				return 0;			DPFROMREG(rv.d, MIPSInst_FS(ir));			break;		case fmovn_op:			if (xcp->regs[MIPSInst_FT(ir)] == 0)				return 0;			DPFROMREG(rv.d, MIPSInst_FS(ir));			break;#endif		case fabs_op:			handler.u = ieee754dp_abs;			goto dcopuop;		case fneg_op:			handler.u = ieee754dp_neg;			goto dcopuop;		case fmov_op:			/* an easy one */			DPFROMREG(rv.d, MIPSInst_FS(ir));			goto copcsr;			/* binary op on handler */		      dcopbop:{				ieee754dp fs, ft;				DPFROMREG(fs, MIPSInst_FS(ir));				DPFROMREG(ft, MIPSInst_FT(ir));				rv.d = (*handler.b) (fs, ft);				goto copcsr;			}		      dcopuop:{				ieee754dp fs;				DPFROMREG(fs, MIPSInst_FS(ir));				rv.d = (*handler.u) (fs);				goto copcsr;			}			/* unary conv ops */		case fcvts_op:{			ieee754dp fs;			DPFROMREG(fs, MIPSInst_FS(ir));			rv.s = ieee754sp_fdp(fs);			rfmt = s_fmt;			goto copcsr;		}		case fcvtd_op:			return SIGILL;	/* not defined */		case fcvtw_op:{			ieee754dp fs;			DPFROMREG(fs, MIPSInst_FS(ir));			rv.w = ieee754dp_tint(fs);	/* wrong */			rfmt = w_fmt;			goto copcsr;		}#if __mips >= 2 || __mips64		case fround_op:		case ftrunc_op:		case fceil_op:		case ffloor_op:{			unsigned int oldrm = ieee754_csr.rm;			ieee754dp fs;			DPFROMREG(fs, MIPSInst_FS(ir));			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];			rv.w = ieee754dp_tint(fs);			ieee754_csr.rm = oldrm;			rfmt = w_fmt;			goto copcsr;		}#endif#if __mips64 && !defined(SINGLE_ONLY_FPU)		case fcvtl_op:{			ieee754dp fs;			DPFROMREG(fs, MIPSInst_FS(ir));			rv.l = ieee754dp_tlong(fs);			rfmt = l_fmt;			goto copcsr;		}		case froundl_op:		case ftruncl_op:		case fceill_op:		case ffloorl_op:{			unsigned int oldrm = ieee754_csr.rm;			ieee754dp fs;			DPFROMREG(fs, MIPSInst_FS(ir));			ieee754_csr.rm = ieee_rm[MIPSInst_FUNC(ir) & 0x3];			rv.l = ieee754dp_tlong(fs);			ieee754_csr.rm = oldrm;			rfmt = l_fmt;			goto copcsr;		}#endif /* __mips >= 3 && !fpu(single) */		default:			if (MIPSInst_FUNC(ir) >= fcmp_op) {				unsigned cmpop = MIPSInst_FUNC(ir) - fcmp_op;				ieee754dp fs, ft;				DPFROMREG(fs, MIPSInst_FS(ir));				DPFROMREG(ft, MIPSInst_FT(ir));				rv.w = ieee754dp_cmp(fs, ft,					cmptab[cmpop & 0x7], cmpop & 0x8);				rfmt = -1;				if ((cmpop & 0x8)					&&					ieee754_cxtest					(IEEE754_INVALID_OPERATION))					rcsr = FPU_CSR_INV_X | FPU_CSR_INV_S;				else					goto copcsr;			}			else {				return SIGILL;			}			break;		}		break;	}#endif /* ifndef SINGLE_ONLY_FPU */	case w_fmt:{		ieee754sp fs;		switch (MIPSInst_FUNC(ir)) {		case fcvts_op:			/* convert word to single precision real */			SPFROMREG(fs, MIPSInst_FS(ir));			rv.s = ieee754sp_fint(fs.bits);			rfmt = s_fmt;			goto copcsr;#ifndef SINGLE_ONLY_FPU		case fcvtd_op:			/* convert word to double precision real */			SPFROMREG(fs, MIPSInst_FS(ir));			rv.d = ieee754dp_fint(fs.bits);			rfmt = d_fmt;			goto copcsr;#endif		default:			return SIGILL;		}		break;	}#if __mips64 && !defined(SINGLE_ONLY_FPU)	case l_fmt:{		switch (MIPSInst_FUNC(ir)) {		case fcvts_op:			/* convert long to single precision real */			rv.s = ieee754sp_flong(ctx->fpr[MIPSInst_FS(ir)]);			rfmt = s_fmt;			goto copcsr;		case fcvtd_op:			/* convert long to double precision real */			rv.d = ieee754dp_flong(ctx->fpr[MIPSInst_FS(ir)]);			rfmt = d_fmt;			goto copcsr;		default:			return SIGILL;		}		break;	}#endif	default:		return SIGILL;	}	/*	 * Update the fpu CSR register for this operation.	 * If an exception is required, generate a tidy SIGFPE exception,	 * without updating the result register.	 * Note: cause exception bits do not accumulate, they are rewritten	 * for each op; only the flag/sticky bits accumulate.	 */	ctx->fcr31 = (ctx->fcr31 & ~FPU_CSR_ALL_X) | rcsr;	if ((ctx->fcr31 >> 5) & ctx->fcr31 & FPU_CSR_ALL_E) {		/*printk ("SIGFPE: fpu csr = %08x\n",ctx->fcr31); */		return SIGFPE;	}	/*	 * Now we can safely write the result back to the register file.	 */	switch (rfmt) {	case -1:{#if __mips >= 4		cond = fpucondbit[MIPSInst_FD(ir) >> 2];#else		cond = FPU_CSR_COND;#endif		if (rv.w)			ctx->fcr31 |= cond;		else			ctx->fcr31 &= ~cond;		break;	}#ifndef SINGLE_ONLY_FPU	case d_fmt:		DPTOREG(rv.d, MIPSInst_FD(ir));		break;#endif	case s_fmt:		SPTOREG(rv.s, MIPSInst_FD(ir));		break;	case w_fmt:		SITOREG(rv.w, MIPSInst_FD(ir));		break;#if __mips64 && !defined(SINGLE_ONLY_FPU)	case l_fmt:		DITOREG(rv.l, MIPSInst_FD(ir));		break;#endif	default:		return SIGILL;	}	return 0;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/766160c29fadbafad1d6eb5e965922c7e78beb88/cp1emu.c/buggy/arch/mips/math-emu/cp1emu.c