⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fpe.c

📁 早期freebsd实现
💻 C
字号:
/*- * Copyright (c) 1985 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Computer Consoles Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)fpe.c	7.1 (Berkeley) 12/6/90 */#include "../include/psl.h"#include "../include/reg.h"#include "../include/pte.h"#include "../include/mtpr.h"#include "../math/Kfp.h"#include "sys/param.h"#include "sys/systm.h"#include "sys/user.h"#include "sys/proc.h"#include "sys/seg.h"#include "sys/acct.h"#include "sys/kernel.h"/* * Floating point emulation support. */extern	float Kcvtlf(), Kaddf(), Ksubf(), Kmulf(), Kdivf();extern	double Kcvtld(), Kaddd(), Ksubd(), Kmuld(), Kdivd();extern	float Ksinf(), Kcosf(), Katanf(), Klogf(), Ksqrtf(), Kexpf();#define	OP(dop)		((dop) &~ 01)	/* precision-less version of opcode */#define	isdouble(op)	((op) & 01)	/* is opcode double or float */struct	fpetab {	int	fpe_op;		/* base opcode emulating */	float	(*fpe_ffunc)();	/* float version of op */	double	(*fpe_dfunc)();	/* double version of op */} fpetab[] = {	{ OP(CVLD),	Kcvtlf,	Kcvtld },	{ OP(ADDD),	Kaddf,	Kaddd },	{ OP(SUBD),	Ksubf,	Ksubd },	{ OP(MULD),	Kmulf,	Kmuld },	{ OP(DIVD),	Kdivf,	Kdivd },	{ SINF,		Ksinf,	0 },	{ COSF,		Kcosf,	0 },	{ ATANF,	Katanf,	0 },	{ LOGF,		Klogf,	0 },	{ SQRTF,	Ksqrtf,	0 },	{ EXPF,		Kexpf,	0 },};#define	NFPETAB	(sizeof (fpetab) / sizeof (fpetab[0]))/* * Emulate the FP opcode. Update psl as necessary. * If OK, set opcode to 0, else to the FP exception #. * Not all parameter longwords are relevant, depends on opcode. * * The entry mask is set by locore.s so ALL registers are saved. * This enables FP opcodes to change user registers on return. *//* WARNING!!!! THIS CODE MUST NOT PRODUCE ANY FLOATING POINT EXCEPTIONS *//*ARGSUSED*/fpemulate(hfsreg, acc_most, acc_least, dbl, op_most, op_least, opcode, pc, psl){	int r0, r1;			/* must reserve space */	register int *locr0 = ((int *)&psl)-PS;	register struct fpetab *fp;	int hfs = 0; 			/* returned data about exceptions */	int type;			/* opcode type, FLOAT or DOUBLE */	union { float ff; int fi; } f_res;	union { double dd; int di[2]; } d_res;	int error = 0;#ifdef lint	r0 = 0; r0 = r0; r1 = 0; r1 = r1;#endif	type = isdouble(opcode) ? DOUBLE : FLOAT;	for (fp = fpetab; fp < &fpetab[NFPETAB]; fp++)		if ((opcode & 0xfe) == fp->fpe_op)			break;	if (type == DOUBLE) {		if (fp->fpe_dfunc == 0)			fp = &fpetab[NFPETAB];		else			locr0[PS] &= ~PSL_DBL;	}	if (fp >= &fpetab[NFPETAB]) {		opcode = DIV0_EXC;	/* generate SIGILL - XXX */		return (0);	}	switch (type) {	case DOUBLE:		d_res.dd = (*fp->fpe_dfunc)(acc_most, acc_least, op_most,		    op_least, &hfs);		if (d_res.di[0] == 0 && d_res.di[1] == 0)			locr0[PS] |= PSL_Z;		if (d_res.di[0] < 0)			locr0[PS] |= PSL_N;		break;	case FLOAT:		f_res.ff = (*fp->fpe_ffunc)(acc_most, acc_least, op_most,		    op_least, &hfs);		if (f_res.fi == 0)			locr0[PS] |= PSL_Z;		if (f_res.fi ==  0)			locr0[PS] |= PSL_N;		break;	}	if (hfs & HFS_OVF) {		locr0[PS] |= PSL_V;	/* turn on overflow bit */#ifdef notdef		if (locr0[PS] & PSL_IV)   {  /* overflow enabled? */#endif			opcode = OVF_EXC;			return ((hfs & HFS_DOM) ? EDOM : ERANGE);#ifdef notdef		}#endif	} else if (hfs & HFS_UNDF) {		if (locr0[PS] &  PSL_FU) {  /* underflow enabled? */			opcode = UNDF_EXC;			return ((hfs & HFS_DOM) ? EDOM : ERANGE);		} 	} else if (hfs & HFS_DIVZ) {		opcode = DIV0_EXC;		return (0);	} else if (hfs & HFS_DOM)		error = EDOM;	else if (hfs & HFS_RANGE)		error = ERANGE;	switch (type) {	case DOUBLE:		if (hfs & (HFS_OVF|HFS_UNDF)) {			d_res.dd = 0.0;			locr0[PS] |= PSL_Z;		}		mvtodacc(d_res.di[0], d_res.di[1], &acc_most);		break;	case FLOAT:		if (hfs & (HFS_OVF|HFS_UNDF)) {			f_res.ff = 0.0;			locr0[PS] |= PSL_Z;		}		mvtofacc(f_res.ff, &acc_most);		break;	}	opcode = 0;	return (error);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -