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


#include "dmp_defs.h"

/**************************************************************************
*
*    		Test the current instruction
*
*  If the current instruction accesses any operands, then test it with
*  all major applicable addressing modes.
*
*  NOTE: Pipline tests 3 & 4 are not run with the "no-fpp" firmware because
*        the ADDs would cause traps. They are not run with certain "load
*        type instructions because of a hardware restriction (an ADDF 
*        followed by an LDF will cause a floating overflow event).
*
*  30-Apr-85  added pipelined instruction tests
*  17-May-85  don't run pre-piped stuff w/ LDF, LNF (ovfl errors)
*  21-Jun-85  added 3rd operand for MULL3
**************************************************************************/
test_inst()
{
/*
 * Set the values for the indirect pointers
*/
	*adr_op1_ptr = (int) adr_op1;		/* set word offset ptr #1  */
	*adr_op2_ptr = (int) adr_op2;		/* set word offset ptr #2  */
	*adr_op3_ptr = (int) adr_op3;		/* set word offset ptr #3  */
	error = FALSE;				/* clear the error flag    */
	set_load_flag();			/* set/reset load Acc flag */
	if( !no_ops )
	     test_0_ops();	/* test inst w/ no operands */
	else {
	     tst_abs();		/* absolute addressing             */
	     if( s_to_d || 
	       ( (precision == SGL) && (op_type == LOAD) ) )
	          tst_i_l();	/* immediate longword              */
	     tst_b();		/* byte displacement relative      */
	     tst_w();		/* word displacement relative      */
	     tst_l();		/* longword displacement relative  */
	     tst_b_d();		/* byte disp. relative deferred    */
	     tst_w_d();		/* word disp. relative deferred    */
	     tst_l_d();		/* longword disp. rel. deferred    */
	     tst_r();		/* direct register                 */
	     tst_r_d();		/* register deferred               */
	     if( user_mode ) {	/* do stack stuff in user mode only */
		  if( (op_code == MULL2_OP_CODE) || 
		      (op_code == MULL3_OP_CODE) ) {
		       tst_mull_stack();	/* POP, POP, PUSH */
		       tst_pop_d();		/* deferred POP   */
	          }
		  else if( d_to_s || 
			 ( (precision == SGL) && (op_type == STORE) ) ) {
	               tst_push();	/* PUSH ( auto-decremented SP ) */
	               tst_pop_d();	/* deferred POP                 */
	          }
		  else if( s_to_d || 
			 ( (precision == SGL) && (op_type == LOAD) ) ) {
	               tst_pop();	/* POP ( auto-incremented SP )  */
	               tst_pop_d();	/* deferred POP                 */
		  }
 	     }
	     tst_r_b();		/* register + byte displacement    */
	     tst_r_w();		/* register + word displacement    */
	     tst_r_l();		/* register + longword disp.       */
	     tst_r_bd();	/* reg. + byte disp. deferred      */
	     tst_r_wd();	/* reg. + word disp. deferred      */
	     tst_r_ld();	/* reg. + longword disp. deferred  */
	     tst_x_fpd();	/* FP deferred + longword index    */
	     tst_x_l();		/* longword disp. + longword index */
	     if( !no_fpp_wcs ) {
	          tst_p1();		/* pipe 1  - load w/ register data */
	          tst_p2();		/* pipe 2  - load w/ lw addressing */
	          if( ( op_code != LDF_OP_CODE ) && 
		      ( op_code != LNF_OP_CODE ) &&
		      ( op_code != CVLF_OP_CODE ) ) {
	                tst_p3();	/* pipe 3  - mulx w/ register data */
	                tst_p4();	/* pipe 4  - mulx w/ lw addressing */
	          }
	     }  /* end IF not no-fpp */
	}  /* end IF one or more operands */
}





/*******************************************************************
* ABSOLUTE ADDRESSING:
* instr =  <op-code> <9f> <&dmp_op_1> {<9f> <&dmp_op_2> <9f> <&dmp_op_3>}
*******************************************************************/
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 = addr_code3 = 0x9f;
	addr_size = 4;			/* longword (4 byte) ops. */
	addr_1    = DMP_OP_1;		/* abs. address of data   */
	addr_2    = DMP_OP_2;
	addr_3    = DMP_OP_3;
	if( no_ops == 1 )
	     min_shift = 15;
	else if( no_ops == 2 )
	     min_shift = 10;
	else 
	     min_shift = 5;
	shift_count = 19;
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 3, 4, 4, 6, 5 );  /* set exp fault cnt */
	     pack_inst();		/* pack the instr. code     */
	     run_code();		/* execute the instruction  */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}





/*******************************************************************
* IMMEDIATE LONGWORD ADDRESSING:	( sgl and sgl_to_dbl only )
* instr =  <op-code> <8f> <data> { <8f> <data>  <8f> <data> }
*
* NOTE: If the instruction is MULL2, op #2 will use absolute addressing.
*       If the instruction is MULL3, op #3 will use absolute addressing.
*******************************************************************/
tst_i_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_IM_L;
	addr_code = addr_code2 = 0x8f;	
	addr_code3 = 0x9f;		/* MULL3 uses ABS for op #3 */
	addr_3 = DMP_OP_3;		/* addr_3 points to DMP_OP3 */
	if( op_code == MULL2_OP_CODE ) {
	     addr_code2 = 0x9f;		/* MULL2 uses ABS for op #2 */
	     addr_2 = DMP_OP_2;		/* addr_2 points to DMP_OP2 */
	}
	addr_size = 4;			/* longword (4 byte) data   */
	if( (op_code == MULL2_OP_CODE) || (op_code == MULL3_OP_CODE) )
	     exp_page_faults = 3;	/* 3 pages are used         */
	else
	     exp_page_faults = 2;	/* 2 pages are used         */
	shift_count = 19;
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     addr_1 = dbl_value_1.m;	/* set the 1st operand     */
	     if( op_code != MULL2_OP_CODE )
	          addr_2 = dbl_value_2.m;  /* set the 2nd operand  */
	     pack_inst();		/* pack the instr. code    */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}



