File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / d / dmp4 / test_mulf.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:30:21 2019 UTC (7 years ago) by root
Branches: bsd, MAIN
CVS tags: v121, HEAD
Power 6/32 Unix version 1.21


/*******************************************************************
* ABSOLUTE ADDRESSING:
*  instruction =  <op-code> <9f> <&dmp_op_1> {<9f> <&dmp_op_2>}
*******************************************************************/
tst_abs()
{
	pipe_test = FALSE;		/* clear the pipe test flag */
	fill_reg_buf( load_regs );	/* set data for registers */
	fill_reg_buf( exp_regs );	/* set data for registers */
	addr_mode = ADR_ABSOLUTE;
	addr_code = addr_code2 = 0x9f;
	addr_size = 4;			/* longword (4 byte) ops. */
	addr_1    = DMP_OP_1;		/* abs. address of data   */
	addr_2    = DMP_OP_2;
	if( no_ops == 2 )
	     min_shift = 6;
	 else 
	     min_shift = 11;
	shift_count = 15;
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 3, 4, 4, 6 );  /* set exp fault cnt  */
	     pack_inst();		/* pack the instr. code   */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 15;
	}
}




  
/*******************************************************************
* LONGWORD DISPLACEMENT RELATIVE DEFERRED ADDRESSING:
*  instruction =  <op-code> <ff> <offset to dmp_op_1>
*                         { <ff> <offset to dmp_op_1> }
*******************************************************************/
tst_l_d()
{
	pipe_test = FALSE;		/* clear the pipe test flag */
	fill_reg_buf( load_regs );	/* set data for registers */
	fill_reg_buf( exp_regs );	/* set data for registers */
	addr_mode = ADR_L_DSP_DEF;
	addr_code = addr_code2 = 0xff;
	addr_size = 4;			/* longword (4 byte) op.  */
	if( no_ops == 2 )
	     min_shift = 6;
	 else 
	     min_shift = 11;
	shift_count = 15; 
	for( index = 0; index <= max_index; index++ )
	{
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 4, 5, 6, 8 );  /* set exp fault cnt  */
	     addr_1 = os_ad_op1 + 10 - shift_count; /* operand offset */
	     addr_2 = os_ad_op2 +  5 - shift_count; 
	     pack_inst();		/* pack the instr. code   */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 15;
	}
}





/*******************************************************************
* AUTO-INCREMENTED STACK POINTER ADDRESSING  ( POP ):  ( sgl ops only )
*  instruction =  <op-code> <8e> 
* 
* The data will be pushed by "run_code"
* Pop will be run with SGL instructions only.
*******************************************************************/
tst_pop()
{
	pipe_test = FALSE;		/* clear the pipe test flag */
	fill_reg_buf( load_regs );	/* set data for registers */
	fill_reg_buf( exp_regs );	/* set data for registers */
	addr_mode = ADR_POP;
	addr_code = addr_code2 = 0x8e;
	addr_size = 0;			/* no addressing bytes    */
	pack_inst();			/* pack the instr. code   */
	if( no_ops == 2 ) {
	     min_shift = 14;
	     exp_page_faults = 4;	/* 4 pages are used       */
	 } else  {
	     min_shift = 15;
	     exp_page_faults = 3;	/* 3 pages are used       */
	}
	shift_count = 15;
	for( index = 0; index <= max_index; index++ )
	{
	     get_current_data( adr_op1, adr_op2 );
	     sgl_value_9 = dbl_value_1.m; /* data to be pushed   */
	     sgl_value_10 = dbl_value_2.m;
	     run_code();		/* execute the instruction */
	     (*test_ptr)();		/* verify the results     */
	     if( force_loop )
		  run_code();		/* start the error loop   */
	     if( --shift_count < min_shift )
		  shift_count = 15;
	}
}






/*******************************************************************
* REGISTER + BYTE DISPLACEMENT ADDRESSING:
*  instruction =  <op-code> <a4> <(&op_1 -r4)>
*                         { <a5> <(&op_2- r5)> }
*******************************************************************/
tst_r_b()
{
	pipe_test = FALSE;		/* clear the pipe test flag */
	fill_reg_buf( load_regs );	/* set data for registers */
	fill_reg_buf( exp_regs );	/* set data for registers */
	addr_mode  = ADR_REG_B;
	addr_code  = 0xa4;		/* addr 1 is offset by r4 */
	addr_code2 = 0xa5;		/* addr 2 is offset by r5 */
	addr_size  = 1;			/* 1 byte operand         */
	addr_1 = 20;			/* set the 1st byte offset */
	addr_2 = 4;			/* set the 2nd byte offset */
	pack_inst();			/* pack the instr. code    */
	load_regs[4] = (int) adr_op1 - 20;  /* get the reg value   */
	load_regs[5] = (int) adr_op2 - 4;
	exp_regs[4] = load_regs[4];
	exp_regs[5] = load_regs[5];
	if( no_ops == 2 )
	     min_shift = 12;
	 else 
	     min_shift = 14;
	 shift_count = 15; 
	 for( index = 0; index <= max_index; index++ )
	 {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 3, 4, 4, 6 );  /* set exp fault cnt  */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 15;
	 }
}




/*******************************************************************
*         INDEXED LONGWORD DISPLACEMENT ADDRESSING:
*  instruction =  <op-code> <44> <ef> <longword offset>
*                         { <45> <ef> <longword offset> }
*******************************************************************/
tst_x_l()
{
	pipe_test = FALSE;		/* clear the pipe test flag */
	fill_reg_buf( load_regs );	/* set data for registers */
	fill_reg_buf( exp_regs );	/* set data for registers */
	addr_mode  = ADR_I_L;
	addr_code  = 0x44;		/* code for reg. 4 index  */
	addr_code2 = 0x45;		/* code for reg. 5 index  */
	addr_codeB = 0xef;		/* code for longword disp */
	addr_size  = 4;			/* longword (4 byte) op.  */
	if( sgl_op )
	{
	     load_regs[4] = 4;		/* reg 4 = 4 (longwords)  */
	     load_regs[5] = 6;		/* reg 5 = 6 (longwords)  */
	} else {
	     load_regs[4] = 2;		/* reg 4 = 2 (quadwords)  */
	     load_regs[5] = 3;		/* reg 5 = 3 (quadwords)  */
	}
	exp_regs[4] = load_regs[4];
	exp_regs[5] = load_regs[5];
	if( no_ops == 2 )
	     min_shift = 4;
	 else 
	     min_shift = 10;
	shift_count = 15; 
	for( index = 0; index <= max_index; index++ )
	{
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 3, 4, 4, 6 );  /* set exp fault cnt    */
	     addr_1 = os_op1 + 9 - shift_count; /* data's offset    */
	     addr_1 -=16;		/*    -16 bytes (2 Q-words) */
	     addr_2 = os_op2 + 3 - shift_count; /* data's offset    */
	     addr_2 -=24;		/*    -24 bytes (3 Q-words) */
	     pack_inst();		/* pack the instr. code     */
	     run_code();		/* execute the instruction  */
	     if( --shift_count < min_shift )
		  shift_count = 15;
	}
}







