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

📄 fpa3x_dev.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
 *       reg2 uses data register 1 thru 29, and holds value 2; *       reg3 uses data register 2 thru 30, and holds value 8; *       reg4 uses data register 3 thru 31, and holds value 4. */pointer_cmdreg(){	register u_int r1, r2, r3, r4, data, dreg;	u_int ms, ls, ms_exp, ls_exp;	/* single precision command register test */	for (r1=0, r2=1, r3=2, r4=3; r4<FPA_NDATA_REGS; r1++, r2++, r3++, r4++)	{		/* clear all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)			if (write_datareg(dreg,SZERO,SZERO)) return;		/* load register value and execute instruction */		if (write_datareg(r2,STWO,SZERO)) return;		if (write_datareg(r3,SEIGHT,SZERO)) return;		if (write_datareg(r4,SFOUR,SZERO)) return;		data = C_REG4(r4) | C_REG3(r3) | C_REG2(r2) | C_REG1(r1);		if (write_fpa((u_int *)CSP_R1_R3aR2xR4,data,ON)) return;		/* read to check all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)		{			if (read_datareg(dreg,&ms,&ls)) return;			ms_exp = (dreg == r1) ? SSIXTEEN :				 (dreg == r2) ? STWO     :				 (dreg == r3) ? SEIGHT   :				 (dreg == r4) ? SFOUR    : SZERO;			ls_exp = SZERO;			if (ms != ms_exp || ls != ls_exp)				send_message(FPERR,ERROR,er_pointer,dreg,ms_exp,ls_exp,ms,ls);    		}	}	/* double precision command register */	for (r1=0, r2=1, r3=2, r4=3; r4<FPA_NDATA_REGS; r1++, r2++, r3++, r4++)	{		/* clear all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)			if (write_datareg(dreg,DZERO_M,DZERO_L)) return;		/* load register value and execute instruction */		if (write_datareg(r2,DTWO_M,DTWO_L)) return;		if (write_datareg(r3,DEIGHT_M,DEIGHT_L)) return;		if (write_datareg(r4,DFOUR_M,DFOUR_L)) return;		data = C_REG4(r4) | C_REG3(r3) | C_REG2(r2) | C_REG1(r1);		if (write_fpa((u_int *)CDP_R1_R3aR2xR4,data,ON)) return;		/* read to check all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)		{			if (read_datareg(dreg,&ms,&ls)) return;			ms_exp = (dreg == r1) ? DSIXTEEN_M :				 (dreg == r2) ? DTWO_M     :				 (dreg == r3) ? DEIGHT_M   :				 (dreg == r4) ? DFOUR_M    : DZERO_M;			ls_exp = DZERO_L;			if (ms != ms_exp || ls != ls_exp)				send_message(FPERR,ERROR,er_pointer,dreg,ms_exp,ls_exp,ms,ls);    		}	}}/* * Function to test the pointers increment decrement using the command * register instructions. * For single precision, it uses the operation transpose 4x4 matrix. * Where reg1 starts from data register 0 thru 15. *	Original Matrix		===>	    Transpose Matrix * 	   0  1  2  3				0  4  8  C *	   4  5  6  7				1  5  9  D *	   8  9  A  B				2  6  A  E *	   C  D  E  F				3  7  B  F * For double precision, it uses the operation: *   reg1 = (reg2*reg3)+(reg2+1)*(reg3+1)+(reg2+2)*(reg3+2)+(reg2+3)*(reg3+3) * Where reg1 uses data register 0 thru 29, and should hold the result 40; *	 reg2 uses data register 1 thru 30, and holds value 1; *	 reg3 uses data register 2 thru 31, and holds value 2; *	 reg3+1 holds value 3; *	 reg3+2 holds value 4; *	 reg3+3 holds value 5; */pointer_incdec(){	register u_int r1, r2, r3, data, dreg;	u_int ms, ls, ms_exp, ls_exp;	/* single precision command register matrix 4x4 transpose test */	for (r1 = 0; r1 < FPA_NSHORT_REGS; r1++)	{		/* fill all data regs with 0xFF */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)			if (write_datareg(dreg,0xFF,0xFF)) return;				/* set up 4x4 matrix start at reg1 */		for (dreg = 0; dreg < 16; dreg++)			if (write_datareg(dreg+r1,dreg,0xFF)) return;		/* execute instruction */		data = C_REG1(r1);		if (write_fpa((u_int *)CSP_TRANS4x4,data,ON)) return;		/* read to check all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)		{			if (read_datareg(dreg,&ms,&ls)) return;			ms_exp = ls_exp = 0xFF;			if (r1 <= dreg && dreg <= (r1+15))			{				ms_exp = dreg - r1;				ms_exp = (ms_exp % 4) * 4 + (ms_exp / 4);			}			if (ms != ms_exp || ls != ls_exp)				send_message(FPERR,ERROR,er_pointer,dreg,ms_exp,ls_exp,ms,ls);    		}	}	/* double precision command register dot product test */	for (r1=0, r2=1, r3=2; r3<(FPA_NDATA_REGS-3); r1++, r2++, r3++)	{		/* clear all data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)			if (write_datareg(dreg,DZERO_M,DZERO_L)) return;		/* load register value and execute instruction */		if (write_datareg(r2,DONE_M,DONE_L)) return;		if (write_datareg(r3,DTWO_M,DTWO_L)) return;		if (write_datareg(r3+1,DTHREE_M,DTHREE_L)) return;		if (write_datareg(r3+2,DFOUR_M,DFOUR_L)) return;		if (write_datareg(r3+3,DFIVE_M,DFIVE_L)) return;		data = C_REG3(r3) | C_REG2(r2) | C_REG1(r1);		if (write_fpa((u_int *)CDP_DOTPROD,data,ON)) return;		/* read to check data registers */		for (dreg = 0; dreg < FPA_NDATA_REGS; dreg++)		{			if (read_datareg(dreg,&ms,&ls)) return;			ms_exp = (dreg == r1) ? DFORTY_M :				 (dreg == r2) ? DONE_M   :				 (dreg == r3) ? DTWO_M   :				 (dreg == (r3+1)) ? DTHREE_M :				 (dreg == (r3+2)) ? DFOUR_M  :				 (dreg == (r3+3)) ? DFIVE_M  : DZERO_M;			ls_exp = DZERO_L;			if (ms != ms_exp || ls != ls_exp)				send_message(FPERR,ERROR,er_pointer,dreg,ms_exp,ls_exp,ms,ls);    		}	}}/* * Function to perform shadow register lock test in both active and * next stages. */lock_test(){	send_message(0,VERBOSE,tst_lock,"short");	lock_short(FALSE);	send_message(0,VERBOSE,tst_lock,"extended");	lock_extend(FALSE);	send_message(0,VERBOSE,tst_lock,"command register");	lock_cmdreg(FALSE);	send_message(0,VERBOSE,tst_lock,"short, next");	lock_short(TRUE);	send_message(0,VERBOSE,tst_lock,"extended, next");	lock_extend(TRUE);	send_message(0,VERBOSE,tst_lock,"command register, next");	lock_cmdreg(TRUE);}/* * Function to perform lock test using single and double short instructions: *	reg1 = reg1 / operand, where reg1 = 1 and operand = 3. * This operation will hang and lock the shadow register assign to reg1. */lock_short(next)register int next;{	register u_int r1, r1_next, inst;	/* enable imask to hang operation */	if (write_fpa(&fpa->fp_imask,FPA_INEXACT,ON)) return;	/* single precision short test */	for (r1 = 0; r1 < FPA_NSHAD_REGS; r1++)	{		if (write_datareg(r1,SONE,SZERO)) return;		if (next)		{			r1_next = (r1 + 1) % FPA_NSHAD_REGS;			if (write_datareg(r1_next,SONE,SZERO)) return;		}		inst = SP_DIVIDE | SP_REG1(r1);		if (write_fpa((u_int *)inst,STHREE,ON)) return;		if (next)		{			inst = SP_DIVIDE | SP_REG1(r1_next);			if (write_fpa((u_int *)inst,STHREE,ON)) return;			check_lock(2,r1,r1_next);		}		else check_lock(1,r1);	}	/* double precision short test */	for (r1 = 0; r1 < FPA_NSHAD_REGS; r1++)	{		if (write_datareg(r1,DONE_M,DONE_L)) return;		if (next)		{			r1_next = (r1 + 1) % FPA_NSHAD_REGS;			if (write_datareg(r1_next,DONE_M,DONE_L)) return;		}		inst = DP_DIVIDE | DP_REG1(r1);		if (write_fpa((u_int *)inst,DTHREE_M,ON)) return;		if (write_fpa((u_int *)DP_LSW,DTHREE_L,ON)) return;		if (next)		{			inst = DP_DIVIDE | DP_REG1(r1_next);			if (write_fpa((u_int *)inst,DTHREE_M,ON)) return;			if (write_fpa((u_int *)DP_LSW,DTHREE_L,ON)) return;			check_lock(2,r1,r1_next);		}		else check_lock(1,r1);	}}/* * Function to perform lock test using single and double extended instruction: *	reg1 = reg2 / operand, where reg2 = 1 and operand = 3. * This operation will hang and lock the shadow register assign to reg1. */lock_extend(next)register int next;{	register u_int r1, r2, r1_next, r2_next, inst;	/* enable imask to hang operation */	if (write_fpa(&fpa->fp_imask,FPA_INEXACT,ON)) return;	/* single precision extended test */	for (r1=0, r2=1; r2 < FPA_NSHAD_REGS; r1++, r2++)	{		if (write_datareg(r2,SONE,SZERO)) return;		if (next)		{			r2_next = (r2 + 1) % FPA_NSHAD_REGS;			r1_next = r1 + 1;			if (write_datareg(r2_next,SONE,SZERO)) return;		}		inst = XSP_DIVIDE | X_REG2(r2);		if (write_fpa((u_int *)inst,STHREE,ON)) return;		inst = X_LSW | X_REG1(r1);		if (write_fpa((u_int *)inst,SZERO,ON)) return;		if (next)		{			inst = XSP_DIVIDE | X_REG2(r2_next);			if (write_fpa((u_int *)inst,STHREE,ON)) return;			inst = X_LSW | X_REG1(r1_next);			if (write_fpa((u_int *)inst,SZERO,ON)) return;			check_lock(2,r1,r1_next);		}		else check_lock(1,r1);	}	/* double precision extended test */	for (r1=0, r2=1; r2 < FPA_NSHAD_REGS; r1++, r2++)	{		if (write_datareg(r2,DONE_M,DONE_L)) return;		if (next)		{			r2_next = (r2 + 1) % FPA_NSHAD_REGS;			r1_next = r1 + 1;			if (write_datareg(r2_next,DONE_M,DONE_L)) return;		}		inst = XDP_DIVIDE | X_REG2(r2);		if (write_fpa((u_int *)inst,DTHREE_M,ON)) return;		inst = X_LSW | X_REG1(r1);		if (write_fpa((u_int *)inst,DTHREE_M,ON)) return;		if (next)		{			inst = XDP_DIVIDE | X_REG2(r2_next);			if (write_fpa((u_int *)inst,DTHREE_M,ON)) return;			inst = X_LSW | X_REG1(r1_next);			if (write_fpa((u_int *)inst,DTHREE_L,ON)) return;			check_lock(2,r1,r1_next);		}		else check_lock(1,r1);	}}/* * Function to perform lock test using Weitek command register instructions: *	1) reg1 = sine(reg2) and reg4 = cosine(reg2), where reg2 = 1. *	2) reg1 = reg2 / reg3, where reg2 = 1 and reg3 = 3. * The first operation will hang and lock all shadow registers. * The second operation will hang and lock the shadow register assign to reg1. */lock_cmdreg(next)register int next;{	register u_int r1, r2, r4, data;	register u_int r1_next, r2_next, r3_next;	/* enable imask to hang operation */	if (write_fpa(&fpa->fp_imask,FPA_INEXACT,ON)) return;	/* single precision command register test */	for (r1=0, r2=1, r4=2; r4 < FPA_NSHAD_REGS; r1++, r2++, r4++)	{		if (write_datareg(r2,SONE,SZERO)) return;		if (next)		{			r3_next = (r4 + 1) % FPA_NSHAD_REGS;			r2_next = r2 + 1;			r1_next = r1 + 1;			if (write_datareg(r2_next,SONE,SZERO)) return;			if (write_datareg(r3_next,STHREE,SZERO)) return;			data = C_REG3(r3_next) | C_REG2(r2_next) | C_REG1(r1_next);			if (write_fpa((u_int *)CWSP_DIVIDE,data,ON)) return;		}		data = C_REG4(r4) | C_REG2(r2) | C_REG1(r1);		if (write_fpa((u_int *)CSP_SINCOS,data,ON)) return;		check_lock(FPA_NSHAD_REGS,0,1,2,3,4,5,6,7);	}	/* double precision command register test */	for (r1=0, r2=1, r4=2; r4 < FPA_NSHAD_REGS; r1++, r2++, r4++)	{		if (write_datareg(r2,DONE_M,DONE_L)) return;		if (next)		{			r3_next = (r4 + 1) % FPA_NSHAD_REGS;			r2_next = r2 + 1;			r1_next = r1 + 1;			if (write_datareg(r2_next,DONE_M,DONE_L)) return;			if (write_datareg(r3_next,DTHREE_M,DTHREE_L)) return;			data = C_REG3(r3_next) | C_REG2(r2_next) | C_REG1(r1_next);			if (write_fpa((u_int *)CWDP_DIVIDE,data,ON)) return;		}		data = C_REG4(r4) | C_REG2(r2) | C_REG1(r1);		if (write_fpa((u_int *)CDP_SINCOS,data,ON)) return;		check_lock(FPA_NSHAD_REGS,0,1,2,3,4,5,6,7);	}}/* * Function to verify that all indicated shadow registers are locked, and * all others are not. * VARARGS. */check_lock(va_alist)va_dcl{	va_list ap;	register int stat, reg, count, lock, n;	u_int shadow[FPA_NSHAD_REGS], *addr, val, ierr_exp;	/* get arguments for all shadow locks */	va_start(ap);	count = va_arg(ap,int);	for (lock = 0; lock < count; lock++)		shadow[lock] = va_arg(ap,u_int);	va_end(ap);	/* verify that each indicated shadow register is locked */	for (reg = 0; reg < FPA_NSHAD_REGS; reg++)	{		/* see if this one is supposed to be locked */		for (lock = 0; lock < count; lock++)			if (shadow[lock] == reg) break;		/* check both most and least significant of register */		addr = (u_int *)&fpa->fp_shad[reg];		for (n = 0; n < 2; n++)		{			stat = read_fpa(addr+n,&val,OFF);			if (lock < count)		/* lock expected */			{				ierr_exp = FPA_HUNG_PIPE;				if (!stat) send_message(FPERR,ERROR,er_nolock,reg);			}			else				/* no lock expected */			{				ierr_exp = 0;				if (stat) send_message(FPERR,ERROR,er_lock,reg);			}			if (read_fpa(&fpa->fp_ierr,&val,ON)) return;			if ((val &= IERR_MASK) != ierr_exp)				send_message(FPERR,ERROR,er_lockierr,ierr_exp,val);			if (write_fpa(&fpa->fp_ierr,0,ON)) return;		}	}	/* clear pipe to unlock */	if (write_fpa(&fpa->fp_clear_pipe,X,ON)) return;}/* * Function to perform jump condition test using command register instructions. */jumpcond_test(){	register u_int data, dreg;	u_int ms, ls, ms_exp;	send_message(0,VERBOSE,tst_jumpcond);	/* assign value to data register 1 thru 7 */	for (dreg = 0; dreg < FPA_NSHAD_REGS; dreg++)		if (write_datareg(dreg,jumpcond[dreg].data,SZERO)) return;	/* execute instructions */	for (dreg = 0; dreg < FPA_NSHAD_REGS; dreg++)	{		data = C_REG2(dreg) | C_REG1(dreg);		if (write_fpa((u_int *)jumpcond[dreg].inst,data,ON)) return;	}	/* read all data registers and check result */	for (dreg = 0; dreg < FPA_NSHAD_REGS; dreg++)	{		if (read_datareg(dreg,&ms,&ls)) return;		ms_exp = jumpcond[dreg].result;		if (ms != ms_exp || ls != SZERO)			send_message(FPERR,ERROR,er_jumpcond,dreg,ms_exp,SZERO,ms,ls);	}}

⌨️ 快捷键说明

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