/*******************************************************************
* BYTE DISPLACEMENT RELATIVE ADDRESSING:
* instr =  <op-code> <af> <offset to dmp_byte_op_1>
*                  { <af> <offset to dmp_byte_op_2> }
*                  { <af> <offset to dmp_byte_op_3> }
*******************************************************************/
tst_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_B_DSP;
	addr_code = addr_code2 = addr_code3 = 0xaf;
	addr_size = 1;			/* 1 byte operand         */
	exp_page_faults = 2;		/* 2 pages are used       */
	if( no_ops == 1 )
	     min_shift = 17;
	else if( no_ops == 2 )
	     min_shift = 15;
	else
	     min_shift = 13;
	shift_count = 19;
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_b_op1, adr_b_op2 );
	     addr_1 = os_b_op1 + 17 - shift_count; /* data's offset */
	     addr_2 = os_b_op2 + 15 - shift_count;
	     addr_3 = os_b_op3 + 13 - shift_count;
	     pack_inst();		/* pack the instr. code    */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}



/*******************************************************************
* WORD DISPLACEMENT RELATIVE ADDRESSING:
*  instruction =  <op-code> <cf> <offset to dmp_op_1>
*                         { <cf> <offset to dmp_op_2> }
*                         { <cf> <offset to dmp_op_3> }
*******************************************************************/
tst_w()
{
	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_W_DSP;
	addr_code = addr_code2 = addr_code3 = 0xcf;
	addr_size = 2;			/* word (2 byte) operand  */
	if( no_ops == 1 )
	     min_shift = 17;
	else if( no_ops == 2 )
	     min_shift = 14;
	else 
	     min_shift = 11;
	shift_count = 19;
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 3, 4, 4, 6, 5 );  /* set exp fault cnt */
	     addr_1 = os_op1 + 16 - shift_count; /* data's offset   */
	     addr_2 = os_op2 + 13 - shift_count;
	     addr_3 = os_op3 + 10 - shift_count;
	     pack_inst();		/* pack the instr. code    */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}



/*******************************************************************
* LONGWORD DISPLACEMENT RELATIVE ADDRESSING:
*  instruction =  <op-code> <ef> <offset to dmp_op_1>
*                         { <ef> <offset to dmp_op_2> }
*                         { <ef> <offset to dmp_op_3> }
*******************************************************************/
tst_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_L_DSP;
	addr_code = addr_code2 = addr_code3 = 0xef;
	addr_size = 4;			/* longword (4 byte) ops. */
	if( no_ops == 1 )
	     min_shift = 15;
	else if( no_ops == 2 )
	     min_shift = 10;
	else 
	     min_shift = 5;
	shift_count = 19;
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
	     addr_1 = os_op1 + 14 - shift_count; /* data's offset */
	     addr_2 = os_op2 +  9 - shift_count;
	     addr_3 = os_op3 +  4 - shift_count;
	     pack_inst();		/* pack the instr. code   */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}



/*******************************************************************
* BYTE DISPLACEMENT RELATIVE DEFERRED ADDRESSING:
*  instruction =  <op-code> <bf> <offset to dmp_byte_op_1>
*                         { <bf> <offset to dmp_byte_op_2> }
*                         { <bf> <offset to dmp_byte_op_3> }
*******************************************************************/
tst_b_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_B_DSP_DEF;
	addr_code = addr_code2 = addr_code3 = 0xbf;
	addr_size = 1;			/* 1 byte operand         */
	adr_b_op1->m = (int) adr_op1;	/* set byte offset ptr #1 */
	adr_b_op2->m = (int) adr_op2;	/* set byte offset ptr #2 */
	adr_b_op3->m = (int) adr_op3;	/* set byte offset ptr #3 */
	if( no_ops == 1 )
	     min_shift = 17;
	else if( no_ops == 2 )
	     min_shift = 15;
	else 
	     min_shift = 13;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 3, 4, 4, 6, 5 ); /* set exp fault count */
	     addr_1 = os_b_op1 + 17 - shift_count; /* data's offset  */
	     addr_2 = os_b_op2 + 15 - shift_count; 
	     addr_3 = os_b_op3 + 13 - shift_count; 
	     pack_inst();		/* pack the instr. code   */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}




/*******************************************************************
* WORD DISPLACEMENT RELATIVE DEFERRED ADDRESSING:
*  instruction =  <op-code> <df> <offset to dmp_op_1_ptr>
*                         { <df> <offset to dmp_op_2_ptr> }
*                         { <df> <offset to dmp_op_3_ptr> }
*******************************************************************/
tst_w_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_W_DSP_DEF;
	addr_code = addr_code2 = addr_code3 = 0xdf;
	addr_size = 2;			/* word (2 byte) operand  */
	if( no_ops == 1 )
	     min_shift = 17;
	else if( no_ops == 2 )
	     min_shift = 14;
	else 
	     min_shift = 11;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 4, 5, 6, 8, 8 );  /* set exp fault count */
	     addr_1 = os_ad_op1 + 16 - shift_count; /* operand offset */
	     addr_2 = os_ad_op2 + 13 - shift_count; 
	     addr_3 = os_ad_op3 + 10 - shift_count; 
	     pack_inst();		/* pack the instr. code   */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}


  
