|
|
Power 6/32 Unix version 1.21
#include "fpp_defs.h"
/***************************************************************************
*
* MULL3 -MULTIPLY INTEGER 3 INSTRUCTION TEST
*
*****************************************************************************/
mull3()
{
asm(".globl _mull3_t");
asm("_mull3_t:"); /* entry address */
if( (cycle == 1) && (prt_hdrs) ) /* print headers on 1st cycle */
{
writes(" MULL3");
}
mull3_1(); /* register data / SGL acc. */
mull3_2(); /* memory data / DBL acc. */
mull3_3(); /* register corruption test */
mull3_4(); /* PSL corruption test */
mull3_5(); /* pipelined entry test */
mull3_6(); /* pipelined exit test */
asm("jmp *return"); /* return to the test monitor */
}
/************************************************************************
*
* SUBTEST 1 - register addressing / single precsion accumulator
*
************************************************************************/
mull3_1()
{
force_loop = FALSE;
subtest = 1;
for( index = 0; index < max_mull_1_index; index++ ) {
sgl_value_1 = mull_1_data[index].op_1; /* get operand 1 */
sgl_value_2 = mull_1_data[index].op_2; /* get operand 2 */
sgl_value_4 = mull_1_data[index].exp; /* get expected results */
sgl_ld_acc = 0x12345678; /* set acc data pattern */
sgl_expected = sgl_ld_acc; /* final Acc expected */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
*/
asm("_mull3_1_lp1:");
asm("movl _sgl_value_1,r3"); /* move the 1st data to r3 */
asm("movl _sgl_value_2,r4"); /* move the 2nd data to r4 */
asm("ldf _sgl_ld_acc"); /* load the acc */
asm("mull3 r3,r4,r5"); /* do the multiply */
asm("nop");
asm("stf _sgl_st_acc"); /* save the acc */
if( force_loop )
asm("brb _mull3_1_lp1");;
asm("movl r5,_sgl_value_3");
if( sgl_expected != sgl_st_acc ) { /* COMPARE the values */
errcnt++; /* bump the error count */
if ( prt_error ) {
print_mull3_error("(Reg. Data) -THE ACC WAS MODIFIED");
writes("initial Acc = ");
write32h( sgl_ld_acc );
writes(", final Acc = ");
write32h( sgl_st_acc );
writes("\n expected Acc = ");
write32h( sgl_expected );
writec('\n');
}
if ( halt_flg ) /* halt on error? */
mull3_halt( 4 );
if ( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mull3_1_lp1"); /* and loop */
} /* end of loop-on-error */
} /* end of acc corr error */
if( sgl_value_4 != sgl_value_3 ) /* COMPARE the values */
{
errcnt++; /* bump the error count */
if ( prt_error ) {
print_mull3_error("(Reg. Data) -BAD MULTIPLY RESULT");
}
if ( halt_flg ) /* halt on error? */
mull3_halt( 1 );
if ( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mull3_1_lp1"); /* and loop */
} /* end of loop-on-error */
} /* end of multiply error */
}
} /* end of subtest 1 */
/************************************************************************
*
* SUBTEST 2 - cache addressing / double precsion accumulator
*
************************************************************************/
mull3_2()
{
force_loop = FALSE;
subtest = 2;
for( index = 0; index < max_mull_1_index; index++ ) {
sgl_value_1 = mull_1_data[index].op_1; /* get operand 1 */
sgl_value_2 = mull_1_data[index].op_2; /* get operand 2 */
sgl_value_4 = mull_1_data[index].exp; /* get expected results */
dbl_ld_acc.m = 0x12345678; /* set acc data pattern */
dbl_ld_acc.l = 0x9abcdef0;
dbl_expected.m = dbl_ld_acc.m; /* final Acc expected */
dbl_expected.l = dbl_ld_acc.l;
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
*/
asm("_mull3_2_lp1:");
asm("ldd _dbl_ld_acc"); /* load the acc */
asm("mull3 _sgl_value_1,_sgl_value_2,_sgl_value_3");
asm("nop");
asm("std _dbl_st_acc"); /* save the acc */
if( force_loop )
asm("brb _mull3_2_lp1");;
if( (dbl_expected.m != dbl_st_acc.m) || /* COMPARE the Acc */
(dbl_expected.l != dbl_st_acc.l) ) {
errcnt++; /* bump the error count */
if ( prt_error ) {
print_mull3_error("(Memory data) -THE ACC WAS MODIFIED");
writes("initial Acc = ");
write32h( dbl_ld_acc.m );
writec(' ');
write32h( dbl_ld_acc.l );
writes(", final Acc = ");
write32h( dbl_st_acc.m );
writec(' ');
write32h( dbl_st_acc.l );
writes("\n expected Acc = ");
write32h( dbl_expected.m );
writec(' ');
write32h( dbl_expected.l );
writec('\n');
}
if ( halt_flg ) /* halt on error? */
mull3_halt( 4 );
if ( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mull3_2_lp1"); /* and loop */
} /* end of loop-on-error */
} /* end of acc corr error */
if( sgl_value_4 != sgl_value_3 ) /* COMPARE the values */
{
errcnt++; /* bump the error count */
if ( prt_error ) {
print_mull3_error("(Memory data) -BAD MULTIPLY RESULT");
}
if ( halt_flg ) /* halt on error? */
mull3_halt( 1 );
if ( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mull3_2_lp1"); /* and loop */
} /* end of loop-on-error */
} /* end of multiply error */
}
} /* end of subtest 2 */
/************************************************************************
*
* SUBTEST 3 - register corruption test
*
************************************************************************/
mull3_3()
{
force_loop = FALSE;
subtest = 2;
fill_reg_buf( load_regs ); /* get pattern for registers */
for( index = 0; index < max_mull_1_index; index++ ) {
sgl_value_1 = mull_1_data[index].op_1; /* get operand 1 */
sgl_value_2 = mull_1_data[index].op_2; /* get operand 2 */
sgl_value_4 = mull_1_data[index].exp; /* get expected results */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
*/
asm("_mull3_3_lp1:");
asm("loadr $0x1fff,_load_regs"); /* load regs 0 - 12 */
asm("mull3 _sgl_value_1,_sgl_value_2,_sgl_value_3");
asm("nop");
asm("storer $0x1fff,_store_regs"); /* store regs 0 - 12 */
if( force_loop )
asm("brb _mull3_3_lp1");
/*
* Now check the result
*/
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 ) {
print_mull3_error(" -A REGISTER WAS MODIFIED");
writes("register ");
writeh( index2 );
writes(" = ");
write32h( store_regs[index2] );
writes(", should be = ");
write32h( load_regs[index2] );
writec('\n');
}
if ( halt_flg ) /* halt on error? */
mull3_halt( 2 );
if ( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mull3_3_lp1"); /* and loop */
}; /* end of loop-on-error */
} /* end of multiply error */
}
} /* end of subtest 3 */
/************************************************************************
*
* SUBTEST 4 - PSL corruption test
*
************************************************************************/
mull3_4()
{
force_loop = FALSE;
subtest = 4;
status_index = 0;
for( index = 0; index < max_mull_1_index; index++ ) {
sgl_value_1 = mull_1_data[index].op_1; /* get operand 1 */
sgl_value_2 = mull_1_data[index].op_2; /* get operand 2 */
sgl_value_4 = mull_1_data[index].exp; /* get expected results */
sgl_dummy1 = status_array[status_index]; /* status = +, -, 0 */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
*/
asm("_mull3_4_lp1:");
asm("tstl _sgl_dummy1");
asm("movpsl _init_psl"); /* save the initial PSL */
asm("mull3 _sgl_value_1,_sgl_value_2,_sgl_value_3");
asm("movpsl _psl_val"); /* save the final PSL */
if( force_loop )
asm("brb _mull3_4_lp1");
/*
* Now check the result
*/
exp_psl = init_psl & 0xffffff3; /* strip off the PSL status */
if( sgl_value_4 < 0 ) /* check the MULL result */
exp_psl |= PSL_N; /* set the NEGATIVE bit */
if( !sgl_value_4 )
exp_psl |= PSL_Z; /* set the ZERO bit */
if( psl_val != exp_psl ) { /* was the final PSL correct */
errcnt++; /* bump the error count */
if ( prt_error ) {
print_mull3_error(" -INCORRECT FINAL PSL");
writes("initial PSL = ");
write32h( init_psl );
writes(", final PSL = ");
write32h( psl_val );
writes(", expected PSL = ");
write32h( exp_psl );
writec('\n');
}
if ( halt_flg ) /* halt on error? */
mull3_halt( 3 );
if ( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mull3_4_lp1"); /* and loop */
}; /* end of loop-on-error */
}; /* end of error */
if( ++status_index >= 3 )
status_index = 0;
}
} /* end of subtest 4 */
/************************************************************************
*
* SUBTEST 5 - Pipelined Entry test
*
************************************************************************/
mull3_5()
{
force_loop = FALSE;
subtest = 5;
for( index = 0; index < max_mull_1_index; index++ ) {
sgl_value_1 = mull_1_data[index].op_1; /* get operand 1 */
sgl_value_2 = mull_1_data[index].op_2; /* get operand 2 */
sgl_value_4 = mull_1_data[index].exp; /* get expected results */
sgl_ld_acc = 0x12345678; /* set acc data pattern */
sgl_expected = sgl_ld_acc; /* final Acc expected */
sgl_value_10 = 0x40800000; /* floating "1.0" */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
*/
asm("_mull3_5_lp1:");
asm("ldf _sgl_ld_acc"); /* load the acc */
asm("mulf _sgl_value_10"); /* do a floating multiply */
asm("mull3 _sgl_value_1,_sgl_value_2,_sgl_value_3");
asm("stf _sgl_st_acc"); /* save the acc */
if( force_loop )
asm("brb _mull3_5_lp1");;
if( sgl_expected != sgl_st_acc ) { /* COMPARE the values */
errcnt++; /* bump the error count */
if ( prt_error ) {
print_mull3_error("(Piped Entry) -BAD FINAL ACC");
writes("initial Acc = ");
write32h( sgl_ld_acc );
writes(", final Acc = ");
write32h( sgl_st_acc );
writes("\nFPP operand = ");
write32h( sgl_value_10 );
writes(", expected Acc = ");
write32h( sgl_expected );
writec('\n');
}
if ( halt_flg ) /* halt on error? */
mull3_halt( 5 );
if ( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mull3_5_lp1"); /* and loop */
} /* end of loop-on-error */
} /* end of acc corr error */
if( sgl_value_4 != sgl_value_3 ) /* COMPARE the values */
{
errcnt++; /* bump the error count */
if ( prt_error ) {
print_mull3_error("(Piped Entry) -BAD MULTIPLY RESULT");
}
if ( halt_flg ) /* halt on error? */
mull3_halt( 1 );
if ( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mull3_5_lp1"); /* and loop */
} /* end of loop-on-error */
} /* end of multiply error */
}
} /* end of subtest 5 */
/************************************************************************
*
* SUBTEST 6 - Pipelined Exit test
*
************************************************************************/
mull3_6()
{
force_loop = FALSE;
subtest = 6;
for( index = 0; index < max_mull_1_index; index++ ) {
sgl_value_1 = mull_1_data[index].op_1; /* get operand 1 */
sgl_value_2 = mull_1_data[index].op_2; /* get operand 2 */
sgl_value_4 = mull_1_data[index].exp; /* get expected results */
sgl_ld_acc = 0x40800000; /* floating "1.0" */
sgl_value_10 = 0x12345678; /* set acc data pattern */
sgl_expected = sgl_value_10; /* final Acc expected */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
*/
asm("_mull3_6_lp1:");
asm("ldf _sgl_ld_acc"); /* load the acc */
asm("mull3 _sgl_value_1,_sgl_value_2,_sgl_value_3");
asm("mulf _sgl_value_10"); /* do a floating multiply */
asm("stf _sgl_st_acc"); /* save the acc */
if( force_loop )
asm("brb _mull3_6_lp1");;
if( sgl_expected != sgl_st_acc ) { /* COMPARE the values */
errcnt++; /* bump the error count */
if ( prt_error ) {
print_mull3_error("(Piped Exit) -BAD FINAL ACC");
writes("initial Acc = ");
write32h( sgl_ld_acc );
writes(", final Acc = ");
write32h( sgl_st_acc );
writes("\nFPP operand = ");
write32h( sgl_value_10 );
writes(", expected Acc = ");
write32h( sgl_expected );
writec('\n');
}
if ( halt_flg ) /* halt on error? */
mull3_halt( 5 );
if ( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mull3_6_lp1"); /* and loop */
} /* end of loop-on-error */
} /* end of acc corr error */
if( sgl_value_4 != sgl_value_3 ) /* COMPARE the values */
{
errcnt++; /* bump the error count */
if ( prt_error ) {
print_mull3_error("(Piped Exit) -BAD MULTIPLY RESULT");
}
if ( halt_flg ) /* halt on error? */
mull3_halt( 1 );
if ( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _mull3_6_lp1"); /* and loop */
} /* end of loop-on-error */
} /* end of multiply error */
}
} /* end of subtest 6 */
/*****************************************************************************
*
* Print an error message of the form:
*
* cycle: xx MULL3 test xx, subtest xx <"your message here">
* operand 1 = xxxxxxxx, result = xxxxxxxx, data index = xx
* operand 2 = xxxxxxxx, expected = xxxxxxxx
*
*****************************************************************************/
print_mull3_error(msg)
char *msg; /* addressing mode msg */
{
writes(" \n"); /* start a new print line */
writes("cycle: ");
writed( cycle );
writes(" MULL3 test ");
writed( test_no );
writes(", subtest ");
writed( subtest );
writes(" ");
writes( msg );
writes("\n operand 1 = ");
write32h( sgl_value_1 );
writes(", result = ");
write32h( sgl_value_3 );
writes(", data index = ");
writed( index );
writes("\n operand 2 = ");
write32h( sgl_value_2 );
writes(", expected = ");
write32h( sgl_value_4 );
writec('\n');
}
/***************************************************************************
*
* HALT ON AN ERROR
*
***************************************************************************/
mull3_halt( code )
int code; /* error code to use */
{
sgl_dummy1 = code; /* save the error code */
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 = operand 1 */
asm("movl _sgl_value_2,r5"); /* r5 = operand 2 */
asm("movl _sgl_value_3,r6"); /* r6 = MULL3's result */
if( code == 1 ) {
asm("movl _sgl_value_4,r7"); /* r7 = expected result */
asm("movl _index,r8");; /* r8 = data index */
}
else if( code == 2 ) { /* corrupted register */
sgl_dummy1 = store_regs[index2]; /* get the actual reg data */
sgl_dummy2 = load_regs[index2]; /* get the data expected */
asm("movl _index2,r7"); /* r7 = register number */
asm("movl _sgl_dummy1,r8"); /* r8 = final reg value */
asm("movl _sgl_dummy2,r9"); /* r9 = expected value */
}
else if( code == 3 ) { /* corrupted PSL */
asm("movl _init_psl,r7"); /* r7 = initial PSL */
asm("movl _psl_val,r8"); /* r8 = final PSL */
asm("movl _exp_psl,r9"); /* r9 = expected PSL */
}
else if( code == 4 ) { /* corrupted Acc */
if( subtest == 1 ) { /* single precision */
dbl_ld_acc.m = sgl_ld_acc;
dbl_ld_acc.l = 0;
dbl_st_acc.m = sgl_st_acc;
dbl_st_acc.l = 0;
dbl_expected.m = sgl_expected;
dbl_expected.l = 0;
};
asm("movl _index,r7"); /* r7 = data index */
asm("movl _dbl_ld_acc,r8"); /* r8 = MS initial Acc. */
asm("movl _dbl_ld_acc+4,r9"); /* r9 = LS initial Acc. */
asm("movl _dbl_st_acc,r10"); /* r10 = MS final Acc. */
asm("movl _dbl_st_acc+4,r11"); /* r11 = LS final Acc. */
asm("movl _dbl_expected,r12"); /* r12 = MS expected Acc. */
asm("movl _dbl_expected+4,r13"); /* r13 = LS expected Acc. */
}
else if( code == 5 ) { /* bad final Acc */
asm("movl _index,r7"); /* r7 = data index */
asm("movl _sgl_ld_acc,r8"); /* r8 = initial Acc. */
asm("movl _sgl_value_10,r9"); /* r9 = fpp operand */
asm("movl _sgl_st_acc,r10"); /* r10 = final Acc. */
asm("movl _sgl_expected,r11"); /* r11 = expected Acc. */
};
asm("halt"); /* HALT ... */
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.