|
|
Power 6/32 Unix version 1.21
#include "fpp_defs.h"
/***************************************************************************
*
* PUSHD - PUSH FLOATING POINT DOUBLE-PRECISION OPERAND ONTO STACK
*
* PUSHD TEST MONITOR
*
* Load a double precision operand into the accumulator and then push it
* onto the stack.
***************************************************************************/
pushd()
{
asm(".globl _pushd_t");
asm("_pushd_t:"); /* entry address */
if( (cycle == 1) && (prt_hdrs) ) /* print headers on 1st cycle */
writes(" PUSHD");
pushd_1(); /* ldd/pushd data patterns */
pushd_2(); /* register corruption test */
if( !no_fpp_wcs )
pushd_3(); /* PSL test */
asm("jmp *return"); /* return to the test monitor */
}
/************************************************************************
*
* SUBTEST 1 - load / push / pop / compare
*
************************************************************************/
pushd_1()
{
force_loop = FALSE;
index = 0;
subtest = 1;
do {
dbl_ld_acc = ldd_1_data[index].ld; /* get data to load */
dbl_expected = ldd_1_data[index].exp; /* get expected results */
if( !(dbl_ld_acc.m & 0x7f800000) ) {
dbl_expected.m = 0;
dbl_expected.l = 0; /* ignore bad 0's */
}
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
* The force loop flag is set after the first error.
*/
asm("_pushd_1_lp1:");
asm("moval (sp),_pre_event_sp"); /* save the pre-push SP */
asm("ldd _dbl_ld_acc"); /* LOAD the (dbl) value */
asm("pushd"); /* PUSH the data */
asm("moval (sp),_post_event_sp"); /* save the post-push SP */
asm("movl (sp)+,_pop_val_1"); /* POP the MS word */
asm("movl (sp)+,_pop_val_2"); /* POP the LS word */
asm("std _dbl_st_acc"); /* save the acc */
if( force_loop )
asm("brb _pushd_1_lp1"); /* run the loop again */
sgl_dummy1 = pre_event_sp - 8; /* get expected final SP */
sgl_value_7 = post_event_sp - pre_event_sp; /* get amount pushed */
if( (dbl_expected.m != pop_val_1) || /* verify stack data */
(dbl_expected.l != pop_val_2) ||
(post_event_sp != sgl_dummy1) ) {
errcnt++; /* bump the error count */
if ( prt_error ) {
writes("\ncycle: ");
writed( cycle );
writes(" PUSHD test ");
writed( test_no );
writes(", subtest 1 (Cache Data) - WRONG DATA PUSHED\n");
print_pushd_data();
writes(", data pushed = ");
write32h( pop_val_1 );
writec(' ');
write32h( pop_val_2 );
writes(", index = ");
writed( index );
writec('\n');
writes(" final Acc = ");
write32h( dbl_st_acc.m );
writec(' ');
write32h( dbl_st_acc.l );
writes(", exp. data = ");
write32h( dbl_expected.m );
writec(' ');
write32h( dbl_expected.l );
writec('\n');
}
if ( halt_flg ) /* halt on error? */
pushd_er_halt( BAD_STORE_HLT );
if ( loop_on_err )
{
force_loop = TRUE; /* set the force loop flag */
asm("brw _pushd_1_lp1"); /* and loop on the error */
} /* end of loop-on-error */
} /* end of data compare error */
if( ( post_event_sp - pre_event_sp ) == 2 ) {/* ver stack data */
errcnt++; /* bump the error count */
if ( prt_error ) {
writes("\ncycle: ");
writed( cycle );
writes(" PUSHD test ");
writed( test_no );
writes(", subtest 1 (Data Pat.) - WRONG PUSH COUNT\n");
print_pushd_data();
writes(", ");
writed( sgl_value_7 );
writes(" longwords pushed, ");
writes("2 expected");
writec('\n');
writes(" final Acc = ");
write32h( dbl_st_acc.m );
writec(' ');
write32h( dbl_st_acc.l );
writec('\n');
}
if ( halt_flg ) /* halt on error? */
pushd_er_halt( PUSH_CNT_HLT );
if ( loop_on_err )
{
force_loop = TRUE; /* set the force loop flag */
asm("brw _pushd_1_lp1"); /* and loop on the error */
} /* end of loop-on-error */
} /* end of push count error */
if( ( dbl_st_acc.m != dbl_expected.m ) &&
( dbl_st_acc.l != dbl_expected.l ) ) {
errcnt++; /* bump the error count */
if ( prt_error )
{
writes("\ncycle: ");
writed( cycle );
writes(" PUSHD test ");
writed( test_no );
writes(", subtest 1 (Acc. Corr.) - BAD FINAL ACC\n");
print_pushd_data();
writes(", data pushed = ");
write32h( pop_val_1 );
writec(' ');
write32h( pop_val_2 );
writes(", index = ");
writed( index );
writec('\n');
writes(" final Acc = ");
write32h( dbl_st_acc.m );
writec(' ');
write32h( dbl_st_acc.l );
writes(", Acc expected = ");
write32h( dbl_expected.m );
writec(' ');
write32h( dbl_expected.l );
writec('\n');
}
if ( halt_flg ) /* halt on error? */
pushd_er_halt( BAD_ACC_HLT );
if ( loop_on_err )
{
force_loop = TRUE; /* set the force loop flag */
asm("brw _pushd_1_lp1"); /* and loop on the error */
} /* end of loop-on-error */
} /* end of acc corr error */
} while( index++ < max_ldd_1_index );
} /* end of subtest 1 */
/************************************************************************
*
* SUBTEST 2 - register corruption test
*
************************************************************************/
pushd_2()
{
force_loop = FALSE;
subtest = 2;
index = 0;
do
{
fill_reg_buf( load_regs ); /* Set the values that */
dbl_ld_acc = ldd_1_data[index].ld; /* get data to load */
dbl_expected = ldd_1_data[index].exp; /* get expected results */
/*
* If LOOP ON ERROR is set, this is the loop for this subtest.
* The force loop flag is set after the first error.
*/
asm("_pushd_2_lp1:");
asm("ldd _dbl_ld_acc"); /* LOAD the (dbl) value */
asm("loadr $0x1fff,_load_regs"); /* load regs 0 - 12 */
asm("nop");
asm("pushd"); /* push the accumulator */
asm("nop");
asm("storer $0x1fff,_store_regs"); /* store regs 0 - 12 */
if( force_loop )
asm("brb _pushd_2_lp1");; /* run the loop again */
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("\ncycle: ");
writed( cycle );
writes(" PUSHD test ");
writed( test_no );
writes(", subtest 2 - A REGISTER WAS MODIFIED\n");
print_pushd_data();
writes(", pushed = ");
write32h( dbl_ld_acc.m );
writec(' ');
write32h( dbl_ld_acc.l );
writec('\n');
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 ) /* halt on error? */
pushd_er_halt( BAD_REG_HLT );
if ( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _pushd_2_lp1"); /* and loop */
} /* end of loop-on-error */
} /* end of compare error */
} while( index++ < max_ldd_1_index );
} /* end of subtest 2 */
/************************************************************************
*
* SUBTEST 3 - PUSHD status test
*
************************************************************************/
pushd_3()
{
force_loop = FALSE;
subtest = 3;
index = 0;
do {
dbl_ld_acc = ldd_1_data[index].ld; /* get the operand */
status_index = 0; /* clear the status index */
do {
sgl_dummy1 = status_array[status_index]; /* array = +, -, 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("_pushd_3_lp1:");
asm("ldd _dbl_ld_acc"); /* load the operand */
asm("tstl _sgl_dummy1"); /* generate initial status */
asm("movpsl _init_psl"); /* save the initial status */
asm("nop");
asm("pushd"); /* push the accumulator */
asm("nop");
asm("movpsl _psl_val"); /* save the final status */
asm("std _dbl_st_acc"); /* save the acc */
if( force_loop ) /* loop? */
asm("brb _pushd_3_lp1");; /* run the loop again */
exp_psl = init_psl; /* get the initial PSL */
exp_psl &= 0xfffffff3; /* clear ZERO, NEGATIVE */
if( !(dbl_ld_acc.m & 0x7f800000) )
exp_psl |= PSL_Z; /* expect the ZERO bit set */
else if( dbl_ld_acc.m & 0x80000000 )
exp_psl |= PSL_N; /* expect the NEG bit set */
if( psl_val != exp_psl ) { /* COMPARE the values */
errcnt++; /* bump the error count */
if ( prt_error ) {
writes(" \n"); /* start a new print line */
writes("cycle: ");
writed( cycle );
writes(" PUSHD test ");
writed( test_no );
writes(", subtest 3 - INCORRECT FINAL PSL\n");
print_pushd_data();
writes(", pushed = ");
write32h( dbl_ld_acc.m );
writec(' ');
write32h( dbl_ld_acc.l );
writec('\n');
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? */
pushd_er_halt( BAD_PSL_HLT );
if ( loop_on_err ) {
force_loop = TRUE; /* set the force loop flag */
asm("jmp _pushd_3_lp1"); /* and loop */
}; /* end of loop-on-error */
} /* end of compare error */
} while( ++status_index < 3 );
} while( index++ < max_ldd_1_index );
} /* end of subtest 3 */
/**************************************************************************
*
* PRINT THE DATA AND STORE RESULTS
*
* initial Acc = xxxxxxxx xxxxxxxx, stored = xxxxxxxx xxxxxxxx, index = xx
* operand = xxxxxxxx xxxxxxxx, expected = xxxxxxxx xxxxxxxx
**************************************************************************/
print_pushd_data()
{
writes("initial Acc = ");
write32h( dbl_ld_acc.m );
writec(' ');
write32h( dbl_ld_acc.l );
}
/**************************************************************************
*
* HALT ON ERROR ROUTINE
*
**************************************************************************/
pushd_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_st_acc.m;
sgl_value_4 = dbl_st_acc.l;
sgl_value_5 = pop_val_1;
sgl_value_6 = pop_val_2;
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 loaded */
asm("movl _sgl_value_2,r5"); /* r5 = LS loaded */
asm("movl _sgl_value_3,r6"); /* r6 = MS stored */
asm("movl _sgl_value_4,r7"); /* r7 = LS stored */
asm("movl _sgl_value_5,r8"); /* r8 = MS popped */
asm("movl _sgl_value_6,r9"); /* r9 = LS popped */
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 _index,r12"); /* r12 = data index */
} else
if( halt_code == BAD_REG_HLT ) {
sgl_dummy1 = load_regs[index2];
sgl_dummy2 = store_regs[index2];
asm("movl _index2,r11"); /* r11 = bad register # */
asm("movl _sgl_dummy2,r12"); /* r12 = actual value */
asm("movl _sgl_dummy1,r13"); /* r13 = expected value */
} else
if( halt_code == BAD_PSL_HLT ) {
asm("movl _init_psl,r11"); /* r11 = initial PSL */
asm("movl _psl_val,r12"); /* r12 = final PSL */
asm("movl _exp_psl,r13"); /* r13 = expected PSL */
} else
if( halt_code == BAD_STORE_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 _index,r12"); /* r12 = data index */
} else
if( halt_code == PUSH_CNT_HLT ) {
asm("movl _sgl_value_7,r10"); /* r10 = num words push */
asm("movl $2,r11"); /* r11 = num words exp */
};
asm("halt"); /* HALT ... */
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.