/*******************************************************************
* LONGWORD DISPLACEMENT RELATIVE DEFERRED ADDRESSING:
*  instruction =  <op-code> <ff> <offset to dmp_op_1_ptr>
*                         { <ff> <offset to dmp_op_2_ptr> }
*                         { <ff> <offset to dmp_op_3_ptr> }
*******************************************************************/
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 = addr_code3 = 0xff;
	addr_size = 4;			/* longword (4 byte) op.  */
	if( no_ops == 1 )
	     min_shift = 15;
	else if( no_ops == 2 )
	     min_shift = 10;
	else 
	     min_shift = 5;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 4, 5, 6, 8, 8 );  /* set exp fault count */
	     addr_1 = os_ad_op1 + 14 - shift_count; /* operand offset */
	     addr_2 = os_ad_op2 +  9 - shift_count; 
	     addr_3 = os_ad_op3 +  4 - shift_count; 
	     pack_inst();		/* pack the instr. code   */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}



/*******************************************************************
* DIRECT REGISTER ADDRESSING:
*  instruction =  <op-code> <50> { <54> } { <56> }
*
* If the instruction = MULL2 the store will be to R4,
* If the instruction = MULL3 the store will be to R6,
* If the instruction is any other store it will be to R0/R1.
*******************************************************************/
tst_r()
{
	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;
	addr_code  = 0x50;		/* 1st op in registers 0/1 */
	addr_code2 = 0x54;		/* 2nd op in registers 4/5 */
	addr_code3 = 0x56;		/* 3rd op in register  6   */
	addr_size = 0;			/* no addressing bytes     */
	pack_inst();			/* pack the instr. code    */
	exp_page_faults = 2;		/* 2 pages are used        */
	if( no_ops == 1 )
	     min_shift = 19;
	else if( no_ops == 2 )
	     min_shift = 18;
	else 
	     min_shift = 17;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	          get_current_data( adr_op1, adr_op2 );
	          load_regs[0] = dbl_value_1.m; /* set the data for the regs*/
	          load_regs[1] = dbl_value_1.l;
	          load_regs[4] = dbl_value_2.m;
	          load_regs[5] = dbl_value_2.l;
	          exp_regs[0]  = load_regs[0];  /* set exp final reg values */
	          exp_regs[1]  = load_regs[1];
	          exp_regs[4]  = load_regs[4];
	          exp_regs[5]  = load_regs[5];
	          if( op_code == MULL2_OP_CODE )
		       exp_regs[4] = dbl_expected.m;
		  else if( op_code == MULL3_OP_CODE )
		       exp_regs[6] = dbl_expected.m;
	          else if( op_type == STORE ) {
		       exp_regs[0] = dbl_expected.m;
		       exp_regs[1] = dbl_expected.l;
	          }
	          if( op_code == CVDL_OP_CODE )	/* correct for sgl store    */
		       exp_regs[1] = dbl_value_1.l; /* r1 shouldn't change  */
	          run_code();			/* execute the instruction  */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}




/*******************************************************************
* REGISTER DEFERRED ADDRESSING:
*  instruction =  <op-code> <60> { <61> <62> }
*******************************************************************/
tst_r_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_REG_DEF;
	addr_code  = 0x60;
	addr_code2 = 0x61;
	addr_code3 = 0x62;
	addr_size  = 0;			/* no address byte(s)   */
	load_regs[0] = (int) adr_op1;	/* get addr of op. 1    */
	load_regs[1] = (int) adr_op2;	/* get addr of op. 2    */
	load_regs[2] = (int) adr_op3;	/* get addr of op. 3    */
	exp_regs[0] = load_regs[0];
	exp_regs[1] = load_regs[1];
	exp_regs[2] = load_regs[2];
	pack_inst();			/* pack the instr. code */
	if( no_ops == 1 )
	     min_shift = 19;
	else if( no_ops == 2 )
	     min_shift = 18;
	else 
	     min_shift = 17;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 3, 4, 4, 6, 5 );  /* set exp fault count   */
	     run_code();		     /* execute the instruction */
	     if( --shift_count < min_shift )
		   shift_count = 19;
	}
}




/*******************************************************************
* AUTO-DECREMENTED STACK POINTER ADDRESSING  ( PUSH ):
*  instruction =  <op-code> <7e>
* 
* The final result will be popped by "run_code". 
* Push will be run with SGL instructions only.
* "DBL_VALUE_4", the final result, will be set by RUN_CODE.
*******************************************************************/
tst_push()
{
	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_PUSH;
	addr_code = 0x7e;
	addr_size = 0;			/* no addressing bytes    */
	exp_page_faults = 3;		/* 3 pages are used       */
	shift_count = 19;
	pack_inst();			/* pack the instr. code   */
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     run_code();		/* execute the instruction */
	     if( force_loop )
		  run_code();		/* start the error loop   */
	}
}




/*******************************************************************
* 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 floating point instructions only. A different
* routine will be used for the integer multiply instructions.
*******************************************************************/
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 == 1 ) {
	     min_shift = 19;
	     exp_page_faults = 3;	/* 3 pages are used       */
	 } else  {			/* 2 operands */
	     min_shift = 18;
	     exp_page_faults = 4;	/* 4 pages are used       */
	}
	shift_count = 19;
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     sgl_value_8 = dbl_value_1.m; /* data to be pushed   */
	     sgl_value_9 = dbl_value_2.m; /* data to be pushed   */
	     run_code();		/* execute the instruction */
	     if( force_loop )
		  run_code();		/* start the error loop   */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}






