bpmain.c 11 KB
/************************************************************************
  WHAT:	RSP SCALAR UNIT BYPASS VERIFICATION TEST PROGRAM GENERATOR
  SCCS:	%W% %G%
  PTLS:	$Id: bpmain.c,v 1.1.1.1 2002/10/29 08:07:06 blythe Exp $
  ENGR:	Evan Y. Wang
  PROJ:	Project Reality
  (CR):	1994 Silicon Graphics, Inc.
 ************************************************************************/
#include <stdio.h>
#include <string.h>
#include "software.h"
#include "bpgen.h"

/************************************************************************
  REGRESSION TEST GENERATOR VARIABLES.
 ************************************************************************/
FILE *fhSFile;
FILE *fhTFile;
char cTFName[20];
int FileCount = 0;
int TestNum = 1;

u32  Tip = IMEM_BASE;
int  Space = 2;
int  DestRegID = 1;
int  Src1RegID = 2;
int  Src2RegID = 3;
int  Src3RegID = 4;
int  DumpRegID = 5;

/************************************************************************
  RSP STATE MODEL.
 ************************************************************************/
u32  Vco;
u32  Reg[32];
UD32 VReg[32][4];
UD32 DMem[DMEM_SIZE>>2];				/* 4K of DMEM	*/

u32 Rand32()	{ return rand()<<16|rand(); }

/************************************************************************
  Header(..) - print common test program header/comment.
 ************************************************************************/
void Header(outp, tno)
    FILE *outp;
    int tno;
{
    fprintf(outp,"/********************************");
    fprintf(outp,"********************************\n");
    fprintf(outp,"  SCALAR UNIT BYPASS TEST: %d\n", tno);
    fprintf(outp," ********************************");
    fprintf(outp,"********************************/\n\n");
    fprintf(outp,".base 0x%8.8lX\n\n", IMEM_BASE);
} /* Header */

/************************************************************************
  AddSrcEntry(..) - add to the rspsim source file.
 ************************************************************************/
void AddSrcEntry(outp, tfno)
    FILE *outp;
    int  tfno;
{
	fprintf(fhSFile, "load bptest%d.bin 0x%8.8lX\n",tfno,IMEM_BASE|0x04001000);
	fprintf(fhSFile, "load bptest%d.dat 0x%8.8lX\n",tfno,DMEM_BASE);
	fprintf(fhSFile, "dep PC 0\nrun\nreg 1\n");

} /* AddSrcEntry */

/************************************************************************
  DmemInit(..) - initialize DMEM.
 ************************************************************************/
PRIVATE void DMemInit(outp)
    FILE *outp;
{
    int i;
    u32 tdp;

    tdp = 0;
    for (i=0; i<(DMEM_SIZE>>2); i++, tdp+=4)
	fprintf(outp,"\t.word\t0x%8.8lX\t\t/* Addr: 0x%4.4X */\n",
		DMem[i].w=Rand32(), tdp);

} /* DMemInit */

/************************************************************************
  Tail(..) - print common test end statements.
 ************************************************************************/
void Tail(outp)
    FILE *outp;
{
    fprintf(outp,"\n\tlui\t$1, 0xFEED;\n");
    fprintf(outp,"Fail:\tbreak;\n");
} /* Tail */

/************************************************************************
  TestGen(..) - generate a test case
 ************************************************************************/
