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

📄 _qfpack.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifdef sccsidstatic char     sccsid[] = "@(#)_Qfpack.c 1.1 92/07/30 SMI";#endif/* * Copyright (c) 1988 by Sun Microsystems, Inc. *//* Pack procedures for Sparc FPU simulator. */#include "_Qquad.h"#include "_Qglobals.h"PRIVATE intoverflow_to_infinity(sign)	int             sign;/* Returns 1 if overflow should go to infinity, 0 if to max finite. */{	int             inf;	switch (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);}PRIVATE voidround(pu)	unpacked       *pu;/* Round according to current rounding mode.	 */{	int             increment;	/* boolean to indicate round up */	int sr;	sr = pu->sticky|pu->rounded;	if (sr == 0)		return;	fpu_set_exception(fp_inexact);	switch (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 ((fp_direction == fp_nearest) && 		(pu->sticky == 0) && increment!=0) {	/* ambiguous case */		pu->significand[3] &= 0xfffffffe;	/* force round to even */	}}PRIVATE voidpackinteger(pu, px)	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(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;		_fp_current_exceptions &= ~(1 << (int) fp_inexact);		fpu_set_exception(fp_invalid);		break;	}}PRIVATE voidpacksingle(pu, px)	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(pu);			if (pu->significand[3] == 0x800000) {	/* rounded								 * back up to								 * normal */				px->exponent = 1;				px->significand = 0;				return;			}			if (_fp_current_exceptions & (1 << fp_inexact))				fpu_set_exception(fp_underflow);			px->significand = 0x7fffff & pu->significand[3];			return;		}		round(pu);		if (pu->significand[3] == 0x1000000) {	/* rounding overflow */			pu->significand[3] = 0x800000;			pu->exponent += 1;		}		if (pu->exponent >= 0xff) {			fpu_set_exception(fp_overflow);			fpu_set_exception(fp_inexact);			if (overflow_to_infinity(pu->sign))				goto infinity;			px->exponent = 0xfe;			px->significand = 0x7fffff;			return;		}		px->exponent = pu->exponent;		px->significand = 0x7fffff & pu->significand[3];	}}PRIVATE voidpackdouble(pu, px, py)	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(pu);			if (pu->significand[2] == 0x100000) {	/* rounded 								 * back up to								 * normal */				px->exponent = 1;				px->significand = 0;				*py = 0;				return;			}			if (_fp_current_exceptions & (1 << fp_inexact))				fpu_set_exception(fp_underflow);			px->exponent = 0;			px->significand = 0xfffff & pu->significand[2];			*py = pu->significand[3];			return;		}		round(pu);		if (pu->significand[2] == 0x200000) {	/* rounding overflow */			pu->significand[2] = 0x100000;			pu->exponent += 1;		}		if (pu->exponent >= 0x7ff) {	/* overflow */			fpu_set_exception(fp_overflow);			fpu_set_exception(fp_inexact);			if (overflow_to_infinity(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(pu, px, py, pz, pw)	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(pu);			if (pu->significand[0] < 0x00010000) {	/* not rounded 								 * back up								 * to normal */				if (_fp_current_exceptions & (1 << fp_inexact))					fpu_set_exception(fp_underflow);				px->exponent = 0;			} else				px->exponent = 1;			px->significand = pu->significand[0];			*py = pu->significand[1];			*pz = pu->significand[2];			*pw = pu->significand[3];			return;		}		round(pu);	/* rounding overflow handled in round() */		if (pu->exponent >= 0x7fff) {	/* overflow */			fpu_set_exception(fp_overflow);			fpu_set_exception(fp_inexact);			if (overflow_to_infinity(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(pu, n, type)	unpacked       *pu;	/* unpacked operand */	int 		*n;	/* output result's address */	enum fp_op_type type;	/* type of datum */{	switch (type) {	case fp_op_integer:		{			packinteger(pu, n);			break;		}	case fp_op_single:		{			single_type     x;			packsingle(pu, &x);			n[0] = *(int*)&x;			break;		}	case fp_op_double:		{			double_type     x;			double		t=1.0;			int		i0,i1;			if((*(int*)&t)!=0) {i0=0;i1=1;} else {i0=1;i1=0;}			packdouble(pu, &x,&n[i1]);			n[i0] = *(int*)&x;			break;		}	case fp_op_extended:		{			extended_type   x;			unsigned        y, z, w;			unpacked        u;			int		k;			switch (fp_precision) {	/* Implement extended						 * rounding precision mode. */			case fp_single:				{					single_type     tx;					packsingle(pu, &tx);					pu = &u;					unpacksingle(pu, tx);					break;				}			case fp_double:				{					double_type     tx;					unsigned        ty;					packdouble(pu, &tx, &ty);					pu = &u;					unpackdouble(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(pu);					pu->sticky=pu->rounded=0;					pu->exponent += k;					fpu_normalize(pu);					break;				}			}			{			int		i0,i1,i2,i3;			double t = 1.0;			if((*(int*)&t)!=0) {i0=0;i1=1;i2=2;i3=3;}			else {i0=3;i1=2;i2=1;i3=0;}			packextended(pu, &x, &n[i1], &n[i2], &n[i3]);			n[i0] = *(int*)&x;			}			break;		}	}}

⌨️ 快捷键说明

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