/*******************************************************************
* STACK ADDRESSING TEST FOR THE MULL2 AND MULL3 INTEGER MULTIPLY INSTRUCTIONS
*
*  For MULL2, operand 1 will be popped from the stack and
*             operand 2 will be in memory
* 
*  For MULL3, operands 1 and 2 will be popped from the stack and
*             operand 3 will be in pushed back onto the stack.
* 
* The stack data will be pushed by "run_code"
*******************************************************************/
tst_mull_stack()
{
	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_size = 0;			/* no addressing bytes      */
	addr_mode = ADR_POP;
	addr_code = 0x8e;		/* auto increment SP (POP)  */
	if( op_code == MULL2_OP_CODE )
	     addr_code2 = 0x60;		/* R0 (deferred) addressing */
	else
	     addr_code2 = 0x8e;		/* auto increment SP (POP)  */
	addr_code3 = 0x7e;		/* auto decrement SP (PUSH) */
	load_regs[0] = (int) adr_op2;	/* set R0 to addr of op #2  */
	exp_regs[0] = load_regs[0];
	pack_inst();			/* pack the instr. code     */
	exp_page_faults = 4;		/* 4 pages are used         */
	if( no_ops == 2 ) 
	     min_shift = 18;		/* MULL2 */
	 else 	
	     min_shift = 17;		/* MULL3 */
	shift_count = 19;
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     if( op_code == MULL2_OP_CODE ) 
	          sgl_value_8 = dbl_value_1.m; /* push operand 1 only */
	     else {
	          sgl_value_8 = dbl_value_1.m; /* push both of        */
	          sgl_value_9 = dbl_value_2.m; /*     the operands    */
	     }
	     run_code();		/* execute the instruction */
	     if( force_loop )
		  run_code();		/* start the error loop   */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}





/*******************************************************************
* AUTO-INCREMENTED STACK POINTER DEFERRED ADDRESSING:
*  instruction =  <op-code> <9e> { <9e> <9e> }
*
* The address(es) of the data will be pushed by "run_code"
*******************************************************************/
tst_pop_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_POP_DEF;
	addr_code = addr_code2 = addr_code3 = 0x9e;
	addr_size = 0;			/* no addressing bytes     */
	pack_inst();			/* pack the instr. code    */
	sgl_value_8  = (int) adr_op1;	/* get 1st op's address    */
	sgl_value_9  = (int) adr_op2;	/* get 2nd op's address    */
	sgl_value_10 = (int) adr_op3;	/* get 3rd op's address    */
	if( no_ops == 1 )
	     min_shift = 19;
	else if( no_ops == 2 )
	     min_shift = 18;
	else 
	     min_shift = 17;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 4, 5, 6, 7, 7 ); /* set exp fault cnt */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		   shift_count = 19;
	}
}




/*******************************************************************
* REGISTER + BYTE DISPLACEMENT ADDRESSING:
*  instruction =  <op-code> <a4> <(&op_1 -r4)>
*                         { <a5> <(&op_2- r5)> }
*                         { <a6> <(&op_3- r6)> }
*******************************************************************/
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_code3 = 0xa6;		/* addr 3 is offset by r6 */
	addr_size  = 1;			/* 1 byte operand         */
	addr_1 = 20;			/* set the 1st byte offset */
	addr_2 = 4;			/* set the 2nd byte offset */
	addr_3 = 16;			/* set the 3rd 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;
	load_regs[6] = (int) adr_op3 - 16;
	exp_regs[4] = load_regs[4];
	exp_regs[5] = load_regs[5];
	exp_regs[6] = load_regs[6];
	if( no_ops == 1 )
	     min_shift = 18;
	else if( no_ops == 2 )
	     min_shift = 16;
	else 
	     min_shift = 14;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 3, 4, 4, 6, 5 );  /* set exp fault count */
	     run_code();		/* execute the instruction    */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	 }
}



/*******************************************************************
* REGISTER + WORD DISPLACEMENT ADDRESSING:
*  instruction =  <op-code> <c4> <(&op_1 -r4)>
*                         { <c5> <(&op_2 -r5)> }
*                         { <c6> <(&op_3 -r6)> }
*******************************************************************/
tst_r_w()
{
	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_W;
	addr_code  = 0xc4;		/* addr 1 is offset by r4 */
	addr_code2 = 0xc5;		/* addr 2 is offset by r5 */
	addr_code3 = 0xc6;		/* addr 3 is offset by r6 */
	addr_size  = 2;			/* word (2 byte) operand  */
	addr_1 = 511;			/* set the 1st word offset */
	addr_2 = 513;			/* set the 2nd word offset */
	addr_3 = 600;			/* set the 3rd word offset */
	pack_inst();			/* pack the instr. code    */
	load_regs[4] = (int) adr_op1 - 511;  /* get the reg value  */
	load_regs[5] = (int) adr_op2 - 513;
	load_regs[6] = (int) adr_op3 - 600;
	exp_regs[4] = load_regs[4];
	exp_regs[5] = load_regs[5];
	exp_regs[6] = load_regs[6];
	if( no_ops == 1 )
	     min_shift = 17;
	else if( no_ops == 2 )
	     min_shift = 14;
	else 
	     min_shift = 11;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 3, 4, 4, 6, 5 );  /* set exp fault count */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}




/*******************************************************************
* REGISTER + LONGWORD DISPLACEMENT ADDRESSING:
*  instruction =  <op-code> <e4> <(&op_1 -r4)>
*                         { <e5> <(&op_2 -r5)> }
*                         { <e6> <(&op_3 -r6)> }
*******************************************************************/
tst_r_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_REG_L;
	addr_code  = 0xe4;		/* addr 1 is offset by r4 */
	addr_code2 = 0xe5;		/* addr 2 is offset by r5 */
	addr_code3 = 0xe6;		/* addr 3 is offset by r6 */
	addr_size  = 4;			/* longword (4 byte) op.  */
	addr_1 = (int) adr_op1 - 123;	/* get the 1st addr base  */
	addr_2 = (int) adr_op2 - 130;	/* get the 2nd addr base  */
	addr_3 = (int) adr_op3 - 255;	/* get the 3rd addr base  */
	load_regs[4] = 123;		/* reg 4 = 123            */
	exp_regs[4]  = 123;
	load_regs[5] = 130;		/* reg 5 = 130            */
	exp_regs[5]  = 130;
	load_regs[6] = 255;		/* reg 5 = 255            */
	exp_regs[6]  = 255;
	pack_inst();			/* pack the instr. code   */
	if( no_ops == 1 )
	     min_shift = 15;
	else if( no_ops == 2 )
	     min_shift = 10;
	else 
	     min_shift = 5;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 3, 4, 4, 6, 5 );  /* set exp fault count */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}




