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

#include "fpp_defs.h"



/***************************************************************************
*
*       CMPD  -COMPARE SGL ACCUMULATOR TO SGL OPERAND
*
*****************************************************************************/
cmpd()
{
        asm(".globl _cmpd_t");
        asm("_cmpd_t:");                        /* entry address            */
        if( ( cycle == 1 ) && ( prt_hdrs ) )    /* print headers on 1st pass  */
        {
           writes(" CMPD");
        }
        cmpd_1();                               /* test via registers         */
        cmpd_2();                               /* test via cache             */
        cmpd_3();                               /* register corruption test   */
        cmpd_4();                               /* acc. corruption test       */
        asm("jmp *return");                     /* return to the test monitor */
}
  


/****************************************************************************
*
*               SUBTEST 1 - CMPD status test  -register data
*
****************************************************************************/
cmpd_1() 
{
        force_loop = FALSE;
        subtest = 1;
	index = 0;
        do 
        {
	   dbl_value_1  = cmpd_1_data[index].one; /* get the data operands  */
	   dbl_value_2  = cmpd_1_data[index].two;
	   sgl_expected = cmpd_1_data[index].flag; /* get expected results */
	   sgl_value_1  = dbl_value_1.m;
	   sgl_value_2  = dbl_value_1.l;
	   sgl_value_3  = dbl_value_2.m;
	   sgl_value_4  = dbl_value_2.l;
           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("_cmpd_1_lp1:");
               asm("movl _sgl_value_1,r4");     /* move operand #1 to r4    */
               asm("movl _sgl_value_2,r5");     /* move operand #1 to r5    */
               asm("movl _sgl_value_3,r6");     /* move operand #2 to r6    */
               asm("movl _sgl_value_4,r7");     /* move operand #2 to r7    */
               asm("ldd r4");                   /* load the operand         */
               asm("tstl _sgl_dummy1");         /* generate initial status  */
               asm("movpsl _init_psl");         /* save the initial status  */
               asm("cmpd r6");                  /* compare the operands     */
               asm("movpsl _psl_val");          /* save the final status    */
               if( force_loop )                 /* loop?                    */
                   asm("brb _cmpd_1_lp1");;     /* run the loop again       */
               exp_psl = init_psl;              /* get the initial PSL      */
               exp_psl &= 0xfffffff3;           /* clear ZERO, NEGATIVE     */
               if( sgl_expected == ZERO )
                   exp_psl |= PSL_Z;            /* expect the ZERO bit set  */
               if( sgl_expected == NEGATIVE )
                   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("  CMPD test ");
		     writed( test_no );
		     writes(", subtest 1 (Reg. Data) - BAD FINAL PSL\n");
                     print_cmpd_data();
                     writes(",  index = ");
                     writed( index );
                     writes("\ninitial PSL = ");
                     write32h( init_psl );
                     writes(",  final PSL = ");
                     write32h( psl_val );
                     writes(",  expected PSL = ");
                     write32h( exp_psl );
                     writes("\n");
                  }
                  if ( halt_flg )
                     cmpd_er_halt( BAD_PSL_HLT );/* halt on the error      */
                  if ( loop_on_err ) {
                     force_loop = TRUE;         /* set the force loop flag */
                     asm("brw _cmpd_1_lp1");    /* and loop on the error   */
                  }   /* end of loop on error    */
               }   /* end of compare error    */
           } while( ++status_index < 3 );       /* end of WHILE loop */
        } while ( index++ < max_cmpd_1_index ); /* end of WHILE loop */
}  /* end of subtest 1 */
  


