Example #1
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  int i;
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;

  fprintf(stderr, "sim: ** starting functional simulation w/ caches **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* no access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC,
	       sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      if (itlb)
	cache_access(itlb, Read, IACOMPRESS(regs.regs_PC),
		     NULL, ISCOMPRESS(sizeof(md_inst_t)), 0, NULL, NULL, 0);
      if (cache_il1)
	cache_access(cache_il1, Read, IACOMPRESS(regs.regs_PC),
		     NULL, ISCOMPRESS(sizeof(md_inst_t)), 0, NULL, NULL, 0);
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
          panic("attempted to execute a bogus opcode");
	}

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* update any stats tracked by PC */
      for (i=0; i < pcstat_nelt; i++)
	{
	  counter_t newval;
	  int delta;

	  /* check if any tracked stats changed */
	  newval = STATVAL(pcstat_stats[i]);
	  delta = newval - pcstat_lastvals[i];
	  if (delta != 0)
	    {
	      stat_add_samples(pcstat_sdists[i], regs.regs_PC, delta);
	      pcstat_lastvals[i] = newval;
	    }

	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr, target_PC = 0;
  enum md_opcode op;
  register int is_write;
  int stack_idx;
  enum md_fault_type fault;

  fprintf(stderr, "sim: ** starting functional simulation w/ predictors **\n");

  /* set up initial default next PC */
  SET_NPC(CPC + sizeof(md_inst_t));

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* no access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC,
         sim_num_insn, &regs, mem);

  while (TRUE) {
    /* maintain $r0 semantics */
    regs.regs_R[MD_REG_ZERO] = 0;

#ifdef TARGET_ALPHA
    regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif

    /* get the next instruction to execute */
    MD_FETCH_INST(inst, mem, regs.regs_PC);

    /* keep an instruction count */
    sim_num_insn++;

    /* set default reference address and access mode */
    addr = 0;
    is_write = FALSE;

    /* set default fault - none */
    fault = md_fault_none;

    /* decode the instruction */
    MD_SET_OPCODE(op, inst);

    /* execute the instruction */
    switch (op) {
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) \
case OP:                                                     \
        SYMCAT(OP,_IMPL);                                    \
        break;

#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)                      \
      case OP:                                               \
        panic("attempted to execute a linking opcode");

#define CONNECT(OP)

#define DECLARE_FAULT(FAULT)            \
  { fault = (FAULT); break; }
#include "machine.def"
default:
  panic("attempted to execute a bogus opcode");
    }

    if (fault != md_fault_none)
      fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

    if (MD_OP_FLAGS(op) & F_MEM) {
      sim_num_refs++;
      if (MD_OP_FLAGS(op) & F_STORE)
        is_write = TRUE;
    }

    if (MD_OP_FLAGS(op) & F_CTRL) {
      md_addr_t pred_PC;
      struct bpred_update_t update_rec;

      sim_num_branches++;

      if (pred) {
        /* get the next predicted fetch address */
        pred_PC = bpred_lookup(
            pred,
            regs.regs_PC,      // branch addr
            target_PC,         // target addr
            op,                // instruction opcode
            MD_IS_CALL(op),    // call?
            MD_IS_RETURN(op),  // return?
            &update_rec,       // stack an update ptr
            &stack_idx);       // stash return stack ptr

        /* valid address returned from branch predictor? */
        if (!pred_PC) {
          /* no predicted taken target, attempt not taken target */
          pred_PC = regs.regs_PC + sizeof(md_inst_t);
        }

        bpred_update(
            pred,
            CPC,                                 // branch addr
            NPC,                                 // resolved branch target
            NPC != CPC + sizeof(md_inst_t),      // taken?
            pred_PC != CPC + sizeof(md_inst_t),  // pred taken?
            pred_PC == NPC,                      // correct pred?
            op,                                  // opcode
            &update_rec);                        // predictor update pointer
      }
    }

    /* check for DLite debugger entry condition */
    if (dlite_check_break(NPC,
                          is_write ? ACCESS_WRITE : ACCESS_READ,
                          addr,
                          sim_num_insn,
                          sim_num_insn)) {
      dlite_main(regs.regs_PC, NPC, sim_num_insn, &regs, mem);
    }

    /* go to the next instruction */
    UPDATE_PC

    /* finish early? */
    if (max_insts && sim_num_insn >= max_insts)
      return;
  }
}
Example #3
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;

  /* ECE552 Assignment 1 - BEGIN CODE */

  int r_in[3], r_out[2];

  /* ECE552 Assignment 1 - END CODE */

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t),
	       regs.regs_PC, sim_num_insn, &regs, mem);

  while (TRUE)
    {

      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */

      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
	  r_out[0] = (O1); r_out[1] = (O2);				\
	  r_in[0] = (I1); r_in[1] = (I2); r_in[2] = (I3);		\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }
      
      /* ECE552 Assignment 1 - BEGIN CODE */

      /* ECE552 Part 1 */

      int i, counter_q1 = 0, counter_q2 = 0, counter_q3 = 0;

      for (i = 0;  i < 3; i++)
      {
	if (r_in[i] != DNA && reg_ready_q1[r_in[i]] > sim_num_insn)
	{
	  int cycle = reg_ready_q1[r_in[i]] - sim_num_insn;
	  
	  if (cycle ==  1)
	  {
  	    counter_q1++;
	  }
	  else if (cycle == 2)
	  {
	    counter_q1 =  counter_q1 + 2;
	  }

	  //reset the register
	  reg_ready_q1[r_in[i]] = DNA;
	}
      }

      if (counter_q1 == 1)
      {
        sim_num_one_cycle_hazard_q1++;
      }
      else if (counter_q1 >= 2)
      {
	 sim_num_two_cycle_hazard_q1++;
      }	

      if (r_out[0] != DNA)
      {
	reg_ready_q1[r_out[0]] = sim_num_insn + 3;
      }

      if (r_out[1] != DNA)
      {
	reg_ready_q1[r_out[1]] = sim_num_insn + 3;
      }
    
      sim_num_RAW_hazard_q1 = sim_num_one_cycle_hazard_q1 + sim_num_two_cycle_hazard_q1; 

      /* ECE552 Part 2*/

      for (i = 0;  i < 3; i++)
      {
	if (r_in[i] != DNA && reg_ready_q2[r_in[i]] > sim_num_insn)
	{
	  if ((i == 0) && (MD_OP_FLAGS(op) & F_MEM) &&
	      (MD_OP_FLAGS(op) & F_STORE))
	  {
	      continue;
	  }
          
	  int cycle = reg_ready_q2[r_in[i]] - sim_num_insn;

	  if (cycle == 1)
	  {
	    counter_q2++;
	  }
	  else if (cycle == 2)
	  {
		counter_q2 = counter_q2 + 2;
	  }

          //reset the register
	  reg_ready_q2[r_in[i]] = DNA;
	}
      }
      
      if (counter_q2 == 1)
      {
	sim_num_one_cycle_hazard_q2++;
      }
      else if (counter_q2 >= 2)
      {
	sim_num_two_cycle_hazard_q2++;
      }

      if ((MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
      {
        if (r_out[0] != DNA)
        {
	  reg_ready_q2[r_out[0]] = sim_num_insn + 3;
        }

        if (r_out[1] != DNA)
        {
	  reg_ready_q2[r_out[1]] = sim_num_insn + 3;
        }
      }
      else if (!(MD_OP_FLAGS(op) & F_MEM))
      {
        if (r_out[0] != DNA)
        {
	  reg_ready_q2[r_out[0]] = sim_num_insn + 2;
        }

        if (r_out[1] != DNA)
        {
	  reg_ready_q2[r_out[1]] = sim_num_insn + 2;
        }
      }

      sim_num_RAW_hazard_q2 = sim_num_one_cycle_hazard_q2 + sim_num_two_cycle_hazard_q2;

      /* ECE552 Part 3 */


      if ((MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
      {
	is_current_load = true;
      }
      else if (!(MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
      {
	is_previous_load = false;
      }
 
      if (!(MD_OP_FLAGS(op) & F_LOAD))
      {
		
        for (i = 0;  i < 2; i++)
        {
	  if (r_out[i] != DNA && reg_ready_q3[r_out[i]] > sim_num_insn)
	  {
   	    int cycle = reg_ready_q3[r_out[i]] - sim_num_insn;
	  
	    if (cycle == 1)
	    {
	      //two cycle stall for non mem instruction
	      if (is_current_load == true && is_current_load == true)
	      {
		 sim_num_two_cycle_hazard_q3++;
	      }
	      else
	      {
		sim_num_one_cycle_hazard_q3++;	
	      }
	  }
   	  else if (cycle == 2)
	  {
	    sim_num_two_cycle_hazard_q3++;
	  }

 	  reg_ready_q3[r_out[i]] = DNA;
          counter_q3 = 1;
        }
      } 

	if(counter_q3 == 0 && (r_out[0] != DNA || r_out[1] != DNA))
	{
	  if(is_current_load && is_previous_load && write_back_ready == sim_num_insn + 1)
          {
		sim_num_structural_hazard_q3 = sim_num_structural_hazard_q3 + 2;
          }
	  else if(write_back_ready == sim_num_insn)
	  {
	    sim_num_structural_hazard_q3++;
	  }
	}
    }
      
     if ((MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
     {
       if (r_out[0] != DNA)
       {
	 reg_ready_q3[r_out[0]] = sim_num_insn + 3;
       }

       if (r_out[1] != DNA)
       {
	 reg_ready_q3[r_out[1]] = sim_num_insn + 3;
       }

       write_back_ready = sim_num_insn + 2;
       is_previous_load = true;
     }
     else if (!(MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD))
     {
	is_previous_load = false;
     }

     sim_num_WAW_hazard_q3  = sim_num_one_cycle_hazard_q3 + sim_num_two_cycle_hazard_q3;

     /* ECE552 Assignment 1 - END CODE */

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  if (MD_OP_FLAGS(op) & F_MEM)
	    myfprintf(stderr, "  mem: 0x%08p", addr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
Example #4
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  int i;
  md_inst_t inst;
  register md_addr_t addr;
  register int is_write;
  enum md_opcode op;
  unsigned int flags;
  enum md_fault_type fault;

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* no access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC,
	       sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      mem_access(mem, Read, regs.regs_PC, &inst, sizeof(md_inst_t));

      if (verbose)
	{
	  myfprintf(stderr, "%10n @ 0x%08p: ", sim_num_insn, regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /*
       * profile this instruction
       */
      flags = MD_OP_FLAGS(op);

      if (prof_ic)
	{
	  enum inst_class_t ic;

	  /* compute instruction class */
	  if (flags & F_LOAD)
	    ic = ic_load;
	  else if (flags & F_STORE)
	    ic = ic_store;
	  else if (flags & F_UNCOND)
	    ic = ic_uncond;
	  else if (flags & F_COND)
	    ic = ic_cond;      
	  else if (flags & F_ICOMP)
	    ic = ic_icomp;
	  else if (flags & F_FCOMP)
	    ic = ic_fcomp;
	  else if (flags & F_TRAP)
	    ic = ic_trap;
	  else
	    panic("instruction has no class");

	  /* update instruction class profile */
	  stat_add_sample(ic_prof, (int)ic);
	}

      if (prof_inst)
	{
	  /* update instruction profile */
	  stat_add_sample(inst_prof, (int)op - /* skip NA */1);
	}

      if (prof_bc)
	{
	  enum branch_class_t bc;

	  /* compute instruction class */
	  if (flags & F_CTRL)
	    {
	      if ((flags & (F_CALL|F_DIRJMP)) == (F_CALL|F_DIRJMP))
		bc = bc_call_dir;
	      else if ((flags & (F_CALL|F_INDIRJMP)) == (F_CALL|F_INDIRJMP))
		bc = bc_call_indir;
	      else if ((flags & (F_UNCOND|F_DIRJMP)) == (F_UNCOND|F_DIRJMP))
		bc = bc_uncond_dir;
	      else if ((flags & (F_UNCOND|F_INDIRJMP))== (F_UNCOND|F_INDIRJMP))
		bc = bc_uncond_indir;
	      else if ((flags & (F_COND|F_DIRJMP)) == (F_COND|F_DIRJMP))
		bc = bc_cond_dir;
	      else if ((flags & (F_COND|F_INDIRJMP)) == (F_COND|F_INDIRJMP))
		bc = bc_cond_indir;
	      else
		panic("branch has no class");

	      /* update instruction class profile */
	      stat_add_sample(bc_prof, (int)bc);
	    }
	}

      if (prof_am)
	{
	  enum md_amode_type am;

	  /* update addressing mode pre-probe FSM */
	  MD_AMODE_PREPROBE(op, fsm);

	  /* compute addressing mode */
	  if (flags & F_MEM)
	    {
	      /* compute addressing mode */
	      MD_AMODE_PROBE(am, op, fsm);

	      /* update the addressing mode profile */
	      stat_add_sample(am_prof, (int)am);

	      /* addressing mode pre-probe FSM, after all loads and stores */
	      MD_AMODE_POSTPROBE(fsm);
	    }
	}

      if (prof_seg)
	{
	  if (flags & F_MEM)
	    {
	      /* update instruction profile */
	      stat_add_sample(seg_prof, (int)bind_to_seg(addr));
	    }
	}

      if (prof_tsyms)
	{
	  int tindex;

	  /* attempt to bind inst address to a text segment symbol */
	  sym_bind_addr(regs.regs_PC, &tindex, /* !exact */FALSE, sdb_text);

	  if (tindex >= 0)
	    {
	      if (tindex > sym_ntextsyms)
		panic("bogus text symbol index");

	      stat_add_sample(tsym_prof, tindex);
	    }
	  /* else, could not bind to a symbol */
	}

      if (prof_dsyms)
	{
	  int dindex;

	  if (flags & F_MEM)
	    {
	      /* attempt to bind inst address to a text segment symbol */
	      sym_bind_addr(addr, &dindex, /* !exact */FALSE, sdb_data);

	      if (dindex >= 0)
		{
		  if (dindex > sym_ndatasyms)
		    panic("bogus data symbol index");

		  stat_add_sample(dsym_prof, dindex);
		}
	      /* else, could not bind to a symbol */
	    }
	}

      if (prof_taddr)
	{
	  /* add regs_PC exec event to text address profile */
	  stat_add_sample(taddr_prof, regs.regs_PC);
	}

      /* update any stats tracked by PC */
      for (i=0; i<pcstat_nelt; i++)
	{
	  counter_t newval;
	  int delta;

	  /* check if any tracked stats changed */
	  newval = STATVAL(pcstat_stats[i]);
	  delta = newval - pcstat_lastvals[i];
	  if (delta != 0)
	    {
	      stat_add_samples(pcstat_sdists[i], regs.regs_PC, delta);
	      pcstat_lastvals[i] = newval;
	    }

	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
Example #5
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* ECE552 Pre-Assignment - BEGIN CODE*/
  int r_out[2], r_in[3];
  /* ECE552 Pre-Assignment - END CODE*/

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t),
	       regs.regs_PC, sim_num_insn, &regs, mem);

  while (TRUE)
    {

      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */

      switch (op)
      {
	      /* ECE552 Pre-Assignment - BEGIN CODE*/
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3) \
	      case OP: \
		       r_out[0] = (O1); r_out[1] = (O2); \
	      r_in[0] = (I1); r_in[1] = (I2); r_in[2] = (I3); \
	      SYMCAT(OP,_IMPL); \
	      break;
	      /* ECE552 Pre-Assignment - END CODE*/
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      /* ECE552 Pre-Assignment - BEGIN CODE*/
      if ( (MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD) ) {
	      sim_num_loads++;
      }
      {
	      int i;
	      for (i = 0; i < 3; i++) {
		      if (r_in[i] != DNA && reg_ready [r_in [i]] > sim_num_insn) {
			      if ((i == 0) && (MD_OP_FLAGS(op) & F_MEM) &&
					      (MD_OP_FLAGS(op) & F_STORE)) {
				      continue;
			      }
			      sim_num_lduh++;
			      break;
		      }
	      }
      }
      if ((MD_OP_FLAGS(op) & F_MEM) && (MD_OP_FLAGS(op) & F_LOAD)) {
	      if (r_out[0] != DNA)
		      reg_ready[r_out[0]] = sim_num_insn + 2;
	      if (r_out[1] != DNA)
		      reg_ready[r_out[1]] = sim_num_insn + 2;
      }
      /* ECE552 Pre-Assignment - END CODE*/

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  if (MD_OP_FLAGS(op) & F_MEM)
	    myfprintf(stderr, "  mem: 0x%08p", addr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
Example #6
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register bool_t is_write;
  enum md_fault_type fault;

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC,
	       sim_num_insn, &regs, mem);

  /* fast forward simulator loop, performs functional simulation for
     FASTFWD_COUNT insts, then turns on performance (timing) simulation */
  if (fastfwd_count > 0)
    {
      int icount;

      fprintf(stderr, "sim: ** fast forwarding %d insts **\n", fastfwd_count);

      fastfwding = TRUE;
      for (icount=0; icount < fastfwd_count; icount++)
	{
	  /* maintain $r0 semantics */
	  regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
	  regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

	  /* get the next instruction to execute */
	  inst = __UNCHK_MEM_READ(mem, regs.regs_PC, md_inst_t);

	  /* set default reference address */
	  addr = 0; is_write = FALSE;

	  /* set default fault - none */
	  fault = md_fault_none;

	  /* decode the instruction */
	  MD_SET_OPCODE(op, inst);

	  /* execute the instruction */
	  switch (op)
	    {
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	    case OP:							\
	      SYMCAT(OP,_IMPL);						\
	      break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
	    case OP:							\
	      panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#undef DECLARE_FAULT
#define DECLARE_FAULT(FAULT)						\
	      { fault = (FAULT); break; }
#include "machine.def"
	    default:
	      panic("attempted to execute a bogus opcode");
	    }

	  if (fault != md_fault_none)
	    fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

	  /* update memory access stats */
	  if (MD_OP_FLAGS(op) & F_MEM)
	    {
	      if (MD_OP_FLAGS(op) & F_STORE)
		is_write = TRUE;
	    }

	  /* check for DLite debugger entry condition */
	  if (dlite_check_break(regs.regs_NPC,
				is_write ? ACCESS_WRITE : ACCESS_READ,
				addr, sim_num_insn, sim_num_insn))
	    dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

	  /* go to the next instruction */
	  regs.regs_PC = regs.regs_NPC;
	  regs.regs_NPC += sizeof(md_inst_t);
	}
    }
  fastfwding = FALSE;

  if (trace_fd != NULL)
    {
      fprintf(stderr, "sim: writing EIO file initial checkpoint...\n");
      if (eio_write_chkpt(&regs, mem, trace_fd) != -1)
	panic("checkpoint code is broken");
    }

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* check if checkpoint should be generated here... */
      if (chkpt_active
	  && !range_cmp_range1(&chkpt_range, regs.regs_NPC,
			       sim_num_insn, sim_num_insn))
	{
	  fprintf(stderr, "sim: writing checkpoint file `%s' @ inst %.0f...\n",
		  chkpt_fname, (double)sim_num_insn);

	  /* write the checkpoint file */
	  eio_write_chkpt(&regs, mem, chkpt_fd);

	  /* close the checkpoint file */
	  eio_close(chkpt_fd);

	  /* exit jumps to the target set in main() */
	  longjmp(sim_exit_buf, /* exitcode + fudge */0+1);
	}

      /* get the next instruction to execute */
      inst = __UNCHK_MEM_READ(mem, regs.regs_PC, md_inst_t);

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("bogus opcode");
      }

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
Example #7
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;

  fprintf(stderr, "sim: ** starting functional simulation **\n");

  /* set up initial default next PC */
  regs.regs_PC = ld_text_base;
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t),
	       regs.regs_PC, sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
#ifndef TARGET_ARM
      regs.regs_R[MD_REG_ZERO] = 0;
#endif
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      if (regs.regs_PC >= ld_text_bound)
	{
	  info("all instructions decoded...");
	  exit(0);
	}

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

#if 0
      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3,I4)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);
#endif

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  if (MD_OP_FLAGS(op) & F_MEM)
	    myfprintf(stderr, "  mem: 0x%08p", addr);
	  fprintf(stderr, "\n");
	  myfprintf(stderr, "           op: %d, inst: 0x%08x\n", op, inst);
	  /* fflush(stderr); */
	}

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
Example #8
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr, target_PC;
  enum md_opcode op;
  register int is_write;
  int stack_idx;
  enum md_fault_type fault;
  int setPC, in_flow = FALSE, flow_index, nflow;
  struct md_uop_t flowtab[MD_MAX_FLOWLEN];

  fprintf(stderr, "sim: ** starting functional simulation w/ predictors **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* synchronize register files... */
  regs.regs_R[MD_REG_PC] = regs.regs_PC;

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* no access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC,
	       sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
#ifndef TARGET_ARM
      regs.regs_R[MD_REG_ZERO] = 0;
#endif
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      if (!in_flow)
	{
	  /* keep an instruction count */
	  sim_num_insn++;

	  /* get the next instruction to execute */
	  MD_FETCH_INST(inst, mem, regs.regs_PC);

	  /* decode the instruction */
	  MD_SET_OPCODE(op, inst);

	  if (MD_OP_FLAGS(op) & F_CISC)
	    {
	      /* get instruction flow */
	      nflow = md_get_flow(op, inst, flowtab);
	      if (nflow > 0)
		{
		  in_flow = TRUE;
		  flow_index = 0;
		}
	      else
		fatal("could not locate CISC flow");
	      sim_num_uops += nflow;
	    }
	  else
	    sim_num_uops++;
	}
      if (in_flow)
	{
	  op = flowtab[flow_index].op;
	  inst = flowtab[flow_index++].inst;
	  if (flow_index == nflow)
	    in_flow = FALSE;
	}

      if (op == NA)
	panic("bogus opcode detected @ 0x%08p", regs.regs_PC);
      if (MD_OP_FLAGS(op) & F_CISC)
	panic("CISC opcode decoded");

      setPC = 0;
      regs.regs_R[MD_REG_PC] = regs.regs_PC;

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,O3,I1,I2,I3,I4)	\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFUOP(OP,NAME,OPFORM,RES,FLAGS,O1,O2,O3,I1,I2,I3,I4)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (setPC != 0/* regs.regs_R[MD_REG_PC] != regs.regs_PC */)
	regs.regs_NPC = regs.regs_R[MD_REG_PC];

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      if (MD_OP_FLAGS(op) & F_CTRL)
	{
	  md_addr_t pred_PC;
	  struct bpred_update_t update_rec;

	  sim_num_branches++;

	  if (pred)
	    {
	      /* get the next predicted fetch address */
	      pred_PC = bpred_lookup(pred,
				     /* branch addr */regs.regs_PC,
				     /* target */target_PC,
				     /* inst opcode */op,
				     /* call? */MD_IS_CALL(op),
				     /* return? */MD_IS_RETURN(op),
				     /* stash an update ptr */&update_rec,
				     /* stash return stack ptr */&stack_idx);

	      /* valid address returned from branch predictor? */
	      if (!pred_PC)
		{
		  /* no predicted taken target, attempt not taken target */
		  pred_PC = regs.regs_PC + sizeof(md_inst_t);
		}

	      bpred_update(pred,
			   /* branch addr */regs.regs_PC,
			   /* resolved branch target */regs.regs_NPC,
			   /* taken? */regs.regs_NPC != (regs.regs_PC +
							 sizeof(md_inst_t)),
			   /* pred taken? */pred_PC != (regs.regs_PC +
							sizeof(md_inst_t)),
			   /* correct pred? */pred_PC == regs.regs_NPC,
			   /* opcode */op,
			   /* predictor update pointer */&update_rec);
	    }
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      if (!in_flow)
	{
	  regs.regs_PC = regs.regs_NPC;
	  regs.regs_NPC += sizeof(md_inst_t);
	}

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
Example #9
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr, target_PC;
  enum md_opcode op;
  register int is_write;
  int stack_idx;
  enum md_fault_type fault;

  int out1, out2, in1, in2, in3;	  /* register names */
  int v_out1, v_out2, v_in1, v_in2, v_in3;/* register values */
  int vl_out1, vl_out2, vl_in1, vl_in2, vl_in3;
  md_addr_t addr_dispatch;              /* access_address */
  int m_size;                           /* access_size */
  FILE *stream;
  md_addr_t predicted_PC;

  fprintf(stderr, "sim: ** starting functional simulation w/ predictors **\n");

  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* no access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t), regs.regs_PC,
	       sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      mem_access(mem, Read, regs.regs_PC, &inst, sizeof(md_inst_t));

      /* keep an instruction count */
      sim_num_insn++;

      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,CLASS,O1,O2,I1,I2,I3,            \
                VO1,LO1,VO2,LO2,ADDR,VI1,LI1,VI2,LI2,VI3,LI3,M_Size)    \
	case OP:							\
	  in1 = I1; in2 = I2; in3 = I3;					\
	  v_in1 = VI1; v_in2 = VI2; v_in3 = VI3;			\
	  vl_in1 = LI1; vl_in2 = LI2; vl_in3 = LI3;			\
          SYMCAT(OP,_IMPL);						\
	  out1 = O1; out2 = O2;						\
	  v_out1 = VO1; v_out2 = VO2;					\
	  vl_out1 = LO1; vl_out2 = LO2;					\
	  addr_dispatch = ADDR;						\
	  m_size = M_Size;						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "operand.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      if (MD_OP_FLAGS(op) & F_CTRL)
	{
	  md_addr_t pred_PC;
	  struct bpred_update_t update_rec;

	  sim_num_branches++;

	  if (pred)
	    {
	      /* get the next predicted fetch address */
	      pred_PC = bpred_lookup(pred,
				     /* branch addr */regs.regs_PC,
				     /* target */target_PC,
				     /* inst opcode */op,
				     /* call? */MD_IS_CALL(op),
				     /* return? */MD_IS_RETURN(op),
				     /* stash an update ptr */&update_rec,
				     /* stash return stack ptr */&stack_idx);

	      /* valid address returned from branch predictor? */
	      if (!pred_PC)
		{
		  /* no predicted taken target, attempt not taken target */
		  pred_PC = regs.regs_PC + sizeof(md_inst_t);
		}

	      bpred_update(pred,
			   /* branch addr */regs.regs_PC,
			   /* resolved branch target */regs.regs_NPC,
			   /* taken? */regs.regs_NPC != (regs.regs_PC +
							 sizeof(md_inst_t)),
			   /* pred taken? */pred_PC != (regs.regs_PC +
							sizeof(md_inst_t)),
			   /* correct pred? */pred_PC == regs.regs_NPC,
			   /* opcode */op,
			   /* predictor update pointer */&update_rec);
	    }
	  predicted_PC = pred_PC;
	}

      /*   ここから下を見ればどの変数に何が入っているか分かるはず。 */
      stream = stdout;
      fprintf(stream, "############################################################ \n");
      fprintf(stream, " --- trace count(%d) \n", (int)sim_num_insn);
      fprintf(sim_fd, "%s, inst: `",
      fprintf(stream, "       opcode: %s, inst: `",
	      MD_OP_NAME(op));
      md_print_insn(inst, regs.regs_PC, stream);
      fprintf(stream, "'\n");
      myfprintf(stream, "         PC: 0x%08p, NPC: 0x%08p",
		regs.regs_PC, regs.regs_NPC);
      if(pred)
	myfprintf(stream, " (pred_PC: 0x%08p)\n",
		  regs.regs_PC, regs.regs_NPC, predicted_PC);
      else
	myfprintf(stream, "\n");
      fprintf(stream," |  in(r%02d,r%02d,r%02d),out(r%02d,r%02d),\n",
	      in1, in2, in3, out1, out2);
      fprintf(stream," |  IN(%8x,%8x,%8x),OUT(%8x,%8x)addr(%8x)|\n",
	      v_in1, v_in2, v_in3, v_out1, v_out2, addr_dispatch);
      /* ダブルワードだった場合,この変数がセットされる */
      fprintf(stream," |  in(%8x,%8x,%8x),out(%8x,%8x)         |\n",
	      vl_in1, vl_in2, vl_in3, vl_out1, vl_out2);

      /* machine.h をみるとopから命令の種類を判別する方法が分かる。以下は例 */
      if (op == MD_NOP_OP)
	{
	  fprintf(stream, "   NOP instruction \n");
	}
      else if (MD_OP_FLAGS(op) & F_MEM)
	{
	  fprintf(stream, "   MEMORY instruction \n");
	  if (MD_OP_FLAGS(op) & F_STORE)
	    fprintf(stream, "        store instruction \n");
	  else if (MD_OP_FLAGS(op) & F_LOAD)
	    fprintf(stream, "        load instruction \n");
	  fprintf(stream, "          ld/st address is %010x\n",
		  addr_dispatch);
	  fprintf(stream, "          ld/st size is %2d\n",
		  m_size);
	  /* ロードストアがバイト単位なのか,ワード単位なのか,
	     ハーフワード単位なのかは,opを見て判断できる。
	     例えば, md_op2name[op] が "sh"ならハーフワードである。
	     しかし、これだと面倒なのでoperand.defを改良した方が良い
	     かも知れない。これはおまかせ。
	     */
	  
	  /* ロードストアの詳細に関しては,machine.def を参照。
	     例えば,store halfの場合,(machine.def をエディタで開いて
	     "sh"と言う文字列をサーチすれば該当箇所が見つかる)
	     以下のようにかかれている。*/
	  /*
                #define SH_IMPL                                     
                  {                                                 
                    half_t _src;                                    
                    enum md_fault_type _fault;                      
                    _src = (half_t)(word_t)GPR(RT);                 
                    WRITE_HALF(_src, GPR(BS) + OFS, _fault);        
                    if (_fault != md_fault_none)                    
                      DECLARE_FAULT(_fault);                        
                   }
		   */
	  /*ここで、GPR(BS)はBS番レジスタの値 OFS はオフセットを示す。
	    そして,GPR(RT)はRT番レジスタの値を示す。
	    そしてWRITE_HALF(_src, GPR(BS) + OFS, _fault);は
	    値 _src をアドレス GPR(BS) + OFS に書き込む事を意味する。
	    書き込みのサイズは,halfワードである。*/
	}
      else if (MD_OP_FLAGS(op) & F_CTRL)
	{
	  fprintf(stream, "   BRANCH instruction \n");
	  if (MD_IS_CALL(op))
	    fprintf(stream, "        function call \n");
	  else if (MD_IS_RETURN(op))
	    fprintf(stream, "        function return \n");
	  else if (MD_IS_INDIR(op))
	    fprintf(stream, "        indirect jump \n");
	  else if ((MD_OP_FLAGS(op) & (F_CTRL|F_DIRJMP)) == (F_CTRL|F_DIRJMP))
	    fprintf(stream, "        direct jump \n");
	}
      else
	{
	  fprintf(stream, "   other instruction \n");
	}
      /* この応用として,いきなりopからstoreを判別するには,以下のようにすれば良い*/
      if ((MD_OP_FLAGS(op) & (F_MEM|F_STORE)) == (F_MEM|F_STORE))
	{
	  /*fprintf(stream, "   store instruction \n");*/
	}
      else if ((MD_OP_FLAGS(op) & (F_MEM|F_LOAD)) == (F_MEM|F_LOAD))
	{
	  /*fprintf(stream, "   load instruction \n");*/
	}

      /* ここまで */


      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }
}
Example #10
0
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
  md_inst_t inst;
  register md_addr_t addr;
  enum md_opcode op;
  register int is_write;
  enum md_fault_type fault;

  /* ECE552 Assignment 2 - BEGIN CODE */
  
  int i, j;
 
  /* Initialization of tables */

  for (i = 0; i < 4096; i++)
  {
    two_bit_table[i] = n;
  }
   
  for (i = 0; i < 8; i++)
  {
    for (j = 0; j < 64; j++)
    {
	PHT[i][j] = n;
    }
  }

  for (i = 0; i < 32; i++)
  {
    for (j = 0; j < 1024; j++)
    {
	GPHT[i][j] = n;
    }
  }

 /* ECE552 Assignment 2 - END CODE */

  fprintf(stderr, "sim: ** starting functional simulation **\n");
  
  /* set up initial default next PC */
  regs.regs_NPC = regs.regs_PC + sizeof(md_inst_t);

  /* check for DLite debugger entry condition */
  if (dlite_check_break(regs.regs_PC, /* !access */0, /* addr */0, 0, 0))
    dlite_main(regs.regs_PC - sizeof(md_inst_t),
	       regs.regs_PC, sim_num_insn, &regs, mem);

  while (TRUE)
    {
      /* maintain $r0 semantics */
      regs.regs_R[MD_REG_ZERO] = 0;
#ifdef TARGET_ALPHA
      regs.regs_F.d[MD_REG_ZERO] = 0.0;
#endif /* TARGET_ALPHA */

      /* get the next instruction to execute */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

      /* keep an instruction count */
      sim_num_insn++;
	  
      /* set default reference address and access mode */
      addr = 0; is_write = FALSE;

      /* set default fault - none */
      fault = md_fault_none;

      /* decode the instruction */
      MD_SET_OPCODE(op, inst);

      /* execute the instruction */
      switch (op)
	{
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
	case OP:							\
          SYMCAT(OP,_IMPL);						\
          break;
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
        case OP:							\
          panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { fault = (FAULT); break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
      }

      /* ECE552 Assignment 2 - BEGIN CODE */

      if (MD_OP_FLAGS(op) & F_COND)
      {
	int index = (regs.regs_PC >> 3) & 0xfff;
	int bht_index = (regs.regs_PC >> 6) & 0x1ff;
	int pht_index = (regs.regs_PC >> 3) & 0x7;
	int pht_row_index = BHT[bht_index];
	int gap_pht_index = (regs.regs_PC >> 3) & 0x1f;
	int g_pht_row_index = GHR;
 	

	if (regs.regs_NPC == regs.regs_PC + sizeof(md_inst_t))
	{
          br_taken = 0;
	  sim_num_mispred_static++;
        }
        else
        {
	  br_taken = 1;
        }

	/* two bit saturation branch predictor */

        switch(two_bit_table[index])
        {
	  case N:
	    if (br_taken)
	    {
	      two_bit_table[index] = n;
	      sim_num_mispred_2bitsat++;
	    }
	    break;
	  case n:
  	    if (br_taken)
	    {
	      two_bit_table[index] = t;
	      sim_num_mispred_2bitsat++;
	    }
	    else
	    {
	      two_bit_table[index] = N;
	    }
	    break;
	  case t:
	    if (br_taken)
	    {
	      two_bit_table[index] = T;
	    }
	    else
	    {
	      two_bit_table[index] = n;
	      sim_num_mispred_2bitsat++;
	    }
	    break;
	  case T:
	    if (!br_taken)
	    {
	      two_bit_table[index] = t;
	      sim_num_mispred_2bitsat++;
	    }
	    break;
        }

	/* two level adaptive branch predictor */

	switch(PHT[pht_index][pht_row_index])
        {
	  case N:
	    if (br_taken)
	    {
	      PHT[pht_index][pht_row_index] = n;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f) | 0x1;
	      sim_num_mispred_2level++;
	    }
	    else
	    {
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f);
	    }
	    break;
	  case n:
  	    if (br_taken)
	    {
	      PHT[pht_index][pht_row_index] = t;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f)  | 0x1;
	      sim_num_mispred_2level++;
	    }
	    else
	    {
	      PHT[pht_index][pht_row_index] = N;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f);
	    }
	    break;
	  case t:
	    if (br_taken)
	    {
	      PHT[pht_index][pht_row_index] = T;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f)  | 0x1;
	    }
	    else
	    {
	      PHT[pht_index][pht_row_index] = n;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f);
	      sim_num_mispred_2level++;
	    }
	    break;
	  case T:
	    if (br_taken)
	    {
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f)  | 0x1;
	    }
	    else
	    {
	      PHT[pht_index][pht_row_index] = t;
	      BHT[bht_index] = ((BHT[bht_index] << 1) & 0x3f);
	      sim_num_mispred_2level++;
	    }
	    break;
        }

	/* open ended branch predictor */

	switch(GPHT[gap_pht_index][g_pht_row_index])
        {
	  case N:
	    if (br_taken)
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = n;
	      GHR = ((GHR << 1) & 0x3ff) | 0x1;
	      sim_num_mispred_openend++;
	    }
	    else
	    {
	      GHR = ((GHR << 1) & 0x3ff);
	    }
	    break;
	  case n:
  	    if (br_taken)
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = t;
	      GHR = ((GHR << 1) & 0x3ff) | 0x1;
	      sim_num_mispred_openend++;
	    }
	    else
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = N;
	      GHR = ((GHR << 1) & 0x3ff);
	    }
	    break;
	  case t:
	    if (br_taken)
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = T;
	      GHR = ((GHR << 1) & 0x3ff) | 0x1;
	    }
	    else
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = n;
	      GHR = ((GHR << 1) & 0x3ff);
	      sim_num_mispred_openend++;
	    }
	    break;
	  case T:
	    if (br_taken)
	    {
	      GHR = ((GHR << 1) & 0x3ff) | 0x1;
	    }
	    else
	    {
	      GPHT[gap_pht_index][g_pht_row_index] = t;
	      GHR = ((GHR << 1) & 0x3ff);
	      sim_num_mispred_openend++;
	    }
	    break;
        }
	
        sim_num_br++;
      }

      /* ECE552 Assignment 2 - END CODE */

      if (fault != md_fault_none)
	fatal("fault (%d) detected @ 0x%08p", fault, regs.regs_PC);

      if (verbose)
	{
	  myfprintf(stderr, "%10n [xor: 0x%08x] @ 0x%08p: ",
		    sim_num_insn, md_xor_regs(&regs), regs.regs_PC);
	  md_print_insn(inst, regs.regs_PC, stderr);
	  if (MD_OP_FLAGS(op) & F_MEM)
	    myfprintf(stderr, "  mem: 0x%08p", addr);
	  fprintf(stderr, "\n");
	  /* fflush(stderr); */
	}

      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

      /* check for DLite debugger entry condition */
      if (dlite_check_break(regs.regs_NPC,
			    is_write ? ACCESS_WRITE : ACCESS_READ,
			    addr, sim_num_insn, sim_num_insn))
	dlite_main(regs.regs_PC, regs.regs_NPC, sim_num_insn, &regs, mem);

      /* go to the next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);

      /* finish early? */
      if (max_insts && sim_num_insn >= max_insts)
	return;
    }