/*******************************************************************
* REGISTER + BYTE DISPLACEMENT DEFERRED ADDRESSING:
*  instruction =  <op-code> <b4> <(&ptr_to_op_3 -r4)>
*                         { <b5> <(&ptr_to_op_3 -r5)> }
*                         { <b6> <(&ptr_to_op_3 -r6)> }
*******************************************************************/
tst_r_bd()
{
	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_DEF;
	addr_code  = 0xb4;		/* addr 1 is offset by r4 */
	addr_code2 = 0xb5;		/* addr 2 is offset by r5 */
	addr_code3 = 0xb6;		/* addr 3 is offset by r6 */
	addr_size  = 1;			/* 1 byte operand         */
	addr_1 = 20;			/* set the 1st byte offset */
	addr_2 = 4;			/* set the 2nd byte offset */
	addr_3 = 16;			/* set the 3rd byte offset */
	pack_inst();			/* pack the instr. code    */
	load_regs[4] = (int) adr_op1_ptr - 20;  /* get the reg value */
	load_regs[5] = (int) adr_op2_ptr - 4;
	load_regs[6] = (int) adr_op3_ptr - 16;
	exp_regs[4] = load_regs[4];
	exp_regs[5] = load_regs[5];
	exp_regs[6] = load_regs[6];
	if( no_ops == 1 )
	     min_shift = 18;
	else if( no_ops == 2 )
	     min_shift = 16;
	else 
	     min_shift = 14;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 4, 5, 6, 8, 8 );  /* set exp fault count */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}



/*******************************************************************
* REGISTER + WORD DISPLACEMENT DEFERRED ADDRESSING:
*  instruction =  <op-code> <d4> <(&ptr_to_op_1 -r4)>
*                         { <d5> <(&ptr_to_op_2 -r5)> }
*                         { <d6> <(&ptr_to_op_3 -r6)> }
*******************************************************************/
tst_r_wd()
{
	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_W_DEF;
	addr_code  = 0xd4;		/* addr 1 is offset by r4 */
	addr_code2 = 0xd5;		/* addr 2 is offset by r5 */
	addr_code3 = 0xd6;		/* addr 3 is offset by r6 */
	addr_size  = 2;			/* word (2 byte) operand  */
	addr_1 = 511;			/* set the 1st word offset */
	addr_2 = 601;			/* set the 2nd word offset */
	addr_3 = 1027;			/* set the 3rd word offset */
	pack_inst();			/* pack the instr. code    */
	load_regs[4] = (int) adr_op1_ptr - 511; /* get the reg value */
	load_regs[5] = (int) adr_op2_ptr - 601;
	load_regs[6] = (int) adr_op3_ptr - 1027;
	exp_regs[4] = load_regs[4];
	exp_regs[5] = load_regs[5];
	exp_regs[6] = load_regs[6];
	if( no_ops == 1 )
	     min_shift = 17;
	else if( no_ops == 2 )
	     min_shift = 14;
	else 
	     min_shift = 11;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 4, 5, 6, 8, 8 );  /* set exp fault count */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}




/*******************************************************************
* REGISTER + LONGWORD DISPLACEMENT DEFERRED ADDRESSING:
*  instruction =  <op-code> <f4> <(longword &ptr_to_op_1 -r4)>
*                         { <f5> <(longword &ptr_to_op_2 -r5)> }
*                         { <f6> <(longword &ptr_to_op_3 -r6)> }
*******************************************************************/
tst_r_ld()
{
	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_L_DEF;
	addr_code    = 0xf4;		/* addr 1 is offset by r4 */
	addr_code2   = 0xf5;		/* addr 2 is offset by r5 */
	addr_code3   = 0xf6;		/* addr 3 is offset by r6 */
	addr_size    = 4;		/* longword (4 byte) op.  */
	addr_1 = (int) adr_op1_ptr - 123;	/* set the 1st offset */
	addr_2 = (int) adr_op2_ptr - 212;	/* set the 2nd offset */
	addr_3 = (int) adr_op3_ptr - 510;	/* set the 3rd offset */
	pack_inst();			/* pack the instr. code    */
	load_regs[4] = 123;		/* reg 4 = 123             */
	load_regs[5] = 212;		/* reg 5 = 212             */
	load_regs[6] = 510;		/* reg 6 = 510             */
	exp_regs[4]  = load_regs[4];
	exp_regs[5]  = load_regs[5];
	exp_regs[6]  = load_regs[6];
	if( no_ops == 1 )
	     min_shift = 15;
	else if( no_ops == 2 )
	     min_shift = 10;
	else 
	     min_shift = 5;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 4, 5, 6, 8, 8 );  /* set exp fault count */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}