PRIVATE void TestGen(outp,tno,i1,i2,rt,r1,r2,r3,rd)
    FILE *outp;		/* test file handle			*/
    int  tno;		/* test number				*/
    int  i1;		/* test instruction 1 index to I1Table	*/
    int  i2;		/* test instruction 2 index to I2Table	*/
    int  rt;		/* target/destination register ID	*/
    int  r1;		/* source 1 register ID			*/
    int  r2;		/* source 2 register ID			*/
    int  r3;		/* source 2 register ID			*/
    int  rd;		/* dump register ID			*/
{
    int i;

    fprintf(outp,"\t/* TEST #%2.2d ",tno);
    fprintf(outp,"*********************************************/\n");
    fprintf(outp,"\tlui\t$1,  0x%X\n\n",tno);			Tip+=4;

    fprintf(outp,"\t/* Initialization */\n");

    /* Initialize destination register */
    Reg[rt] = Rand32();
    fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",rt,Reg[rt]>>16);	Tip+=4;
    fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",rt,Reg[rt]&0xFFFF);	Tip+=4;

    /* Clear VU destination and dump registers */
    fprintf(outp,"\tvxor\t$v%d,\t$v%d,\t$v%d\n",rt,rt,rt);	Tip+=4;
    fprintf(outp,"\tvxor\t$v%d,\t$v%d,\t$v%d\n",rd,rd,rd);	Tip+=4;

    /* Initialize source 2 register */
    Reg[r2] = Rand32();
    fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",r2,Reg[r2]>>16);	Tip+=4;
    fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",r2,Reg[r2]&0xFFFF);	Tip+=4;

    /* Initialize source 3 register */
    Reg[r3] = Rand32();
    fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",r3,Reg[r3]>>16);	Tip+=4;
    fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",r3,Reg[r3]&0xFFFF);	Tip+=4;

    /********************************************************************
      WARNING:	Adding any instruction(s) between this warning and the
      end of the TestInit procedure can easily break the generator.
      Proceed with extreme care.
     ********************************************************************/

#define TIP_TESTINSTR	10

    /* WARNING: Source 1 register initialized in InstrEmulation() */
    Tip = InstrEmulation(outp, i1,i2,rt,r1,r2,r3,rd,Tip+(TIP_TESTINSTR<<2))
	- (TIP_TESTINSTR<<2);

    /* Initialize VCO */
    fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",rd,Vco>>16);		Tip+=4;
    fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",rd,Vco&0xFFFF);	Tip+=4;
    fprintf(outp,"\tnop\n");					Tip+=4;
    fprintf(outp,"\tctc2\t$%d,\t$v0\n",rd);			Tip+=4;
    fprintf(outp,"\tnop\n");					Tip+=4;

    /* Initialize dump register */
    fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",rd,Reg[rd]>>16);	Tip+=4;
    fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",rd,Reg[rd]&0xFFFF);	Tip+=4;

    fprintf(outp,"\tnop\n");					Tip+=4;
    fprintf(outp,"\tnop\n");					Tip+=4;
    fprintf(outp,"\tnop\n");					Tip+=4;
    fprintf(outp,"\n");

    fprintf(fhTFile,"\t/* Test */\n");
    fprintf(fhTFile,I1Table[i1].instr,rt,r1,r2);		Tip+=4;
    for (i=0; i<Space; i++) {
	fprintf(outp,"\tnop\n");				Tip+=4;
    }
    fprintf(outp,I2Table[i2].instr,rd,rt,r3);			Tip+=4;

    /********************************************************************
      END OF WARNING.
     ********************************************************************/
} /* TestInit */

/************************************************************************
  ResultCheck(..).
 ************************************************************************/
PRIVATE void ResultCheck(outp,i1,i2,rt,r1,r2,r3,rd)
    FILE *outp;		/* test file handle			*/
    int  i1;		/* test instruction 1 index to I1Table	*/
    int  i2;		/* test instruction 2 index to I2Table	*/
    int  rt;		/* target/destination register ID	*/
    int  r1;		/* source 1 register ID			*/
    int  r2;		/* source 2 register ID			*/
    int  r3;		/* source 3 register ID			*/
    int  rd;		/* dump register ID			*/
{
    int i;

    /* buffering from the test instruction pair */
    fprintf(outp,"\n");
    fprintf(outp,"\t/* Result Check */\n");
    fprintf(outp,"\tnop\n");					Tip+=4;
    fprintf(outp,"\tnop\n");					Tip+=4;
    fprintf(outp,"\tnop\n");					Tip+=4;

    /* check dump register */
    fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",r1,Reg[rd]>>16);	Tip+=4;
    fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",r1,Reg[rd]&0xFFFF);	Tip+=4;
    fprintf(outp,"\tbne\t$%d,\t$%d,\tFail\n",r1,rd);		Tip+=4;
    fprintf(outp,"\tnop\n");					Tip+=4;

    /* check target register */
    fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",r1,Reg[rt]>>16);	Tip+=4;
    fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",r1,Reg[rt]&0xFFFF);	Tip+=4;
    fprintf(outp,"\tbne\t$%d,\t$%d,\tFail\n",r1,rt);		Tip+=4;
    fprintf(outp,"\tnop\n");					Tip+=4;

    /* check VCO */
    fprintf(outp,"\tcfc2\t$%d,\t$v0\n",r1);			Tip+=4;
    fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",r2,Vco>>16);		Tip+=4;
    fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",r2,Vco&0xFFFF);	Tip+=4;
    fprintf(outp,"\tbne\t$%d,\t$%d,\tFail\n",r1,r2);		Tip+=4;
    fprintf(outp,"\tnop\n");					Tip+=4;

    /* check VREG_1 */
    if (I2Table[i2].op == OP_LQV) {
	fprintf(outp,"\tlui\t$%d,\t0\n",r1);			Tip+=4;
	fprintf(outp,"\tori\t$%d,\t0xFF\n",r1);			Tip+=4;
	fprintf(outp,"\tctc2\t$0,\t$v0\n");			Tip+=4;
	fprintf(outp,"\tlqv\t$v%d[0],\t0($%d)\n",rt,rt);	Tip+=4;
	fprintf(outp,"\tveq\t$v%d,\t$v%d,\t$v%d\n",r1,rd,rt);	Tip+=4;
	fprintf(outp,"\tnop\n");				Tip+=4;
	fprintf(outp,"\tcfc2\t$%d,\t$v1\n",r2);			Tip+=4;
	fprintf(outp,"\tnop\n");				Tip+=4;
	fprintf(outp,"\tbne\t$%d,\t$%d,\tFail\n",r1,r2);	Tip+=4;
	fprintf(outp,"\tnop\n");				Tip+=4;
    }
    fprintf(outp,"\n");

} /* ResultCheck */

