instr.c 5.4 KB
/************************************************************************
  WHAT:	RSP SCALAR UNIT BYPASS VERIFICATION TEST PROGRAM GENERATOR
  SCCS:	%W% %G%
  PTLS:	$Id: instr.c,v 1.1.1.1 2002/05/02 03:29:13 blythe Exp $
  ENGR:	Evan Y. Wang
  PROJ:	Project Reality
  (CR):	1994 Silicon Graphics, Inc.
 ************************************************************************/
#include <stdio.h>
#include <math.h>
#include "software.h"
#include "bpgen.h"

ITABLE I1Table[] = {

    { "\tjalr\t$%d,\t$%d\n",	  OP_JALR, VTYPE_UIP, 0, 0x01, 0x01 },
    { "\tcfc2\t$%d,\t$v0\n",	  OP_CFC2, VTYPE_U16, 0, 0x02, 0x02 },
    { "\txor\t$%d,\t$%d,\t$%d\n", OP_XOR,  VTYPE_U32, 0, 0x04, 0x04 },
    { "\txori\t$%d,\t$%d,\t0xFFFF\n",  OP_XORI, VTYPE_U32, 0, 0x08, 0x08 },
    { "\tlw\t$%d,\t0($%d)\n",	  OP_LW,   VTYPE_U32, 0, 0x10, 0x10 },
};
int I1TableSize = sizeof(I1Table)/sizeof(I1Table[0]);

ITABLE I2Table[] = {

    { "\txor\t$%d,\t$%d,\t$%d\n",     OP_XOR,  VTYPE_U32, 0, 0xFF, 0xFF },
    { "\txori\t$%d,\t$%d,\t0xFFFF\n", OP_XORI, VTYPE_U32, 0, 0xFF, 0xFF },
    { "\tlw\t$%d,\t0($%d)\n",	      OP_LW,   VTYPE_UDP, 0, 0xFF, 0xFF },
    { "\tbne\t$%d,\t$%d,\tFail\n",    OP_BNE,  VTYPE_EQU, 0, 0xFF, 0xFE },
    { "/*%d*/\tctc2\t$%d,\t$v0\n",    OP_CTC2, VTYPE_U16, 0, 0xFF, 0xFF },
    { "\tlqv\t$v%d[0],\t0($%d)\n",    OP_LQV,  VTYPE_UDP, 0, 0xFF, 0xFF },
    { "\tjalr\t$%d,\t$%d\n",	      OP_JALR, VTYPE_UIP, 0, 0xFE, 0xFE },
};
int I2TableSize = sizeof(I2Table)/sizeof(I2Table[0]);

u32 InstrEmulation(outp,i1,i2,rt,r1,r2,r3,rd,tip)
    FILE *outp;		/* test file - use this sparingly!	*/
    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			*/
    u32  tip;		/* PC of test instruction 1		*/
{
    int i;
    u32 tdp,ttip;
    u8 *pch;
    u8 *pch2;

    tip+=(2<<2);	/* for initialization of Reg[r1]	*/

    /********************************************************************
      TEST INSTRUCTION 1 EMULATION
     ********************************************************************/
    Reg[r1] = Rand32();
    Reg[rd] = Rand32();
    Vco = (Reg[rd] & 0xFFFF) | (Reg[rd]&0x8000 ? ~0xFFFF : 0);

    /********************************************************************
      TEST PREPARATION STEP 1: At this point all of the "input" registers
      are initialized.  However, for some special (a majority given how
      we selected the instructions) cases the input registers are altered.
      They are altered below in the first pass.
     ********************************************************************/
    switch (I1Table[i1].op) {

      case OP_JALR:
	/* re-assign Reg[r1] value */
	Reg[r1] = tip+(2<<2);
	Reg[rt] = tip+(2<<2);
	break;

      case OP_CFC2:
	/* re-assign VCO value */
	if (I2Table[i2].vtype == VTYPE_UIP) Vco = tip+((Space+3)<<2);
	Reg[rt] = Vco;
	break;

      case OP_XOR:
	/* re-assign Reg[r1] value */
	if (I2Table[i2].vtype == VTYPE_UIP)
	    Reg[r1] = (tip+((Space+3)<<2)) ^ Reg[r2];
	Reg[rt] = Reg[r1] ^ Reg[r2];
	break;

      case OP_XORI:
	/* re-assign Reg[r1] value */
	if (I2Table[i2].vtype == VTYPE_UIP)
	    Reg[r1] = (tip+((Space+3)<<2)) ^ 0xFFFF;
	Reg[rt] = Reg[r1] ^ 0xFFFF;
	break;
    }

    fprintf(outp,"\tlui\t$%d,\t0x%4.4X\n",r1,Reg[r1]>>16);
    fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",r1,Reg[r1]&0xFFFF);

    /********************************************************************
      TEST PREPARATION STEP 2: Second pass through test instruction 1.
      We only use (and not alter) the "input" registers.
     ********************************************************************/
    switch (I1Table[i1].op) {

      case OP_LW:
	tdp = (Reg[r1]&(DMEM_SIZE-1))>>2;
	pch = &DMem[tdp].u.h.u.hb + (Reg[r1]&3);
	if (I2Table[i2].vtype == VTYPE_UIP) {
	    tip += (3<<2); /* adjust Tip for following three instructions */
	    ttip = tip+((Space+3)<<2);	/* prediction of Tip at test */
	    fprintf(outp,"\tlui\t$%d,\t0\n",rd);
	    fprintf(outp,"\tori\t$%d,\t0x%4.4X\n",rd,ttip);
	    fprintf(outp,"\tsw\t$%d,\t0($%d)\n",rd,r1);
	    *(pch)   = (ttip>>24)&0xFF;	    *(pch+1) = (ttip>>16)&0xFF;
	    *(pch+2) = (ttip>> 8)&0xFF;	    *(pch+3) = (ttip    )&0xFF;
	}
	Reg[rt] = *(pch)<<24 | *(pch+1)<<16 | *(pch+2)<<8 | *(pch+3);
	break;
    }

    /********************************************************************
      TEST PREPARATION STEP 3: Emulate test instruction 2.
     ********************************************************************/
    switch (I2Table[i2].op) {

      case OP_XOR:
	Reg[rd] = Reg[rt] ^ Reg[r3];
	break;

      case OP_XORI:
	Reg[rd] = Reg[rt] ^ 0xFFFF;
	break;

      case OP_LW:
	tdp = (Reg[rt]&(DMEM_SIZE-1))>>2;
	pch = &DMem[tdp].u.h.u.hb + (Reg[rt]&3);
	Reg[rd] = *(pch)<<24 | *(pch+1)<<16 | *(pch+2)<<8 | *(pch+3);
	break;

      case OP_BNE:
	Reg[rd] = Reg[rt];
	break;

      case OP_CTC2:
	Vco = (Reg[rt] & 0xFFFF) | (Reg[rt]&0x8000 ? ~0xFFFF : 0);
	break;

      case OP_LQV:
	/* The result of this emulation is not used.  We leave it in
	 * in case we need in the future.
	 */
	tdp = Reg[rt]&(DMEM_SIZE-1);
	pch = &DMem[(tdp>>4)<<2].u.h.u.hb + (tdp&0xF);
	pch2 = &VReg[rd][0].u.h.u.hb;
	for (i=tdp&0xF; i<0x10; i++) *pch2++ = *pch++;
	break;

      case OP_JALR:
	Reg[rd] = tip+((Space+3)<<2);
	break;
    }

    return tip;

} /* InstrEmulation */