/*******************************************************************
* FRAME POINTER DEFERRED + LONGWORD INDEX ADDRESSING:
*  instruction =  <op-code> <44> <6d> { <45> <6d> } { <46> <6d> }
* 
*  The indeces used will be either quadword indeces ( for DBL operands )
*  of longword indeces ( for SGL operands ).
*
* NOTE: 
*  dmp_op_2 is 4 pages away from dmp_op_1. (200 hex quadwords)
*  dmp_op_3 is 5 pages & 4 bytes from dmp_op_1. (501 hex longwords)
*  IF THIS RELATIVE DISPLACEMENT IS CHANGED THEN THE R5 AND/OR R6 INDICES
*  MUST BE CHANGED IN THIS CODE!!! 
*  ( The R5 index is used by CMPF2, CMPD2, MULL2, & MULL3. 
*    The R6 index is used by MULL3. )
*******************************************************************/
tst_x_fpd()
{
	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_FP_DEF;
	addr_code  = 0x44;		/* code for reg. 4 index  */
	addr_code2 = 0x45;		/* code for reg. 5 index  */
	addr_code3 = 0x46;		/* code for reg. 6 index  */
	addr_codeB = 0x6d;		/* code for FP deferred   */
	addr_size = 0;			/* no addr. field per se  */
	pack_inst();			/* pack the instr. code   */
/*
 * set the frame pointer to '&operand_1 - 16 bytes' (2 quad-words)
*/
	sgl_dummy1 = (int) adr_op1;	/* get the addr of op #1  */
	load_regs[13] = sgl_dummy1-16;	/* FP = op 1's addr - 16  */
	exp_regs[13] = load_regs[13];
	if( sgl_op ) {
	    load_regs[4] = 4;		/* FP to op_1 (longwords) */
	    load_regs[5] = 0x404;	/* FP to op_2 (longwords) */
	    load_regs[6] = 0x505;	/* FP to op_2 (longwords) */
	} else {
	    load_regs[4] = 2;		/* FP to op_1 (quadwords) */
	    load_regs[5] = 0x202;	/* FP to op_2 (quadwords) */
	}
	exp_regs[4] = load_regs[4];
	exp_regs[5] = load_regs[5];
	exp_regs[6] = load_regs[6];
	if( no_ops == 1 )
	     min_shift = 18;
	else if( no_ops == 2 )
	     min_shift = 16;
	else 
	     min_shift = 14;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 3, 4, 4, 6, 5 );  /* set exp fault count */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}



/*******************************************************************
*         INDEXED LONGWORD DISPLACEMENT ADDRESSING:
*  instruction =  <op-code> <44> <ef> <longword offset>
*                         { <45> <ef> <longword offset> }
*                         { <46> <ef> <longword offset> }
*
* NOTE: The index to operand 3 (R6) is only used with MULL3.
*******************************************************************/
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_code3 = 0x46;		/* code for reg. 6 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)  */
	     load_regs[6] = 5;		/* reg 6 = 5 (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];
	exp_regs[6] = load_regs[6];
	if( no_ops == 1 )
	     min_shift = 14;
	else if( no_ops == 2 )
	     min_shift = 8;
	else 
	     min_shift = 2;
	shift_count = 19; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 3, 4, 4, 6, 5 );  /* set exp fault count */
	     addr_1 = os_op1 + 13 - shift_count; /* data's offset   */
	     addr_1 -=16;		/*   -16 bytes (2 Q-words)  */
	     addr_2 = os_op2 +  7 - shift_count; /* data's offset   */
	     addr_2 -=24;		/*   -24 bytes (3 Q-words)  */
	     addr_3 = os_op3 +  1 - shift_count; /* data's offset   */
	     addr_3 -=20;		/*   -20 bytes (5 L-words)  */
	     pack_inst();		/* pack the instr. code     */
	     run_code();		/* execute the instruction  */
	     if( --shift_count < min_shift )
		  shift_count = 19;
	}
}





/*******************************************************************
* PIPELINE TEST #1 -DIRECT REGISTER ADDRESSING WITH AN INITIAL LOAD
*
*  This test will put a LOAD instruction immediately in front of the
*  test instruction and a MULTIPLY instruction immediately behind it.
*  The instruction buffer will look like:
*
*  <ldf/ldd> <instruction> <mulf/muld> where:
*  instruction =  <op-code> <50> { <54> } { <58> }
*
*  The load will be done through register R6 deferred.
*  The multiply addressing mode will be through register R2 deferred.
*******************************************************************/
tst_p1()
{
	pipe_test = 1;		/* set pipelined test flag to test #3 */
	if( acc_ld_size == DBL )
	     pipe_inst1 = LDD_OP_CODE;
	else
	     pipe_inst1 = LDF_OP_CODE;
	if( acc_st_size == DBL )
	     pipe_inst2 = MULD_OP_CODE;
	else
	     pipe_inst2 = MULF_OP_CODE;
	addr_code_p1 = 0x66;		/* set the 1st piped addr mode */
	addr_code_p2 = 0x62;		/* set the 2nd piped addr mode */
	fill_reg_buf( load_regs );	/* set data for registers */
	fill_reg_buf( exp_regs );	/* set data for registers */
	load_regs[2] = (int) adr_op4;	/* the MULx is w/ op. #4  */
	exp_regs[2] = load_regs[2];
	load_regs[6] = (int) adr_op5;	/* the LDx is w/ op. #5   */
	exp_regs[6] = load_regs[6];
	adr_op4->m = 0x40800000;	/* set the MULx instr's   */
	adr_op4->l = 0;			/*    operand = '1.0'     */
	addr_mode = ADR_REG;
	addr_code  = 0x50;		/* 1st op in registers 0/1 */
	addr_code2 = 0x54;		/* 2nd op in registers 4/5 */
	addr_code3 = 0x58;		/* 3rd op goes to reg. 8   */
	addr_size = 0;			/* no addressing bytes     */
	pack_inst();			/* pack the instr. code    */
	exp_page_faults = 4;		/* 4 pages are used        */
	if( no_ops == 1 )
	     min_shift = 16;
	else if( no_ops == 2 )
	     min_shift = 15;
	else
	     min_shift = 14;
	shift_count = 18; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     adr_op5->m = dbl_ld_acc.m;		/* get the data for the */
	     adr_op5->l = dbl_ld_acc.l;		/*     load instruction */
	     load_regs[0] = dbl_value_1.m;	/* set the test data    */
	     load_regs[1] = dbl_value_1.l;
	     load_regs[4] = dbl_value_2.m;
	     load_regs[5] = dbl_value_2.l;
	     exp_regs[4]  = load_regs[4];	/* set exp final reg value */
	     exp_regs[5]  = load_regs[5];
	     if( op_type == STORE ) {
		  exp_regs[0] = dbl_expected.m;
		  exp_regs[1] = dbl_expected.l;
	     } else {
		  exp_regs[0] = dbl_value_1.m;
		  exp_regs[1] = dbl_value_1.l;
	          if( op_code == MULL3_OP_CODE )
	               exp_regs[8] = dbl_expected.m;
	          if( op_code == MULL2_OP_CODE )
	               exp_regs[4] = dbl_expected.m;
	     }
	     if( op_code == CVDL_OP_CODE )	/* correct for sgl store    */
		  exp_regs[1] = dbl_value_1.l;	/* r1 shouldn't change  */
	     run_code();			/* execute the instruction  */
	     if( --shift_count < min_shift )
		  shift_count = 18;
	}
	pipe_test = FALSE;			/* clear the pipe test flag */
}



