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

📄 pack.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifdef sccsidstatic char     sccsid[] = "@(#)pack.c 1.1 92/07/30 SMI";#endif/* * Copyright (c) 1988 by Sun Microsystems, Inc. *//* Pack procedures for Sparc FPU simulator. */#include <machine/fpu/fpu_simulator.h>#include <machine/fpu/globals.h>/* * Returns 1 if overflow should go to infinity, 0 if to max finite. */PRIVATE intoverflow_to_infinity(pfpsd, sign)	fp_simd_type	*pfpsd;		/* Pointer to simulator data */	int		sign;{	int		inf;	switch (pfpsd->fp_direction) {	case fp_nearest:		inf = 1;		break;	case fp_tozero:		inf = 0;		break;	case fp_positive:		inf = !sign;		break;	case fp_negative:		inf = sign;		break;	}	return (inf);}/* * Round according to current rounding mode. */PRIVATE voidround(pfpsd, pu)	register fp_simd_type	*pfpsd;	/* Pointer to simulator data */	register unpacked	*pu;{	int		increment;	/* boolean to indicate round up */	int		sr;	sr = pu->sticky|pu->rounded;	if (sr == 0)		return;	fpu_set_exception(pfpsd, fp_inexact);	switch (pfpsd->fp_direction) {	case fp_nearest:		increment = pu->rounded;		break;	case fp_tozero:		increment = 0;		break;	case fp_positive:		increment = (pu->sign == 0) & (sr != 0);		break;	case fp_negative:		increment = (pu->sign != 0) & (sr != 0);		break;	}	if (increment) {	    pu->significand[3]++;	    if (pu->significand[3] == 0) {		pu->significand[2]++;		if (pu->significand[2] == 0) {		    pu->significand[1]++;		    if (pu->significand[1] == 0) {			pu->significand[0]++;	/* rounding carried out */			if (pu->significand[0] == 0x20000) {			    pu->exponent++;			    pu->significand[0] = 0x10000;			}		    }		}	    }	}	if ((pfpsd->fp_direction == fp_nearest) &&	    (pu->sticky == 0) && increment!=0) {	/* ambiguous case */		pu->significand[3] &= 0xfffffffe; /* force round to even */	}}PRIVATE voidpackinteger(pfpsd, pu, px)	fp_simd_type	*pfpsd;	/* Pointer to simulator data */	unpacked	*pu;	/* unpacked result */	int		*px;	/* packed integer */{	switch (pu->fpclass) {	case fp_zero:		*px = 0;		break;	case fp_normal:		if (pu->exponent >= 32)			goto overflow;		fpu_rightshift(pu, 112 - pu->exponent);		round(pfpsd, pu);		if (pu->significand[3] >= 0x80000000)			if ((pu->sign == 0)||(pu->significand[3] > 0x80000000))				goto overflow;		*px = pu->significand[3];		if (pu->sign)			*px = -*px;		break;	case fp_infinity:	case fp_quiet:	case fp_signaling:overflow:		if (pu->sign)			*px = 0x80000000;		else			*px = 0x7fffffff;		pfpsd->fp_current_exceptions &= ~(1 << (int) fp_inexact);		fpu_set_exception(pfpsd, fp_invalid);		break;	}}PRIVATE voidpacksingle(pfpsd, pu, px)	fp_simd_type	*pfpsd;	/* Pointer to simulator data */	unpacked	*pu;	/* unpacked result */	single_type	*px;	/* packed single */{	px->sign = pu->sign;	switch (pu->fpclass) {	case fp_zero:		px->exponent = 0;		px->significand = 0;		break;	case fp_infinity:infinity:		px->exponent = 0xff;		px->significand = 0;		break;	case fp_quiet:	case fp_signaling:		fpu_rightshift(pu, 113-24);		px->exponent = 0xff;		px->significand = 0x400000|(0x3fffff&pu->significand[3]);		break;	case fp_normal:		fpu_rightshift(pu, 113-24);		pu->exponent += SINGLE_BIAS;		if (pu->exponent <= 0) {			px->exponent = 0;			fpu_rightshift(pu, 1 - pu->exponent);			round(pfpsd, pu);			if (pu->significand[3] == 0x800000) {	/*								 * rounded								 * back up to								 * normal								 */				px->exponent = 1;				px->significand = 0;				fpu_set_exception(pfpsd, fp_inexact);			} else				px->significand = 0x7fffff & pu->significand[3];			if (pfpsd->fp_current_exceptions & (1 << fp_inexact))				fpu_set_exception(pfpsd, fp_underflow);			if (pfpsd->fp_fsrtem & (1<<fp_underflow)) {				fpu_set_exception(pfpsd, fp_underflow);				pfpsd->fp_current_exceptions &=						~(1 << (int) fp_inexact);			}			return;		}		round(pfpsd, pu);		if (pu->significand[3] == 0x1000000) {	/* rounding overflow */			pu->significand[3] = 0x800000;			pu->exponent += 1;		}		if (pu->exponent >= 0xff) {			fpu_set_exception(pfpsd, fp_overflow);			fpu_set_exception(pfpsd, fp_inexact);			if (pfpsd->fp_fsrtem & (1<<fp_overflow)) {				pfpsd->fp_current_exceptions &=						~(1 << (int) fp_inexact);			}			if (overflow_to_infinity(pfpsd, pu->sign))				goto infinity;			px->exponent = 0xfe;			px->significand = 0x7fffff;			return;		}		px->exponent = pu->exponent;		px->significand = 0x7fffff & pu->significand[3];	}}PRIVATE voidpackdouble(pfpsd, pu, px, py)	fp_simd_type	*pfpsd;	/* Pointer to simulator data */	unpacked	*pu;	/* unpacked result */	double_type	*px;	/* packed double */	unsigned	*py;{	px->sign = pu->sign;	switch (pu->fpclass) {	case fp_zero:		px->exponent = 0;		px->significand = 0;		*py = 0;		break;	case fp_infinity:infinity:		px->exponent = 0x7ff;		px->significand = 0;		*py = 0;		break;	case fp_quiet:	case fp_signaling:		fpu_rightshift(pu, 113-53);		px->exponent = 0x7ff;		px->significand = 0x80000 | (0x7ffff & pu->significand[2]);		*py = pu->significand[3];		break;	case fp_normal:		fpu_rightshift(pu, 113-53);		pu->exponent += DOUBLE_BIAS;		if (pu->exponent <= 0) {	/* underflow */			px->exponent = 0;			fpu_rightshift(pu, 1 - pu->exponent);			round(pfpsd, pu);			if (pu->significand[2] == 0x100000) {	/*								 * rounded								 * back up to								 * normal								 */				px->exponent = 1;				px->significand = 0;				*py = 0;				fpu_set_exception(pfpsd, fp_inexact);			} else {				px->exponent = 0;				px->significand = 0xfffff & pu->significand[2];				*py = pu->significand[3];			}			if (pfpsd->fp_current_exceptions & (1 << fp_inexact))				fpu_set_exception(pfpsd, fp_underflow);			if (pfpsd->fp_fsrtem & (1<<fp_underflow)) {				fpu_set_exception(pfpsd, fp_underflow);				pfpsd->fp_current_exceptions &=						~(1 << (int) fp_inexact);			}			return;		}		round(pfpsd, pu);		if (pu->significand[2] == 0x200000) {	/* rounding overflow */			pu->significand[2] = 0x100000;			pu->exponent += 1;		}		if (pu->exponent >= 0x7ff) {	/* overflow */			fpu_set_exception(pfpsd, fp_overflow);			fpu_set_exception(pfpsd, fp_inexact);			if (pfpsd->fp_fsrtem & (1<<fp_overflow)) {				pfpsd->fp_current_exceptions &=						~(1 << (int) fp_inexact);			}			if (overflow_to_infinity(pfpsd, pu->sign))				goto infinity;			px->exponent = 0x7fe;			px->significand = 0xfffff;			*py = 0xffffffff;			return;		}		px->exponent = pu->exponent;		px->significand = 0xfffff & pu->significand[2];		*py = pu->significand[3];		break;	}}PRIVATE voidpackextended(pfpsd, pu, px, py, pz, pw)	fp_simd_type	*pfpsd;	/* Pointer to simulator data */	unpacked	*pu;	/* unpacked result */	extended_type	*px;	/* packed extended */	unsigned	*py, *pz, *pw;{	px->sign = pu->sign;	switch (pu->fpclass) {	case fp_zero:		px->exponent = 0;		px->significand = 0;		*pz = 0;		*py = 0;		*pw = 0;		break;	case fp_infinity:infinity:		px->exponent = 0x7fff;		px->significand = 0;		*pz = 0;		*py = 0;		*pw = 0;		break;	case fp_quiet:	case fp_signaling:		px->exponent = 0x7fff;		px->significand = 0x8000 | pu->significand[0];	/*								 * Insure quiet								 * nan.								 */		*py = pu->significand[1];		*pz = pu->significand[2];		*pw = pu->significand[3];		break;	case fp_normal:		pu->exponent += EXTENDED_BIAS;		if (pu->exponent <= 0) {	/* underflow */			fpu_rightshift(pu, 1-pu->exponent);			round(pfpsd, pu);			if (pu->significand[0] < 0x00010000) {	/*								 * not rounded								 * back up								 * to normal								 */				px->exponent = 0;			} else {				px->exponent = 1;				fpu_set_exception(pfpsd, fp_inexact);			}			if (pfpsd->fp_current_exceptions & (1 << fp_inexact))				fpu_set_exception(pfpsd, fp_underflow);			if (pfpsd->fp_fsrtem & (1<<fp_underflow)) {				fpu_set_exception(pfpsd, fp_underflow);				pfpsd->fp_current_exceptions &=						~(1 << (int) fp_inexact);			}			px->significand = pu->significand[0];			*py = pu->significand[1];			*pz = pu->significand[2];			*pw = pu->significand[3];			return;		}		round(pfpsd, pu); /* rounding overflow handled in round() */		if (pu->exponent >= 0x7fff) {	/* overflow */			fpu_set_exception(pfpsd, fp_overflow);			fpu_set_exception(pfpsd, fp_inexact);			if (pfpsd->fp_fsrtem & (1<<fp_overflow)) {				pfpsd->fp_current_exceptions &=						~(1 << (int) fp_inexact);			}			if (overflow_to_infinity(pfpsd, pu->sign))				goto infinity;			px->exponent = 0x7ffe;	/* overflow to max norm */			px->significand = 0xffff;			*py = 0xffffffff;			*pz = 0xffffffff;			*pw = 0xffffffff;			return;		}		px->exponent = pu->exponent;		px->significand = pu->significand[0];		*py = pu->significand[1];		*pz = pu->significand[2];		*pw = pu->significand[3];		break;	}}void_fp_pack(pfpsd, pu, n, type)	fp_simd_type	*pfpsd;	/* Pointer to simulator data */	unpacked	*pu;	/* unpacked operand */	unsigned	n;	/* register where datum starts */	enum fp_op_type type;	/* type of datum */{	switch (type) {	case fp_op_integer:		{			int		x;			packinteger(pfpsd, pu, &x);			if (!(pfpsd->fp_current_exceptions & pfpsd->fp_fsrtem))				pfpsd->fp_current_write_freg(&x, n, pfpsd);			break;		}	case fp_op_single:		{			single_type	x;			packsingle(pfpsd, pu, &x);			if (!(pfpsd->fp_current_exceptions & pfpsd->fp_fsrtem))				pfpsd->fp_current_write_freg(&x, n, pfpsd);			break;		}	case fp_op_double:		{			double_type	x;			unsigned	y;			packdouble(pfpsd, pu, &x, &y);			if (!(pfpsd->fp_current_exceptions &			    pfpsd->fp_fsrtem)) {				pfpsd->fp_current_write_freg(&x, DOUBLE_E(n),								pfpsd);				pfpsd->fp_current_write_freg(&y, DOUBLE_F(n),								pfpsd);			}			break;		}	case fp_op_extended:		{			extended_type	x;			unsigned	y, z, w;			unpacked	U;			int		k;			switch (pfpsd->fp_precision) {	/*							 * Implement extended							 * rounding precision							 * mode.							 */			case fp_single:				{					single_type	tx;					packsingle(pfpsd, pu, &tx);					pu = &U;					unpacksingle(pfpsd, pu, tx);					break;				}			case fp_double:				{					double_type	tx;					unsigned	ty;					packdouble(pfpsd, pu, &tx, &ty);					pu = &U;					unpackdouble(pfpsd, pu, tx, ty);					break;				}			case fp_precision_3:	/* rounded to 64 bits */				{					k = pu->exponent + EXTENDED_BIAS;					if (k>=0) k = 113-64;					else	k = 113-64-k;					fpu_rightshift(pu, 113-64);					round(pfpsd, pu);					pu->sticky=pu->rounded=0;					pu->exponent += k;					fpu_normalize(pu);					break;				}			}			packextended(pfpsd, pu, &x, &y, &z, &w);			if (!(pfpsd->fp_current_exceptions &			    pfpsd->fp_fsrtem)) {				pfpsd->fp_current_write_freg(&x, EXTENDED_E(n),								pfpsd);				pfpsd->fp_current_write_freg(&y, EXTENDED_F(n),								pfpsd);				pfpsd->fp_current_write_freg(&z, EXTENDED_G(n),								pfpsd);				pfpsd->fp_current_write_freg(&w, EXTENDED_H(n),								pfpsd);			}			break;		}	}}void_fp_pack_word(pfpsd, pu, n)	fp_simd_type	*pfpsd;	/* Pointer to simulator data */	unsigned	*pu;	/* unpacked operand */	unsigned	n;	/* register where datum starts */{	pfpsd->fp_current_write_freg(pu, n, pfpsd);}

⌨️ 快捷键说明

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