/*******************************************************************
* PIPELINED TEST #2 -LONGWORD DISPLACEMENT RELATIVE ADDR. WITH A PRE MULTIPLY
*
*  This test will put MULTIPLY instructions immediately in front of and
*  behind the test instruction.
*  The instruction buffer will look like:
*
*  <mulf/muld> <instruction> <mulf/muld> where:
*  instruction =  <op-code> <ef> <offset to dmp_op_1>
*                         { <ef> <offset to dmp_op_2> }
*
*  The 1st multiply's addressing will be indirect through register R6.
*  The 2nd multiply's addressing will be indirect through register R2.
*******************************************************************/
tst_p2()
{
	pipe_test = 2;		/* set the piplined flag to test # 2 */
	if( acc_ld_size == DBL )
	     pipe_inst1 = MULD_OP_CODE;
	else
	     pipe_inst1 = MULF_OP_CODE;
	if( acc_st_size == DBL )
	     pipe_inst2 = MULD_OP_CODE;
	else
	     pipe_inst2 = MULF_OP_CODE;
	fill_reg_buf( load_regs );	/* set data for registers */
	fill_reg_buf( exp_regs );	/* set data for registers */
	load_regs[2] = (int) adr_op3;	/* 2nd MULx is w/ op. #3 */
	exp_regs[2] = load_regs[2];
	load_regs[6] = (int) adr_op4;	/* 1st MULx is w/ op. #4  */
	exp_regs[6] = load_regs[6];
	adr_op3->m = 0x40800000;	/* set the piped mult's   */
	adr_op3->l = 0;			/*    operand = '1.0'     */
	adr_op4->m = 0x40800000;
	adr_op4->l = 0;	
	addr_mode = ADR_L_DSP;
	addr_code = addr_code2 = 0xef;
	addr_size = 4;			/* longword (4 byte) ops. */
	if( no_ops == 2 )
	     min_shift = 2;
	 else
	     min_shift = 7;
	shift_count = 15; 
	for( index = 0; index <= max_index; index++ )
	{
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 5, 6, 6, 8 );  /* set exp fault cnt  */
	     addr_1 = os_op1 +  8 - shift_count; /* data's offset */
	     addr_2 = os_op2 +  3 - shift_count;
	     pack_inst();		/* pack the instr. code   */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 15;
	}
	pipe_test = FALSE;		/* clear the pipe test flag */
}





/*
 ***************************************************************************
 *
 *	GET DATA FOR DOUBLE PRECISION INSTRUCTIONS
 *
 ***************************************************************************
*/
get_current_data( dptr_1, dptr_2 )
struct u64 *dptr_1;				/* pointer to 1st operand */
struct u64 *dptr_2;				/* pointer to 2nd operand */
{
	if( no_ops == 2 )
	{
	     dbl_ld_acc   = ldd_data[ index +1 ].op_1;
	     dbl_value_1  = data_ptr[ index ].op_1;
	     dbl_value_2  = data_ptr[ index ].op_2;
	     dbl_expected = data_ptr[ index ].exp;
	     *dptr_1 = dbl_value_1;		/* set 1st operand */
	     *dptr_2 = dbl_value_2;		/* set 2nd operand */
	} else {   /* only 1 operand */
	     dbl_ld_acc   = data_ptr[ index ].op_1;
	     dbl_value_1  = data_ptr[ index ].op_2;
	     dbl_expected = data_ptr[ index ].exp;
	     *dptr_1 = dbl_value_1;		/* set the operand */
	}
}



/*
 ***************************************************************************
 *	Set the number of translation faults expected
 *
 *  The entry parameters are the number of faults expected with an instruction
 *  cache miss and with varying data types. The correct fault count is
 *  selected and put into "exp_page_faults". 
 *  In double precision compare operations, the system won't fetch the 
 *  least significant half of the operand(s) if the most significant halves 
 *  are different. The # of faults expected will be adjusted for this.
 * 
 ***************************************************************************
*/
get_exp_faults( sgl_1, dbl_1, sgl_2, dbl_2 )
int sgl_1;				/* exp # faults for 1 sgl operand  */
int dbl_1;				/* exp # faults for 1 dbl operand  */
int sgl_2;				/* exp # faults for 2 sgl operands */
int dbl_2;				/* exp # faults for 2 dbl operands */
{
	if( no_ops == 1 ) {
	     if( sgl_op )
	          exp_page_faults = sgl_1;	/* 1 sgl operand  */
	      else
	          exp_page_faults = dbl_1;	/* 1 dbl operand  */
	} else {
	     if( sgl_op )
	          exp_page_faults = sgl_2;	/* 2 sgl operands */
	      else
	          exp_page_faults = dbl_2;	/* 2 dbl operands */
	}
	if( (op_code == CMPD_OP_CODE)  && (dbl_value_1.m != dbl_ld_acc.m) ||
	    (op_code == CMPD2_OP_CODE) && (dbl_value_1.m != dbl_value_2.m) )
	     exp_page_faults--;
}




unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.