/****************************************************************************
*
*               SUBTEST 2 - CMPD status test  -cache data
*
****************************************************************************/
cmpd_2() 
{
        force_loop = FALSE; 
	subtest = 2;
	index = 0;
        do 
        {
           dbl_value_1  = cmpd_1_data[index].one; /* get the data operands  */
           dbl_value_2  = cmpd_1_data[index].two;
           sgl_expected = cmpd_1_data[index].flag;/* get expected results */
           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("_cmpd_2_lp1:");
               asm("ldd _dbl_value_1");         /* load the 1st operand     */
               asm("tstl _sgl_dummy1");         /* generate initial status  */
               asm("movpsl _init_psl");         /* save the initial status  */
               asm("cmpd _dbl_value_2");        /* compare the operands     */
               asm("movpsl _psl_val");          /* save the final status    */
               if( force_loop )                 /* loop?                    */
                   asm("brb _cmpd_2_lp1");;     /* run the loop again       */
               exp_psl = init_psl;              /* get the initial PSL      */
               exp_psl &= 0xfffffff3;           /* clear ZERO, NEGATIVE     */
               if( sgl_expected == ZERO )
                   exp_psl |= PSL_Z;            /* expect the ZERO bit set  */
               if( sgl_expected == NEGATIVE )
                   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("  CMPD test ");
		     writed( test_no );
		     writes(", subtest 2 (Cache Data) - BAD FINAL PSL\n");
                     print_cmpd_data();
                     writes(",  index = ");
                     writed( index );
                     writes("\ninitial PSL = ");
                     write32h( init_psl );
                     writes(",  final PSL = ");
                     write32h( psl_val );
                     writes(",  expected PSL = ");
                     write32h( exp_psl );
                     writes("\n");
                  }
                  if ( halt_flg ) 
                     cmpd_er_halt( BAD_PSL_HLT );   /* halt on the error   */
                  if ( loop_on_err ) {
                     force_loop = TRUE;         /* set the force loop flag */
                     asm("brw _cmpd_2_lp1");    /* and loop on the error   */
                  }   /* end of loop on error    */
               }  /* end of compare error */
           } while( ++status_index < 3 );       /* end of WHILE loop */
        } while ( index++ < max_cmpd_1_index ); /* end of WHILE loop */
}  /* end of subtest 2 */
  


/************************************************************************
*
*       SUBTEST 3 - Check for register corruption
*
************************************************************************/
cmpd_3() 
{
        force_loop = FALSE;                     /* clear force_loop flg   */
        subtest = 3;
	fill_reg_buf( load_regs );              /* get pattern for regs   */
	index = 0;
        do 
        {
             dbl_value_1  = cmpd_1_data[index].one;   /* data to load    */
             dbl_value_2  = cmpd_1_data[index].two;   /* data to compare */
             dbl_expected = cmpd_1_data[index].one;   /* 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("_cmpd_3_lp1:");
             asm("ldd _dbl_value_1");           /* LOAD the accumulator  */
             asm("nop");
	     asm("loadr $0x1fff,_load_regs");   /* load regs 0 - 12       */
             asm("nop");
             asm("cmpd _dbl_value_2");          /* test the values        */
             asm("nop");
             asm("storer $0x1fff,_store_regs"); /* store regs 0 - 12 */
             if( force_loop )                   /* loop?                    */
                   asm("brb _cmpd_3_lp1");;     /* run the loop again       */
/*
 * 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(", CMPD test ");
		       writed( test_no );
	writes(", subtest 3 - A REGISTER WAS MODIFIED\n");
                       print_cmpd_data();            /* print the operands    */
                       writes("\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? */
                            cmpd_er_halt( BAD_REG_HLT );   /* PC after halt */
                       if ( loop_on_err ) {
                          force_loop = TRUE;         /* set force loop flag */
                          asm("brw _cmpd_3_lp1");    /* and loop on error   */
                       }   /* end of loop on error    */
                  }    /* end of register corruption error */
        } while ( index++ < max_cmpd_1_index ); /* end of WHILE loop */
}  /* end of subtest 3 */
  