/*******************************************************************
* PIPELINE TEST #2 -LONGWORD DISP REL ADDRESSING WITH AN INITIAL LOAD
*
*  This test will put a LOAD instruction immediately in front of the
*  test instruction and a MULTIPLY instruction immediately behind it.
*  The instruction buffer will look like:
*
*  <ldf/ldd> <instruction> <mulf/muld> where:
*  instruction =  <op-code> <ef> <offset to dmp_op_1>
*                         { <ef> <offset to dmp_op_2> }
*                         { <ef> <offset to dmp_op_3> }
*
*  The load's addressing mode will be through register R6 deferred.
*  The multiply's addressing mode will be through register R2 deferred.
*******************************************************************/
tst_p2()
{
	pipe_test = 2;		/* set the piplined test flag to test #4 */
	if( acc_ld_size == DBL )
	     pipe_inst1 = LDD_OP_CODE;
	else
	     pipe_inst1 = LDF_OP_CODE;
	if( acc_st_size == DBL )
	     pipe_inst2 = MULD_OP_CODE;
	else
	     pipe_inst2 = MULF_OP_CODE;
	addr_code_p1 = 0x66;		/* set the 1st piped addr mode */
	addr_code_p2 = 0x62;		/* set the 2nd piped addr mode */
	fill_reg_buf( load_regs );	/* set data for registers */
	fill_reg_buf( exp_regs );	/* set data for registers */
	load_regs[2] = (int) adr_op4;	/* MULx is via op. #4     */
	exp_regs[2] = load_regs[2];
	load_regs[6] = (int) adr_op5;	/* LDx is via op. #5      */
	exp_regs[6] = load_regs[6];
	adr_op4->m = 0x40800000;	/* set the piped mult's   */
	adr_op4->l = 0;			/*    operand = '1.0'     */
	addr_mode = ADR_L_DSP;
	addr_code = addr_code2 = addr_code3 = 0xef;
	addr_size = 4;			/* longword (4 byte) ops. */
	if( no_ops == 1 )
	     min_shift = 12;
	else if( no_ops == 2 )
	     min_shift = 7;
	else 
	     min_shift = 2;
	shift_count = 18; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 5, 6, 6, 8, 7 );	/* set exp fault count   */
	     adr_op5->m = dbl_ld_acc.m;		/* get the data for the  */
	     adr_op5->l = dbl_ld_acc.l;		/*      load instruction */
	     addr_1 = os_op1 + 12 - shift_count;
	     addr_2 = os_op2 +  7 - shift_count;
	     addr_3 = os_op3 +  2 - shift_count;
	     pack_inst();		/* pack the instr. code   */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 18;
	}
	pipe_test = FALSE;		/* clear the pipe test flag */
}





/*******************************************************************
* PIPELINE TEST #3 -DIRECT REGISTER ADDRESSING WITH AN INITIAL MULTIPLY
*
*  This test will put a MULTIPLY instruction immediately in front of the
*  test instruction and a MULTIPLY instruction immediately behind it.
*  Both multiplys will be times "1.0".
*
*  The instruction buffer will look like:
*  	<mulf/muld> <instruction> <mulf/muld> where:
*  	instruction =  <op-code> <50> { <54> } { <58> }
*
*  The 1st multiply will be done through register R6 deferred.
*  The 2nd multiply will be done through register R2 deferred.
*******************************************************************/
tst_p3()
{
	pipe_test = 3;		/* set pipelined test flag to pipe test #1 */
	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;
	addr_code_p1 = 0x66;		/* set the 1st piped addr mode */
	addr_code_p2 = 0x62;		/* set the 2nd piped addr mode */
	fill_reg_buf( load_regs );	/* set data for registers */
	fill_reg_buf( exp_regs );	/* set data for registers */
	load_regs[2] = (int) adr_op4;	/* 2nd MULx is via op. #4 */
	exp_regs[2] = load_regs[2];
	load_regs[6] = (int) adr_op5;	/* 1st MULx is via op. #5 */
	exp_regs[6] = load_regs[6];
	adr_op4->m = 0x40800000;	/* set the MULx instr's   */
	adr_op4->l = 0;			/*    operand = '1.0'     */
	adr_op5->m = 0x40800000;
	adr_op5->l = 0;	
	addr_mode = ADR_REG;
	addr_code  = 0x50;		/* 1st op in registers 0/1 */
	addr_code2 = 0x54;		/* 2nd op in registers 4/5 */
	addr_code3 = 0x58;		/* 3rd op goes to reg. 8   */
	addr_size = 0;			/* no addressing bytes     */
	pack_inst();			/* pack the instr. code    */
	exp_page_faults = 4;		/* 4 pages are used        */
	if( no_ops == 1 )
	     min_shift = 16;
	else if( no_ops == 2 )
	     min_shift = 15;
	else
	     min_shift = 14;
	shift_count = 18; 
	for( index = 0; index <= max_index; index++ ) {
	          get_current_data( adr_op1, adr_op2 );
	          load_regs[0] = dbl_value_1.m; /* set the test data    */
	          load_regs[1] = dbl_value_1.l;
	          load_regs[4] = dbl_value_2.m;
	          load_regs[5] = dbl_value_2.l;
		  if( op_code == MULL2_OP_CODE )
	               exp_regs[4] = dbl_expected.m;	/* store to reg #4 */
	          else
		       exp_regs[4] = load_regs[4];	/* reg 4 s/n change */
	          exp_regs[5]  = load_regs[5];
		  if( op_code == MULL3_OP_CODE )
	               exp_regs[8] = dbl_expected.m;	/* store to reg #8 */
	          if( op_type == LOAD ) {
		       exp_regs[0] = dbl_value_1.m;
		       exp_regs[1] = dbl_value_1.l;
	          } else {
		       exp_regs[0] = dbl_expected.m;
		       exp_regs[1] = dbl_expected.l;
	          }
	          if( op_code == CVDL_OP_CODE )	/* correct for sgl store    */
		       exp_regs[1] = dbl_value_1.l; /* r1 shouldn't change  */
	          run_code();			/* execute the instruction  */
	     if( --shift_count < min_shift )
		  shift_count = 18;
	}
	pipe_test = FALSE;			/* clear the pipe test flag */
}




