print_insts.c 4.75 KB
/*
 * Copyright (C) 1996-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:10 $
 *****************************************************************/

#include "cpu_state.h"
#include "tcl_init.h"
#include "simtypes.h"
#include "mipsy.h"
#include "cpu.h"
#include "cpu_interface.h"
#include "print_insts.h"
#include "sim_error.h"
#include "machine_params.h"
#include "file_formats.h"

#ifdef MIPSY_MXS
#include "ms.h"
#endif

#include <string.h>

#if defined(sgi)
#include <disassembler.h>
#endif

char printInstMask[SIM_MAXCPUS];
int printInstSkipMask;

/*****************************************************************
 * PrintInstsInit
 * 
 * If on the SGI platform, initialize the disassembler. We can come up
 * with a way of doing this on the other machines if desired. 
 ****************************************************************/

void
PrintInstsInit(void)
{
   int i;

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

   printInstSkipMask = 0;

   for (i = 0; i < TOTAL_CPUS; 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.
 *****************************************************************/

static char piBuf[100];

void
SprintInstruction(Inst inst, char* buf)
{
#if defined(sgi) && defined(PRINT_INSTRUCTIONS)
   uint piTarget = 0;
   unsigned piG1 = 0;
   unsigned piG3 = 0;
   int piInstType; 

# if defined(SIM_MIPS32)
   piInstType = disasm(buf, (Elf32_Addr)&inst, (Elf32_Addr)inst, 
                         (Elf32_Addr *)&piG1, (Elf32_Addr *)&piTarget, 
                         (Elf32_Addr *)&piG3);
# else 
   piInstType = disasm64(buf, (Elf64_Addr)&inst, (Elf32_Addr)inst, 
                         (Elf32_Addr *)&piG1, (Elf64_Addr *)&piTarget, 
                         (Elf32_Addr *)&piG3);
# endif
#else
   sprintf(buf, "%x", inst);
#endif
}

/*****************************************************************
 * PrintInstruction
 *****************************************************************/
void   
PrintInstruction(Inst inst, int cpuNum)
{
   SprintInstruction(inst, piBuf);
   CPUPrint("%lld %d: PC %#llx:   %s \n", MipsyCycleCount(cpuNum),
            cpuNum, (Reg64) PE[cpuNum].PC,  piBuf);
} 



/*****************************************************************
 * 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 requires mipsy compiled -DPRINT_INSTRUCTIONS",
                    NULL);
   return TCL_ERROR;
#else /* PRINT_INSTRUCTIONS */
   int i;

#ifndef SOLO
   if (simosCPUType != MIPSY) {
      Tcl_AppendResult(interp, "instDump only supported in mipsy",
                       NULL);
      return TCL_ERROR;
   }
#endif
   if (argc < 2) {
      Tcl_AppendResult(interp, 
                       "Usage: 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 < TOTAL_CPUS; i++) {
         printInstMask[i] = 0;
      }
#ifdef MIPSY_MXS
      enable_iprint = 0;
#endif
   } else if (!strcmp(argv[1], "all")) {
      CPUWarning("instDump: Turning instruction dumping on for ALL cpus\n");
      for (i = 0; i < TOTAL_CPUS; i++) {
         printInstMask[i] = 1;
      }
#ifdef MIPSY_MXS
      enable_iprint = 1;
#endif
   } else {
      for (i=1; i<argc; i++) {
         int cpuNum;
         if ((Tcl_GetInt(interp, argv[i], &cpuNum) != TCL_OK)
             || cpuNum >= TOTAL_CPUS ) {
            Tcl_AppendResult(interp, "Bad CPU num passed to instDump command",
                             NULL);
            return TCL_ERROR;
         }
         printInstMask[cpuNum] = 1;
         CPUWarning("instDump: Inst dumping active for cpu %d\n", cpuNum);
      }
   }

   return TCL_OK;
#endif /* PRINT_INSTRUCTIONS */
}