/************************************************************************
*
*       SUBTEST 4 - Check for accumulator corruption
*
************************************************************************/
cmpd_4() 
{
        force_loop = FALSE;                         /* clear force_loop flg */
        index = 0;
        do 
        {
             dbl_value_1   = cmpd_1_data[index].one; /* data to load */
             dbl_value_2   = cmpd_1_data[index].two;
             dbl_expected  = cmpd_1_data[index].one; /* expected result */
	     if( !(dbl_value_1.m & 0x7f800000) ) {    /*   */
		dbl_expected.m = 0;		     /*   */
		dbl_expected.l = 0;		/* ignore bad 0's */
		}				/*                */
             sgl_value_1  = dbl_value_1.m;
             sgl_value_2  = dbl_value_1.l;
             sgl_value_3  = dbl_value_2.m;
             sgl_value_4  = dbl_value_2.l;
/*
 * If LOOP ON ERROR is set, this is the loop for this subtest.
 * The force loop flag is set after the first error.
*/
             asm("_cmpd_4_lp1:");
             asm("movl _sgl_value_1,r4");       /* r4 = operand #1's MSW */
             asm("movl _sgl_value_2,r5");       /* r5 = operand #1's LSW */
             asm("movl _sgl_value_3,r6");       /* r6 = operand #2's MSW */
             asm("movl _sgl_value_4,r7");       /* r7 = operand #2's LSW */
             asm("ldd r4");                     /* store the accumulator */
             asm("cmpd r6");                    /* test the values       */
             asm("std r8");                     /* store the accumulator */
             if( force_loop )                   /* loop?                    */
                   asm("brb _cmpd_4_lp1");;     /* run the loop again       */
             asm("movl r8,_sgl_value_5");       /* move results to cache */
             asm("movl r9,_sgl_value_6");
             if (  (sgl_value_5 != dbl_expected.m) || /* COMPARE the values */
                   (sgl_value_6 != dbl_expected.l) ){
                  errcnt++;                     /* bump the error count */
                  if ( prt_error ) {
                       writes(" \n");      /* start a new print line   */
                       writes("cycle: ");
                       writed( cycle );
                       writes(", CMPD test ");
		       writed( test_no );
	writes(", subtest 4 - THE ACC WAS MODIFIED\n");
                       print_cmpd_data();
                       writes(",  index = ");
		       writed( index );
		       writec('\n');
		       writes("  final Acc = ");
		       write32h( sgl_value_5 );
		       writec(' ');
		       write32h( sgl_value_6 );
		       writec('\n');
		       writes("   expected = ");
		       write32h( dbl_expected.m );
		       writec(' ');
		       write32h( dbl_expected.l );
		       writec('\n');
		       }
                  if ( halt_flg )               /* halt on error? */
                       cmpd_er_halt( BAD_ACC_HLT ); /* halt on the error */
                  if ( loop_on_err ) {
                     force_loop = TRUE;         /* set the force loop flag */
                     asm("brw _cmpd_4_lp1");    /* and loop on the error   */
                  }   /* end of loop on error    */
             }   /* end of compare error    */
        } while ( index++ < max_cmpd_1_index ); /* end of WHILE loop */
}  /* end of subtest 4 */
  


/**************************************************************************
*
*       PRINT THE DATA AND STORE RESULTS
*
* initial Acc = xxxxxxxx xxxxxxxx,  operand = xxxxxxxx xxxxxxxx
**************************************************************************/
print_cmpd_data()
{
        writes("initial Acc = ");
        write32h( dbl_value_1.m );
        writec(' ');
        write32h( dbl_value_1.l );
        writes("  operand = ");
        write32h( dbl_value_2.m );
        writec(' ');
        write32h( dbl_value_2.l );
}
  


/**************************************************************************
*
*               HALT ON ERROR ROUTINE 
*
**************************************************************************/
cmpd_er_halt( halt_code )
int halt_code;
{
        sgl_value_1 = dbl_value_1.m;
        sgl_value_2 = dbl_value_1.l;
        sgl_value_3 = dbl_value_2.m;
        sgl_value_4 = dbl_value_2.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  = MS operand 2    */
        asm("movl _psl_val,r8");                /* r8  = actual PSL      */
        if( halt_code == BAD_ACC_HLT ) {
             sgl_value_1 = dbl_expected.m;
             sgl_value_2 = dbl_expected.l;
             asm("movl _sgl_value_5,r9");       /* r9  = MS stored       */
             asm("movl _sgl_value_6,r10");      /* r10 = LS stored       */
             asm("movl _sgl_value_1,r11");      /* r11 = MS expected     */
             asm("movl _sgl_value_2,r12");      /* r12 = LS expected     */
        } else 
          if( halt_code == BAD_REG_HLT ) {
             sgl_dummy1 = load_regs[index2];
             sgl_dummy2 = store_regs[index2];
             asm("movl _index2,r9");            /* r9  = bad register #  */
             asm("movl _sgl_dummy2,r10");       /* r10 = actual value    */
             asm("movl _sgl_dummy1,r11");       /* r11 = expected value  */
        } else
          if( halt_code == BAD_PSL_HLT ) {
             asm("movl _exp_psl,r9");           /* r9  = expected PSL    */
             asm("movl _index,r10");            /* r10 = data index      */
        };
        asm("halt");                            /* HALT ...              */
}  

unix.superglobalmegacorp.com

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