|
|
Power 6/32 Unix version 1.21
#include "fpp_defs.h"
/*****************************************************************************
*
* DIVD - DOUBLE PRECISION FLOATING POINT DIVIDE TEST
*
*****************************************************************************/
divd()
{
asm(".globl _divd_t");
asm("_divd_t:"); /* entry address */
if( (cycle == 1) && (prt_hdrs) ) /* print headers on 1st cycle */
writes(" DIVD");
divd_1(); /* div through a register */
divd_2(); /* div through the cache */
divd_3(); /* wait 1 NOP before storeing */
for( nop_cnt = 3; nop_cnt > 0; nop_cnt-- )
divd_3(nop_cnt); /* wait 6 ... 2 NOPs */
divd_4(); /* wait 3 NOPs */
divd_5(); /* wait 1 NOP before storing */
divd_6(); /* register stability test */
divd_7(); /* PSL stability test */
asm("jmp *return"); /* return to the test monitor */
}
/************************************************************************
*
* SUBTEST 1 - divide through a register
*
************************************************************************/
divd_1()
{
force_loop = FALSE;
subtest = 1;
for( index = 0; index < max_divd_1_index; index++ ) {
dbl_ld_acc = divd_1_data[index].op_1; /* get operand 1 */
dbl_value_1 = divd_1_data[index].op_2; /* get operand 2 */
dbl_expected = divd_1_data[index].exp; /* get expected result */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
* The force loop flag is set after the first error.
*/
asm("_divd_1_lp1:");
asm("movl _dbl_ld_acc,r2"); /* move operand 1 to r2/r3 */
asm("movl _dbl_ld_acc+4,r3");
asm("movl _dbl_value_1,r4"); /* move operand 2 to r4/r5 */
asm("movl _dbl_value_1+4,r5");
asm("ldd r2"); /* load the 1st operand */
asm("divd r4"); /* divide the 2nd operand */
asm("std _dbl_st_acc"); /* store the result */
if( force_loop )
asm("brb _divd_1_lp1");; /* loop on the error */
/*
* end error loop - test the results
*/
if( (dbl_st_acc.m != dbl_expected.m) || /* verify the results */
(dbl_st_acc.l != dbl_expected.l) ) {
errcnt++; /* bump the error count */
if( prt_error ) {
writes(" \n"); /* start a new print line */
writes("cycle: ");
writed( cycle );
writes(" DIVD test ");
writed( test_no );
writes(", subtest 1 (Reg. Data) - BAD FINAL ACC\n");
print_divd_data();
}
if( halt_flg )
divd_er_halt( BAD_ACC_HLT ); /* halt on the error */
if( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("brw _divd_1_lp1");; /* and loop on the error */
} /* end of loop on error */
} /* end of compare error */
} /* end of WHILE loop */
} /* end of subtest 1 */
/************************************************************************
*
* SUBTEST 2 - divide through memory
*
************************************************************************/
divd_2()
{
force_loop = FALSE;
subtest = 2;
for( index = 0; index < max_divd_1_index; index++ ) {
dbl_ld_acc = divd_1_data[index].op_1; /* get operand 1 */
dbl_value_1 = divd_1_data[index].op_2; /* get operand 2 */
dbl_expected = divd_1_data[index].exp; /* get expected result */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
* The force loop flag is set after the first error.
*/
asm("_divd_2_lp1:");
asm("ldd _dbl_ld_acc"); /* load the 1st operand */
asm("divd _dbl_value_1"); /* divide the 2nd operand */
asm("std _dbl_st_acc"); /* store the result */
if( force_loop )
asm("brb _divd_2_lp1");; /* loop on the error */
/*
* end error loop - test the results
*/
if( (dbl_st_acc.m != dbl_expected.m) || /* verify the results */
(dbl_st_acc.l != dbl_expected.l) ) {
errcnt++; /* bump the error count */
if( prt_error ) {
writes(" \n"); /* start a new print line */
writes("cycle: ");
writed( cycle );
writes(" DIVD test ");
writed( test_no );
writes(", subtest 2 (Cache Data) - BAD FINAL ACC\n");
print_divd_data();
}
if( halt_flg )
divd_er_halt( BAD_ACC_HLT ); /* halt on the error */
if( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("brw _divd_2_lp1");; /* and loop on the error */
} /* end of loop on error */
} /* end of compare error */
} /* end of WHILE loop */
} /* end of subtest 2 */
/****************************************************************************
*
* SUBTEST 3 - Wait 2n NOPs before storing the results
*
****************************************************************************/
divd_3( count )
int count; /* wait "count" * 2 NOPs */
{
force_loop = FALSE;
subtest = 3;
sgl_dummy2 = count; /* get the NOP count */
for( index = 0; index < max_divd_1_index; index++ ) {
dbl_ld_acc = divd_1_data[index].op_1; /* get operand 1 */
dbl_value_1 = divd_1_data[index].op_2; /* get operand 2 */
dbl_expected = divd_1_data[index].exp; /* get expected result */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
* The force loop flag is set after the first error.
*/
asm("_divd_3_lp1:");
asm("movl _sgl_dummy2,r0"); /* set the NOP count */
asm("ldd _dbl_ld_acc"); /* load the 1st operand */
asm("nop"); /* delay */
asm("divd _dbl_value_1"); /* divide the 2nd operand */
asm("1:");
asm("decl r0"); /* decrement the NOP count */
asm("bneq 1b"); /* till the count = 0 */
asm("std _dbl_st_acc"); /* store the result */
if( force_loop )
asm("brb _divd_3_lp1");; /* loop on the error */
/*
* end error loop - test the results
*/
if( (dbl_st_acc.m != dbl_expected.m) || /* verify the results */
(dbl_st_acc.l != dbl_expected.l) ) {
errcnt++; /* bump the error count */
if( prt_error ) {
writes(" \n"); /* start a new print line */
writes("cycle: ");
writed( cycle );
writes(" DIVD test ");
writed( test_no );
writes(", subtest 3 (wait ");
sgl_dummy1 = 2*count;
writed( sgl_dummy1 ); /* write the NOP count */
writes(" NOPs) - BAD FINAL ACC\n");
print_divd_data();
}
if( halt_flg )
divd_er_halt( BAD_ACC_HLT ); /* halt on the error */
if( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("brw _divd_3_lp1");; /* and loop on the error */
} /* end of loop on error */
} /* end of compare error */
} /* end of WHILE loop */
} /* end of subtest 3 */
/************************************************************************
*
* SUBTEST 4 - Wait 2 NOPs before storing the results
*
************************************************************************/
divd_4()
{
force_loop = FALSE;
subtest = 4;
for( index = 0; index < max_divd_1_index; index++ ) {
dbl_ld_acc = divd_1_data[index].op_1; /* get operand 1 */
dbl_value_1 = divd_1_data[index].op_2; /* get operand 2 */
dbl_expected = divd_1_data[index].exp; /* get expected result */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
* The force loop flag is set after the first error.
*/
asm("_divd_4_lp1:");
asm("ldd _dbl_ld_acc"); /* load the 1st operand */
asm("nop"); /* delay */
asm("divd _dbl_value_1"); /* divide the 2nd operand */
asm("nop"); /* delay before ... */
asm("nop"); /* ... storing the result */
asm("std _dbl_st_acc"); /* store the result */
if( force_loop )
asm("brb _divd_4_lp1");; /* loop on the error */
/*
* end error loop - test the results
*/
if( (dbl_st_acc.m != dbl_expected.m) || /* verify the results */
(dbl_st_acc.l != dbl_expected.l) ) {
errcnt++; /* bump the error count */
if( prt_error ) {
writes(" \n"); /* start a new print line */
writes("cycle: ");
writed( cycle );
writes(" DIVD test ");
writed( test_no );
writes(", subtest 4 (2 NOPs) - BAD FINAL ACC\n");
print_divd_data();
}
if( halt_flg )
divd_er_halt( BAD_ACC_HLT ); /* halt on the error */
if( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("brw _divd_4_lp1");; /* and loop on the error */
} /* end of loop on error */
} /* end of compare error */
} /* end of WHILE loop */
} /* end of subtest 4 */
/************************************************************************
*
* SUBTEST 5 - Wait 1 NOP before storing the results
*
************************************************************************/
divd_5()
{
force_loop = FALSE;
subtest = 5;
for( index = 0; index < max_divd_1_index; index++ ) {
dbl_ld_acc = divd_1_data[index].op_1; /* get operand 1 */
dbl_value_1 = divd_1_data[index].op_2; /* get operand 2 */
dbl_expected = divd_1_data[index].exp; /* get expected result */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
* The force loop flag is set after the first error.
*/
asm("_divd_5_lp1:");
asm("ldd _dbl_ld_acc"); /* load the 1st operand */
asm("nop"); /* delay */
asm("divd _dbl_value_1"); /* divide the 2nd operand */
asm("nop"); /* delay before storing */
asm("std _dbl_st_acc"); /* store the result */
if( force_loop )
asm("brb _divd_5_lp1");; /* loop on the error */
/*
* end error loop - test the results
*/
if( (dbl_st_acc.m != dbl_expected.m) || /* verify the results */
(dbl_st_acc.l != dbl_expected.l) ) {
errcnt++; /* bump the error count */
if( prt_error ) {
writes(" \n"); /* start a new print line */
writes("cycle: ");
writed( cycle );
writes(" DIVD test ");
writed( test_no );
writes(", subtest 5 (1 NOP) - BAD FINAL ACC\n");
print_divd_data();
}
if( halt_flg )
divd_er_halt( BAD_ACC_HLT ); /* halt on the error */
if( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("brw _divd_5_lp1");; /* and loop on the error */
} /* end of loop on error */
} /* end of compare error */
} /* end of WHILE loop */
} /* end of subtest 5 */
/************************************************************************
*
* SUBTEST 6 - Check for register corruption
*
************************************************************************/
divd_6()
{
force_loop = FALSE; /* clear force_loop flg */
subtest = 6;
fill_reg_buf( load_regs ); /* get patterns for regs */
index = 0;
dbl_ld_acc = divd_1_data[0].op_1; /* get operand 1 */
dbl_value_1 = divd_1_data[0].op_2; /* get operand 2 */
dbl_expected = divd_1_data[0].exp; /* get expected result */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
* The force loop flag is set after the first error.
*/
asm("_divd_6_lp1:");
asm("ldd _dbl_ld_acc"); /* LOAD the accumulator */
asm("nop");
asm("loadr $0x1fff,_load_regs"); /* load regs 0 - 12 */
asm("nop");
asm("divd _dbl_value_1"); /* do the divide */
asm("nop");
asm("storer $0x1fff,_store_regs"); /* store regs 0 - 12 */
asm("std _dbl_st_acc"); /* save the accumulator */
if( force_loop )
asm("brb _divd_6_lp1");; /* loop on the error */
/*
* Now compare the stored register values to those that were loaded
*/
index2 = 0;
while( (load_regs[index2] == store_regs[index2]) && (index2 < 13) )
index2++; /* check reg values */
if( index2 < 13 ) { /* error if index2 < 13 */
errcnt++; /* bump the error count */
if( prt_error ) {
writes(" \n"); /* start a new print line */
writes("cycle: ");
writed( cycle );
writes(" DIVD test ");
writed( test_no );
writes(", subtest 6 - A REGISTER WAS CHANGED\n");
print_divd_data(); /* print the operands */
writes("register "); /* print the information */
writed( index2 ); /* about the corrupted */
writes(" = "); /* register */
write32h( store_regs[index2] );
writes(", should be = ");
write32h( load_regs[index2] );
writes("\n");
}
if( halt_flg )
divd_er_halt( BAD_REG_HLT ); /* halt on the error */
if( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("brw _divd_6_lp1");; /* and loop on the error */
} /* end of loop on error */
} /* end of register corruption error */
} /* end of subtest 6 */
/************************************************************************
*
* SUBTEST 7 - Check for PSL corruption
*
************************************************************************/
divd_7()
{
force_loop = FALSE; /* clear force_loop flg */
subtest = 7;
fill_reg_buf( load_regs ); /* get patterns for regs */
for( index = 0; index < 3; index++ ) {
dbl_ld_acc = divd_1_data[index].op_1; /* get operand 1 */
dbl_value_1 = divd_1_data[index].op_2; /* get operand 2 */
dbl_expected = divd_1_data[index].exp; /* get expected */
sgl_dummy1 = status_array[status_index]; /* status = +, -, 0 */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
* The force loop flag is set after the first error.
*/
asm("_divd_7_lp1:");
asm("ldd _dbl_ld_acc"); /* LOAD the accumulator */
asm("nop");
asm("tstl _sgl_dummy1"); /* set the PSL status */
asm("movpsl _init_psl"); /* save the initial PSL */
asm("divd _dbl_value_1"); /* do the divide */
asm("nop");
asm("movpsl _psl_val"); /* save the final PSL */
asm("std _dbl_st_acc"); /* save the accumulator */
if( force_loop )
asm("brb _divd_7_lp1");; /* loop on the error */
/*
* Now compare the final PSL to the initial PSL -they should be the same
*/
exp_psl = init_psl;
if( psl_val != exp_psl ) {
errcnt++; /* bump the error count */
if( prt_error ) {
writes(" \n"); /* start a new print line */
writes("cycle: ");
writed( cycle );
writes(" DIVD test ");
writed( test_no );
writes(", subtest 7 - INCORRECT FINAL PSL\n");
print_divd_data(); /* print the operands */
writes("initial PSL = ");
write32h( init_psl );
writes(", final PSL = ");
write32h( psl_val );
writes(", expected PSL = ");
write32h( exp_psl );
writes("\n");
}
if( halt_flg )
divd_er_halt( BAD_PSL_HLT ); /* halt on the error */
if( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("brw _divd_7_lp1");; /* and loop on the error */
} /* end of loop on error */
} /* end of PSL corruption error */
} /* end of WHILE loop */
} /* end of subtest 7 */
/**************************************************************************
*
* PRINT THE DATA AND STORE RESULTS
*
* initial Acc = xxxxxxxx xxxxxxxx, stored = xxxxxxxx xxxxxxxx, index = xx
* operand = xxxxxxxx xxxxxxxx, expected = xxxxxxxx xxxxxxxx
**************************************************************************/
print_divd_data()
{
writes("initial Acc = ");
write32h( dbl_ld_acc.m );
writec(' ');
write32h( dbl_ld_acc.l );
writes(", stored = ");
write32h( dbl_st_acc.m );
writec(' ');
write32h( dbl_st_acc.l );
writes(", index = ");
writed( index );
writec('\n');
writes(" operand = ");
write32h( dbl_value_1.m );
writec(' ');
write32h( dbl_value_1.l );
writes(", expected = ");
write32h( dbl_expected.m );
writec(' ');
write32h( dbl_expected.l );
writec('\n');
}
/**************************************************************************
*
* HALT ON ERROR ROUTINE
*
**************************************************************************/
divd_er_halt( halt_code )
int halt_code;
{
sgl_value_1 = dbl_ld_acc.m;
sgl_value_2 = dbl_ld_acc.l;
sgl_value_3 = dbl_value_1.m;
sgl_value_4 = dbl_value_1.l;
sgl_value_5 = dbl_st_acc.m;
sgl_value_6 = dbl_st_acc.l;
sgl_dummy1 = halt_code; /* get the error type */
asm("movl _test_no,r0"); /* r0 = test number */
asm("movl _subtest,r1"); /* r1 = subtest number */
asm("movl _sgl_dummy1,r2"); /* r2 = error code */
asm("movl _cycle,r3"); /* r3 = cycle count */
asm("movl _sgl_value_1,r4"); /* r4 = MS operand 1 */
asm("movl _sgl_value_2,r5"); /* r5 = LS operand 1 */
asm("movl _sgl_value_3,r6"); /* r6 = MS operand 2 */
asm("movl _sgl_value_4,r7"); /* r7 = LS operand 2 */
asm("movl _sgl_value_5,r8"); /* r8 = MS stored */
asm("movl _sgl_value_6,r9"); /* r9 = LS stored */
if( halt_code == BAD_ACC_HLT ) {
sgl_value_1 = dbl_expected.m;
sgl_value_2 = dbl_expected.l;
asm("movl _sgl_value_1,r10"); /* r10 = MS expected */
asm("movl _sgl_value_2,r11"); /* r11 = LS expected */
asm("movl _index2,r12"); /* r12 = data index */
} else
if( halt_code == BAD_REG_HLT ) {
sgl_dummy1 = load_regs[index2];
sgl_dummy2 = store_regs[index2];
asm("movl _index2,r10"); /* r10 = bad register # */
asm("movl _sgl_dummy2,r11"); /* r11 = actual value */
asm("movl _sgl_dummy1,r12"); /* r12 = expected value */
} else
if( halt_code == BAD_PSL_HLT ) {
asm("movl _init_psl,r10"); /* r10 = initial PSL */
asm("movl _psl_val,r11"); /* r11 = final PSL */
asm("movl _exp_psl,r12"); /* r12 = expected PSL */
};
asm("halt"); /* HALT ... */
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.