|
|
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--;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.