/*******************************************************************
* PIPELINE TEST #4 -LONGWORD DISP REL ADDR. WITH AN INITIAL 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> }
*                         { <ef> <offset to dmp_op_3> }
*
*  The 1st multiply's addressing will be through register R6 deferred.
*  The 2nd multiply's addressing will be through register R2 deferred.
*******************************************************************/
tst_p4()
{
	pipe_test = 4;		/* 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;
	addr_code_p1 = 0x66;		/* set the 1st piped addr mode */
	addr_code_p2 = 0x62;		/* set the 2nd piped addr mode */
	fill_reg_buf( load_regs );	/* set data for registers */
	fill_reg_buf( exp_regs );	/* set data for registers */
	load_regs[2] = (int) adr_op4;	/* 2nd MULx is w/ op. #4 */
	exp_regs[2] = load_regs[2];
	load_regs[6] = (int) adr_op5;	/* 1st MULx is w/ op. #5  */
	exp_regs[6] = load_regs[6];
	adr_op4->m = 0x40800000;	/* set the piped mult's   */
	adr_op4->l = 0;			/*    operand = '1.0'     */
	adr_op5->m = 0x40800000;
	adr_op5->l = 0;	
	addr_mode = ADR_L_DSP;
	addr_code = addr_code2 = addr_code3 = 0xef;
	addr_size = 4;			/* longword (4 byte) ops. */
	if( no_ops == 1 )
	     min_shift = 12;
	else if( no_ops == 2 )
	     min_shift = 7;
	else
	     min_shift = 2;
	shift_count = 18; 
	for( index = 0; index <= max_index; index++ ) {
	     get_current_data( adr_op1, adr_op2 );
	     get_exp_faults( 5, 6, 6, 8, 7 );  /* set exp fault count */
	     addr_1 = os_op1 + 12 - shift_count; /* data's offset */
	     addr_2 = os_op2 +  7 - shift_count;
	     addr_3 = os_op3 +  2 - shift_count;
	     pack_inst();		/* pack the instr. code   */
	     run_code();		/* execute the instruction */
	     if( --shift_count < min_shift )
		  shift_count = 18;
	}
	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 == 1 ) {
	     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 */
	} else if( no_ops == 2 ) {
	     if( index < (ldf_cnt -1) )
	          dbl_ld_acc   = ldd_data[index+1].op_1;
	     else
	          dbl_ld_acc   = ldd_data[index & 0xf].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 {   /* 3 operands */
	     if( index < (ldf_cnt -1) )
	          dbl_ld_acc   = ldd_data[index +1].op_1;
	     else
	          dbl_ld_acc   = ldd_data[index & 0xf].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 */
	}
}



/*
 ***************************************************************************
 *	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 (CMPD, CMPD2) 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. 
 *  When using the "no-fpp" version of firmware the least significant longword
 *  will always be fetched for CMPD. CMPD2 acts the same with either WCS.
 * 
 ***************************************************************************
*/
get_exp_faults( sgl_1, dbl_1, sgl_2, dbl_2, sgl_3 )
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 */
int sgl_3;				/* exp # faults for 3 sgl 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( no_ops == 2 ) {
	     if( sgl_op )
	          exp_page_faults = sgl_2;	/* 2 sgl operands */
	      else
	          exp_page_faults = dbl_2;	/* 2 dbl operands */
	} else 	/* 3 sgl operands */
	          exp_page_faults = sgl_3;	/* 3 sgl operands */
	if( (op_code == CMPD2_OP_CODE) && (dbl_value_1.m != dbl_value_2.m) ) 
	     exp_page_faults--;
	if( (op_code == CMPD_OP_CODE) && (dbl_value_1.m != dbl_ld_acc.m) &&
	    (!no_fpp_wcs) )
	     exp_page_faults--;
}


/*
 ***************************************************************************
 *
 *	Set or reset the LOAD_ACCUMULATOR flag
 *
 *  If the current instruction loads the accumulator then set the flag.
 *  This flag is used by the page fault handler.
 ***************************************************************************
*/
set_load_flag()
{
	if( (op_code == LDF_OP_CODE)  ||	/* load SGL Acc. */
	    (op_code == LNF_OP_CODE)  ||	/* load / negate SGL Acc. */
	    (op_code == LDD_OP_CODE)  ||	/* load SGL Acc. */
	    (op_code == LND_OP_CODE)  ||	/* load / negate SGL Acc. */
	    (op_code == LDFD_OP_CODE) )		/* load SGL to DBL Acc. */
	     load_type_inst = TRUE;
	else
	     load_type_inst = FALSE;
}


unix.superglobalmegacorp.com

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