/************************************************************************
  main(..) - gen program entry point.  Determining whether we are
  generating all tests in the instruction table (see table.c) as
  indicated by the absence of any command line argument or just a
  selected few given on the command line.  FormTest is called to
  generate the test program(s) for each instruction.
 ************************************************************************/
void main(argc,argv)
    int argc;
    char *argv[];
{
    int j;
    int i1, i2;

    if ((fhSFile = fopen("bpt.scr", "w")) == NULL) {
	fprintf(stderr, "ERROR:\tOpening file bpt.scr failed.\n");
	fprintf(stderr, "\tContinuing...\n");
    }
    fprintf(fhSFile, "silent\n");

    /********************************************************************
      For each instruction in table I1Table[], generate a test file.
     ********************************************************************/
    for (i1=0; i1<I1TableSize; i1++, FileCount++) {

	/* Open test file. */
	sprintf(cTFName,"bptest%d.s",i1);
	if ((fhTFile = fopen(cTFName, "w")) == NULL) {
	    fprintf(stderr, "ERROR:\tOpening file %s failed.\n", cTFName);
	    fprintf(stderr, "\tExiting...\n");
	    exit(1);
	}

	Header(fhTFile, FileCount);	/* Print header for files	*/
	DMemInit(fhTFile);		/* Initialize DMEM		*/

	/* Add entry to rspsim source file for current test file. */
	if (fhSFile != NULL) AddSrcEntry(fhSFile, FileCount);

	/* Initialize important variables. */
	Tip = IMEM_BASE;

	fprintf(fhTFile,"\tlui\t$1,\t0x%4.4X\n", IMEM_BASE>>16);	Tip+=4;
	fprintf(fhTFile,"\tori\t$1,\t0x%4.4X\n",IMEM_BASE&0xFFFF);	Tip+=4;
	fprintf(fhTFile,"\tlqv\t$v0[0],\t0($1)\n");			Tip+=4;
	for (j=0; j<32; j++) {
	    fprintf(fhTFile,"\tvnxor\t$v%d,\t$v0,\t$v0\n",j);		Tip+=4;
	}

	/* For each instruction in table I2Table, generate a test case. */
	for (i2=0; i2<I2TableSize; i2++) {

	    /* Eliminate incompatible instruction pairs. */
	    if (I1Table[i1].grpmsk & I2Table[i2].grpmsk) {

		/* Vary the number of NOPs between the instruction pair. */
		for (Space=2;
		     (Space>0
		      ||(Space==0&&(I1Table[i1].nonseq&I2Table[i2].nonseq)))
		     && Space>=I1Table[i1].min_nop; Space--) {

		    TestGen(fhTFile,TestNum,i1,i2,
			    DestRegID,Src1RegID,Src2RegID,Src3RegID,DumpRegID);

		    ResultCheck(fhTFile,i1,i2,
				DestRegID,Src1RegID,Src2RegID,Src3RegID,DumpRegID);

		    TestNum++;
		    DestRegID = ((DestRegID+1)%31)+1;
		    Src1RegID = ((Src1RegID+1)%31)+1;
		    Src2RegID = ((Src2RegID+1)%31)+1;
		    Src3RegID = ((Src3RegID+1)%31)+1;
		    DumpRegID = ((DumpRegID+1)%31)+1;
		}
	    }
	}

	Tail(fhTFile);
	fclose(fhTFile);
    }

    bpmult(FileCount++,TestNum);

    fprintf(fhSFile, "q\n");
    fclose(fhSFile);

} /* main */