print_insts.c 8.25 KB
/*
 * Copyright (C) 1998 by the Board of Trustees
 *    of Leland Stanford Junior University.
 * Copyright (C) 1998 Digital Equipment Corporation
 *
 * This file is part of the SimOS distribution.
 * See LICENSE file for terms of the license.
 *
 */

/*
 * Copyright (C) 1998 by the Board of Trustees
 *    of Leland Stanford Junior University.
 * 
 * This file is part of the SimOS distribution. 
 * See LICENSE file for terms of the license. 
 *
 */

/****************************************************************
 * print_insts.c
 * 
 * Routines for printing out instructions that are simulated.
 * 
 * $Author: blythe $
 * $Date: 2002/05/29 01:09:11 $
 *****************************************************************/
#include "tcl_init.h"
#include "simtypes.h"
#include "alpha.h"
#include "alpha_insts.h"
#include "ev5_ipr.h"

#include "print_insts.h"
#include "sim_error.h"
#include "machine_params.h"
#include "ipr_decode.h"
#include <string.h>

extern void disasm();

char printInstMask[SIM_MAXCPUS];


void
PrintInstsInit(Tcl_Interp *interp)
{
   int i;
   ASSERT(interp);
   Tcl_CreateCommand(interp, "instDump", PrintInstTclCmd,
                     (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);

#if defined(sgi) && defined(PRINT_INSTRUCTIONS) && !defined(_ABIN32)
   /* Initialize the disassembly routines - This tells it not to print
      the instruction address since it will always be the same. */
   dis_init( "", 0, 0, 1);
#endif


   for (i = 0; i < NUM_CPUS(0); i++) {
#ifdef T5_MODEL
      printInstMask[i] = 1;
#else
      printInstMask[i] = 0;
#endif
   }
}

/*****************************************************************
 * PrintInstruction
 *
 * Simple procedure to output an instruction in text form.
 * The statics declared out of the function speed it up and 
 * remove compiler warnings.
 *****************************************************************/


/*****************************************************************
 * PrintInstruction
 *****************************************************************/
void PrintInstruction (AlphaState *P,uint instr)
{
   extern int64 gammaCurrentTime[SIM_MAXCPUS]; /*hack */
   union alpha_instruction ainst = (union alpha_instruction) instr;
   char buf[200];
   long piG1=0, piG2=0, piG3=0;
   int cpunum = P->myNum;
   switch (ainst.common.opcode) {
   case PRIV_OP_MFPR:
      sprintf(buf, "0x%08lx\t0x%08x\tmfpr\t%s,%s val=0x%lx",P->PC,instr,
              GetIPRName(ainst.m_format.memory_displacement),
              GetRegName(ainst.m_format.ra),
              EV5_GetIPR(cpunum, ainst.m_format.memory_displacement));
      break;
   case PRIV_OP_MTPR: {
      Reg rav;
      CPUVec.GetRegister(cpunum, ainst.m_format.ra, &rav);
      sprintf(buf, "0x%08lx\t0x%08x\tmtpr\t%s,%s val=0x%lx",P->PC,instr,
              GetIPRName(ainst.m_format.memory_displacement),
              GetRegName(ainst.m_format.ra),
              rav);
   } break;
   case PRIV_OP_HW_ST: 
   {
      Reg rav, rbv;
      ev5_hwldst_format ii = (ev5_hwldst_format)instr;
      CPUVec.GetRegister(cpunum, ii.hwmem_format.ra, &rav);
      CPUVec.GetRegister(cpunum, ii.hwmem_format.rb, &rbv);
      sprintf(buf,"0x%08lx\t0x%08x\thwst\t%s,%d(%s) %s=0x%lx %s=0x%lx ",P->PC,instr,
	      GetRegName(ii.hwmem_format.ra),
	      ii.hwmem_format.disp,
	      GetRegName(ii.hwmem_format.rb),
	      GetRegName(ii.hwmem_format.ra),
	      rav,
	      GetRegName(ii.hwmem_format.rb),
	      rbv);
      break;
   }
   case PRIV_OP_HW_LD:
   {
      Reg rbv;
      ev5_hwldst_format ii = (ev5_hwldst_format)instr;
      CPUVec.GetRegister(cpunum, ii.hwmem_format.rb, &rbv);
      sprintf(buf,"0x%08lx\t0x%08x\thwld\t%s,%d(%s) %s=0x%lx",P->PC,instr,
	      GetRegName(ii.hwmem_format.ra),
	      ii.hwmem_format.disp,
	      GetRegName(ii.hwmem_format.rb),
	      GetRegName(ii.hwmem_format.rb),
	      rbv);
      break;
   }
   case PRIV_OP_REI:
      sprintf(buf,"0x%08lx\t0x%08x\thw_rei\n",P->PC,instr);
      break;
   case op_opc14: {
      int fun = ainst.f_format.function;
      const char *opcodeName = "";
      switch (fun) {
      case opc14_itofs: opcodeName = "itofs"; goto itofX;
      case opc14_itoff: opcodeName = "itoff"; goto itofX;
      case opc14_itoft: opcodeName = "itoft"; goto itofX;
    itofX: sprintf(buf, "0x%08lx\t0x%08x\t%s\t%s,%s",P->PC,instr, opcodeName,
		   GetRegName(ainst.f_format.fa),
		   GetFPRegName(ainst.f_format.fc));
    break;
      case opc14_sqrttc: opcodeName = "sqrttc"; goto sqrtX;
      case opc14_sqrttm: opcodeName = "sqrttm"; goto sqrtX;
      case opc14_sqrtt: opcodeName = "sqrtt"; goto sqrtX;
      case opc14_sqrttd: opcodeName = "sqrttd"; goto sqrtX;
      case opc14_sqrttuc: opcodeName = "sqrttuc"; goto sqrtX;
      case opc14_sqrttum: opcodeName = "sqrttum"; goto sqrtX;
      case opc14_sqrttu: opcodeName = "sqrttu"; goto sqrtX;
      case opc14_sqrttud: opcodeName = "sqrttud"; goto sqrtX;
      case opc14_sqrttsuc: opcodeName = "sqrttsuc"; goto sqrtX;
      case opc14_sqrttsum: opcodeName = "sqrttsum"; goto sqrtX;
      case opc14_sqrttsu: opcodeName = "sqrttsu"; goto sqrtX;
      case opc14_sqrttsud: opcodeName = "sqrttsud"; goto sqrtX;
      case opc14_sqrttsuic: opcodeName = "sqrttsuic"; goto sqrtX;
      case opc14_sqrttsuim: opcodeName = "sqrttsuim"; goto sqrtX;
      case opc14_sqrttsui: opcodeName = "sqrttsui"; goto sqrtX;
      case opc14_sqrttsuid: opcodeName = "sqrttsuid"; goto sqrtX;

      case opc14_sqrtsc: opcodeName = "sqrtsc"; goto sqrtX;
      case opc14_sqrtsm: opcodeName = "sqrtsm"; goto sqrtX;
      case opc14_sqrts: opcodeName = "sqrts"; goto sqrtX;
      case opc14_sqrtsd: opcodeName = "sqrtsd"; goto sqrtX;
      case opc14_sqrtsuc: opcodeName = "sqrtsuc"; goto sqrtX;
      case opc14_sqrtsum: opcodeName = "sqrtsum"; goto sqrtX;
      case opc14_sqrtsu: opcodeName = "sqrtsu"; goto sqrtX;
      case opc14_sqrtsud: opcodeName = "sqrtsud"; goto sqrtX;
      case opc14_sqrtssuc: opcodeName = "sqrtssuc"; goto sqrtX;
      case opc14_sqrtssum: opcodeName = "sqrtssum"; goto sqrtX;
      case opc14_sqrtssu: opcodeName = "sqrtssu"; goto sqrtX;
      case opc14_sqrtssud: opcodeName = "sqrtssud"; goto sqrtX;
      case opc14_sqrtssuic: opcodeName = "sqrtssuic"; goto sqrtX;
      case opc14_sqrtssuim: opcodeName = "sqrtssuim"; goto sqrtX;
      case opc14_sqrtssui: opcodeName = "sqrtssui"; goto sqrtX;
      case opc14_sqrtssuid: opcodeName = "sqrtssuid"; goto sqrtX;
    sqrtX: sprintf(buf, "0x%08lx\t0x%08x\t%s\t%s,%s",P->PC,instr, opcodeName,
		   GetFPRegName(ainst.f_format.fa),
		   GetFPRegName(ainst.f_format.fc));
      }
   } break;
   default: 
      disasm(buf,P->PC,instr,&piG1, &piG2, &piG3);
   }
   /*
    * for now make it a warning
    */
   CPUPrint("%d:%ld DIS  | %s \n",
            P->myNum,gammaCurrentTime[P->myNum],
	      
            buf);
}



/*****************************************************************
 * Tcl interface for controlling mipsy's instruction dumping.
 *****************************************************************/
int 
PrintInstTclCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
{
#ifndef PRINT_INSTRUCTIONS
   Tcl_AppendResult(interp, 
                    "instDump not supported unless mipsy compiled -DPRINT_INSTRUCTIONS",
                    NULL);
   return TCL_ERROR;

#else /* PRINT_INSTRUCTIONS */
   int i;

   if (argc < 2) {
      Tcl_AppendResult(interp, 
                       "Bad: should be: instDump <all|off|list of cpunumbers>", 
                       NULL);
      return TCL_ERROR;
   }

   if (!strcmp(argv[1], "off")) {
      CPUWarning("instDump: Turning instruction dumping OFF\n");
      for (i = 0; i < NUM_CPUS(0); i++) {
         printInstMask[i] = 0;
      }
   } else if (!strcmp(argv[1], "all")) {
      CPUWarning("instDump: Turning instruction dumping on for ALL cpus\n");
      for (i = 0; i < NUM_CPUS(0); i++) {
         printInstMask[i] = 1;
      }
   } else {
      for (i=1; i<argc; i++) {
         int cpuNum;
         if ((Tcl_GetInt(interp, argv[i], &cpuNum) != TCL_OK)
             || cpuNum >= NUM_CPUS(0) ) {
            Tcl_AppendResult(interp, "Bad cpu number passed to instDump command",
                             NULL);
            return TCL_ERROR;
         }
         printInstMask[cpuNum] = 1;
         CPUWarning("instDump: Turning instruction dumping on for cpu %d\n", cpuNum);
      }
   }

   return TCL_OK;
#endif /* PRINT_INSTRUCTIONS */
}