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

📄 fpa_recompute.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#if !defined(lint) && defined(SCCSIDS)static char     sccsid[] = "@(#)fpa_recompute.c 1.1 92/07/30 SMI";#endif/* * Copyright (c) 1989 by Sun Microsystems, Inc.  */#include <signal.h>#include <stdio.h>#include "fpa_support.h"extern double                fabs();		/* Inline expansion actually takes care of				 * this. */STATICextended_precision()/* Forces extended precision expression evaluation	 */{	int             oldmode, newmode;#ifdef F68881	newmode = 0;	oldmode = Wmode(newmode);	newmode = oldmode & ~0xc0;	/* Force extended */	Wmode(newmode);#endif}STATIC longread_msw(n)	int             n;{				/* read most significant 32 bits of FPA reg n */	long           *fpa_pointer;	fpa_pointer = (long *) (FPABASE + 0xc00 + 8 * n);	return (*fpa_pointer);}STATIC longread_lsw(n)	int             n;{				/* read least significant 32 bits of FPA reg				 * n */	long           *fpa_pointer;	fpa_pointer = (long *) (FPABASE + 0xc04 + 8 * n);	return (*fpa_pointer);}STATIC voidwrite_msw(n, data)	int             n;	long            data;{				/* write most significant 32 bits of FPA reg				 * n */	long           *fpa_pointer;	fpa_pointer = (long *) (FPABASE + 0xc00 + 8 * n);	*fpa_pointer = data;}STATIC voidwrite_lsw(n, data)	int             n;	long            data;{				/* write most significant 32 bits of FPA reg				 * n */	long           *fpa_pointer;	fpa_pointer = (long *) (FPABASE + 0xc04 + 8 * n);	*fpa_pointer = data;}STATIC doubleread_single(n)	int             n;{				/* read FPA register n as single */	union singlekluge k;	union doublekluge dk;	k.i[0] = read_msw(n);	dk.x = (double) k.x;	/*	 * Conversion of single to double causes no exception except possibly	 * converting a signalling NaN to quiet.  The following code undoes	 * that. 	 */	if (Wstatus(0) & 0x80) {/* Wstatus(0) clears fpsr. */		dk.i[0] = dk.i[0] & ~0x00080000;	/* Convert quiet back to							 * signalling. */	}	return (dk.x);}STATIC doubleread_long(n)	int             n;{				/* read FPA register n as long */	union singlekluge k;	k.x = read_msw(n);	return (k.x);}STATIC doubleread_double(n)	int             n;{				/* read FPA register n as double */	union doublekluge k;	k.i[0] = read_msw(n);	k.i[1] = read_lsw(n);	return (k.x);}STATIC voidwrite_long(n, data)	int             n;	double          data;{				/* write FPA register n as long */	union singlekluge k;	k.i[0] = data;	write_msw(n, k.i[0]);}STATIC voidwrite_single(n, data)	int             n;	double          data;{				/* write FPA register n as single */	union singlekluge k;	k.x = data;	write_msw(n, k.i[0]);}STATIC voidwrite_double(n, data)	int             n;	double          data;{				/* write FPA register n as double */	union doublekluge k;	k.x = data;	write_msw(n, k.i[0]);	write_lsw(n, k.i[1]);}STATIC doubleread_2_single(data)	long            data;/* * returns FPA register defined in the reg_2 field of data from command * format.  */{	long           *fpa_pointer;	int             reg_1;	double          reg_1_op, reg_2_op;	reg_1 = data & 0x1f;	reg_1_op = read_single(reg_1);	fpa_pointer = (long *) (FPABASE + 0x880);	*fpa_pointer = data;	/* reg_1 gets reg_2 contents */	reg_2_op = read_single(reg_1);	write_single(reg_1, reg_1_op);	return (reg_2_op);}STATIC doubleread_2_double(data)	long            data;/* * returns FPA register defined in the reg_2 field of data from command * format.  */{	long           *fpa_pointer;	int             reg_1;	double          reg_1_op, reg_2_op;	reg_1 = data & 0x1f;	reg_1_op = read_double(reg_1);	fpa_pointer = (long *) (FPABASE + 0x884);	*fpa_pointer = data;	/* reg_1 gets reg_2 contents */	reg_2_op = read_double(reg_1);	write_double(reg_1, reg_1_op);	return (reg_2_op);}STATIC doubleread_3_single(data)	long            data;/* * returns FPA register defined in the reg_3 field of data from command * format, wiping out reg_1 in the process.  */{	long           *fpa_pointer, reg_1;	double          reg_1_op, reg_2_op;	reg_1 = data & 0x1f;	reg_1_op = read_single(reg_1);	fpa_pointer = (long *) (FPABASE + 0x880);	*fpa_pointer = ((data >> 10) & ~0x1f) | reg_1;	/* reg_1 gets reg_3							 * contents */	reg_2_op = read_single(reg_1);	write_single(reg_1, reg_1_op);	return (reg_2_op);}STATIC doubleread_3_double(data)	long            data;/* * returns FPA register defined in the reg_3 field of data from command * format.  */{	long           *fpa_pointer, reg_1;	double          reg_1_op, reg_2_op;	reg_1 = data & 0x1f;	reg_1_op = read_double(reg_1);	fpa_pointer = (long *) (FPABASE + 0x884);	*fpa_pointer = ((data >> 10) & ~0x1f) | reg_1;	/* reg_1 gets reg_3							 * contents */	reg_2_op = read_double(reg_1);	write_double(reg_1, reg_1_op);	return (reg_2_op);}STATIC doubleread_4_single(data)	long            data;/* * returns FPA register defined in the reg_4 field of data from command * format.  */{	long           *fpa_pointer, reg_1;	double          reg_1_op, reg_2_op;	reg_1 = data & 0x1f;	reg_1_op = read_single(reg_1);	fpa_pointer = (long *) (FPABASE + 0x880);	*fpa_pointer = ((data >> 20) & 0x7c0) | reg_1;	/* reg_1 gets reg_4							 * contents */	reg_2_op = read_single(reg_1);	write_single(reg_1, reg_1_op);	return (reg_2_op);}STATIC doubleread_4_double(data)	long            data;/* * returns FPA register defined in the reg_4 field of data from command * format.  */{	long           *fpa_pointer, reg_1;	double          reg_1_op, reg_2_op;	reg_1 = data & 0x1f;	reg_1_op = read_double(reg_1);	fpa_pointer = (long *) (FPABASE + 0x884);	*fpa_pointer = ((data >> 20) & 0x7c0) | reg_1;	/* reg_1 gets reg_4							 * contents */	reg_2_op = read_double(reg_1);	write_double(reg_1, reg_1_op);	return (reg_2_op);}STATIC voidfpa_compare(x, y, pc)	double          x, y;	unsigned short *pc;/* Procedure to recompute Weitek status for x compare y - always unord. */{	long           *fpa_pointer;	int             i, cc;	/*	 * Following code attempts to determine if compare was for == != or	 * for an ordered comparison < <= > >=.  The way it works is the	 * instruction stream is followed from pc+6 to find a bcc, dbcc, or	 * scc instruction: 	 *	 *	 	fpcmps@1  a0@,fpa2 pc->		fpmove@1  fpastatus,d0 pc+4->         	movw    d0,cc pc+6->         	seq     d0 	 *	 * A bcc looks like 6cXX. A dbcc or scc looks like 5cXX with bits 6 and 7	 * on. 	 *	 * Obviously this code can be fooled so we allow at most 100	 * instructions. 	 *	 * This only matters if... 1) neither operand is a signaling nan 2) the	 * comparison is == or !=. When both conditions hold, IEEE invalid	 * should not be signaled. 	 */	pc = (unsigned short *) ((int) pc + 6);	i = 0;	while (((*pc & 0xf000) != 0x6000) && ((*pc & 0xf0c0) != 0x50c0) && (i < 100)) {		i++;		pc++;	}	if (((*pc & 0xf000) != 0x6000)	    || ((*pc & 0xf0c0) != 0x50c0)) {	/* cc op code found */		cc = (*pc & 0x0f00) >> 8;		if ((cc == 6) || (cc == 7))			cc = (x == y);	/* == or !=, don't signal. */		else			cc = (x >= y);	/* Unordered, always signal. */	} else {		/* no cc op code found */		printf(" no cc op code found \n") ;		cc = x >= y;	/* Assume unordered, always signal. */	}	if (!cc) {		/* cc is always false! But we need to fool				 * the optimizer! */		fpa_pointer = (long *) (FPABASE + 0x958);		*fpa_pointer = 0xf00;	/* Set unordered. */	}}STATIC intshort_single(a1, pc)	struct fpa_access *a1;	unsigned short *pc;/* Procedure to recompute short single format instructions. 	 */{	struct fpa_access ap0;	int             opcode, src, dest, found;	double          reg, operand, result;	union singlekluge sk;	found = 1;	ap0 = *a1;	opcode = ap0.kluge.kis.op;	src = ap0.kluge.kis.reg1;	dest = ap0.kluge.kis.reg1;	reg = read_single(src);	sk.i[0] = ap0.data;	operand = sk.x;	switch (opcode) {	case 1:		result = -(operand);		break;	case 2:		result = fabs(operand);		break;	case 3:		result = sk.i[0];		break;	case 4:		result = fpa_tolong(operand);		write_long(dest, result);		goto pastwrites;	case 5:		result = operand;		write_double(dest, result);		goto pastwrites;	case 6:		result = (float) (operand * operand);		break;	case 7:		result = (float) (reg + operand);		break;	case 8:		result = (float) (reg - operand);		break;	case 9:		result = (float) (reg * operand);		break;	case 10:		result = (float) (reg / operand);		break;	case 11:		result = (float) (operand - reg);		break;	case 12:		result = (float) (operand / reg);		break;	case 13:		fpa_compare(operand, 0.0, pc);		goto pastwrites;	case 14:		fpa_compare(operand, reg, pc);		goto pastwrites;	case 15:		fpa_compare(fabs(operand), fabs(reg), pc);		goto pastwrites;	default:		found = 0;		goto pastwrites;	}	write_single(dest, result);pastwrites:;	if (!found)		fprintf(stderr, "\n Invalid result from failed FPA short single format instruction:\n operand %g reg_1 %g \n", operand, reg);	return (found);}STATIC intshort_double(a1, a2, pc)	struct fpa_access *a1, *a2;	unsigned short *pc;/* Procedure to recompute short double format instructions. 	 */{	struct fpa_access ap0, ap1;	int             opcode, src, dest, found;	double          reg, operand, result;	union doublekluge dk;	found = 1;	ap0 = *a1;	ap1 = *a2;	opcode = ap0.kluge.kis.op;	src = ap0.kluge.kis.reg1;	dest = ap0.kluge.kis.reg1;	reg = read_double(src);	dk.i[0] = ap0.data;	dk.i[1] = ap1.data;	operand = dk.x;	switch (opcode) {	case 1:		result = -(operand);		break;	case 2:		result = fabs(operand);		break;	case 3:		result = dk.i[0];		break;	case 4:		result = fpa_tolong(operand);		write_long(dest, result);		goto pastwrited;	case 5:		result = (double) (float) operand;		write_single(dest, result);		goto pastwrited;	case 6:		result = operand * operand;		break;	case 7:		result = reg + operand;		break;	case 8:		result = reg - operand;		break;	case 9:		result = reg * operand;		break;	case 10:		result = reg / operand;		break;	case 11:		result = operand - reg;		break;	case 12:		result = operand / reg;		break;	case 13:		fpa_compare(operand, 0.0, pc);		goto pastwrited;	case 14:		fpa_compare(operand, reg, pc);		goto pastwrited;	case 15:		fpa_compare(fabs(operand), fabs(reg), pc);		goto pastwrited;	default:		found = 0;		goto pastwrited;	}	write_double(dest, result);pastwrited:	if (!found)		fprintf(stderr, "\n Invalid result from failed FPA short double format instruction:\n operand %g reg_1 %g \n", operand, reg);	return (found);}STATIC intextended_semantics(opcode, reg_1, prec, mem_op, mem_2_op, reg_2_op, reg_3_op)	int             opcode, prec, reg_1;	double          mem_op, mem_2_op, reg_2_op, reg_3_op;{	int             found;	double          result;	complexunion	complex1, complex2, complex3;		double d1, d2;		pdoublekluge pdk;	found = 1;	switch (opcode) {	case 0:		extended_precision();		result = mem_2_op + (reg_2_op * mem_op);		break;	case 1:		extended_precision();		result = mem_2_op - (reg_2_op * mem_op);		break;	case 2:		extended_precision();		result = (reg_2_op * mem_op) - mem_2_op;		break;	case 3:		extended_precision();		result = mem_2_op * (reg_2_op + mem_op);		break;	case 4:		extended_precision();		result = mem_2_op * (reg_2_op - mem_op);		break;	case 5:		extended_precision();		result = mem_2_op * (mem_op - reg_2_op);		break;	case 6:		result = reg_2_op + mem_op;		break;	case 7:		result = reg_2_op - mem_op;		break;	case 8:		result = reg_2_op * mem_op;		break;	case 9:		result = reg_2_op / mem_op;		break;	case 10:		result = mem_op - reg_2_op;		break;	case 11:		result = mem_op / reg_2_op;		break;        case 12: /* sqrt */                result = fpa_transcendental(8, mem_op);                break;        case 13: /* hypot */		extended_precision();                pdk.pd[0] = (double *)&mem_op;		pdk.pd[1] = (double *)&reg_2_op;		result = fpa_transcendental(9, pdk.d);                break;        case 14: /* complex negation */                complex3.d = mem_op;                complex1.f[0] = -complex3.f[0];                complex1.f[1] = -complex3.f[1];                result = complex1.d;                break;        case 15: /* complex absolute value */		extended_precision();                complex3.d = mem_op;                d1=complex3.f[0];		d2=complex3.f[1];                pdk.pd[0] = (double *)&d1;		pdk.pd[1] = (double *)&d2;		result = (double) (float) fpa_transcendental(9, pdk.d);                write_single(reg_1, result);                goto pastwrite;                break;

⌨️ 快捷键说明

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