コード例 #1
1
ファイル: sim-safe.c プロジェクト: alista24ftp/cpen411
/* 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;

  // conditional-branch offset bits
  int offbits = 0;
  int twoscompl = 0;
  unsigned int abs_offbits = 0;
  
  // number of bits changed in a GPR
  int bits_changed;
  
  int dst_reg; // destination register in part 3

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

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

	// initialize all the arrays
	init_arrays();
	
		
  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:							\
		  dst_reg = O1;					\
		  if(dst_reg > 0 && dst_reg < NUM_REGS) prev_val[dst_reg] = regs.regs_R[dst_reg]; \
          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 (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); */
	}
	
	
	// for registers 0-31 determine the new value written to dst_reg
	if(dst_reg > 0 && dst_reg < NUM_REGS){
		
		bits_changed = func_bits_chng(prev_val[dst_reg], regs.regs_R[dst_reg]);
		reg_contents[dst_reg] += bits_changed;
		num_inst_chng_bits++;
		
	}
	
	
	  if(MD_OP_FLAGS(op) & F_COND)
	{
		g_total_cond_branches++;
		
		// increment histogram index with corresp. offset bits
		offbits = (regs.regs_TPC - regs.regs_PC)/8;
		
		// absolute value representation of the offbits
		abs_offbits = abs(regs.regs_TPC - regs.regs_PC)/8;
				
		if(offbits < 0){
			// if offset is negative, simply add one bit (the signed bit) to its absolute value
			// this is equivalent to offbits = ceil(log10(-1*offbits)/log10(2) + 1); (trust me, I've tried it)
			offbits = floor(log10(abs_offbits)/log10(2) + 2) + 1; 
		}else{
			offbits = floor(log10(abs_offbits)/log10(2) + 2);
		}
		
		
		histogram[offbits]++;

	}
	
	  if(MD_OP_FLAGS(op) & F_DIRJMP)
	{
		g_total_uncond_branches++;
		
	}
	
	  if((MD_OP_FLAGS(op) & F_FCOMP) || (MD_OP_FLAGS(op) & F_FPCOND))
	{
		g_total_fp_inst++;
	}
	
	  if(MD_OP_FLAGS(op) & F_STORE)
	{
		g_total_store_inst++;
	}
	
	  if(MD_OP_FLAGS(op) & F_LOAD)
	{
		g_total_ld_inst++;
	}
	
	  if(MD_OP_FLAGS(op) & F_IMM)
	{
		g_total_imm_inst++;
	}
	
      if (MD_OP_FLAGS(op) & F_MEM)
	{
	  sim_num_refs++;
	  if (MD_OP_FLAGS(op) & F_STORE)
	    is_write = TRUE;
	}

	

      /* 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;
		}
    }
}
コード例 #2
0
ファイル: sim-fast.c プロジェクト: plessl/zippy
/* load program into simulated state */
void
sim_load_prog(char *fname,		/* program to load */
	      int argc, char **argv,	/* program arguments */
	      char **envp)		/* program environment */
{
  /* load program text and data, set up environment, memory, and regs */
  ld_load_prog(fname, argc, argv, envp, &regs, mem, TRUE);

#ifdef TARGET_ALPHA
  /* pre-decode text segment */
  {
    unsigned i, num_insn = (ld_text_size + 3) / 4;

    fprintf(stderr, "** pre-decoding %u insts...", num_insn);

    /* allocate decoded text space */
    dec = mem_create("dec");

    for (i=0; i < num_insn; i++)
      {
	enum md_opcode op;
	md_inst_t inst;
	md_addr_t PC;

	/* compute PC */
	PC = ld_text_base + i * sizeof(md_inst_t);

	/* get instruction from memory */
	MD_FETCH_INST(inst, mem, PC);

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

	/* insert into decoded opcode space */
	MEM_WRITE_WORD(dec, PC << 1, (word_t)op);
	MEM_WRITE_WORD(dec, (PC << 1)+sizeof(word_t), inst);
      }
    fprintf(stderr, "done\n");
  }
#endif /* TARGET_ALPHA */
}
コード例 #3
0
void fetch(void)
{
    md_inst_t inst;
    inst_t *pI = NULL;

    if( g_piperegister[IF_ID_REGISTER] != NULL )
        return; // pipeline is stalled

    // allocate an instruction record, fill in basic information
    pI            = alloc_inst();
    pI->taken     = 0;
    pI->stalled   = 0;
    pI->pc        = g_fetch_pc;
    pI->status    = ALLOCATED;
    pI->op        = 0;
    pI->donecycle = 0xFFFFFFFF; // i.e., largest unsigned integer
    pI->uid       = g_uid++;

    /* get the instruction bits from the instruction memory */
    MD_FETCH_INST(inst, mem, g_fetch_pc);
    pI->inst = inst;

    if( g_fetch_redirected ) {
       // set PC to target of branch/jump
       g_fetch_pc = g_target_pc;

       // Opps... it looks like we fetched the wrong instruction. So, turn it into a "bubble" by 
       // deleting the instruction and leaving the IF/ID register "empty".  Note that, in 
       // hardware we would mux a nop (all zeros) into the IF/ID instruction register field.
       free_inst(pI);
       g_fetch_redirected = 0;
    } else {
       // set PC to point to next sequential instruction
       g_fetch_pc += sizeof(md_inst_t);

       // place the instruction in the IF/ID register
       pI->status = FETCHED; 
       g_piperegister[IF_ID_REGISTER] = pI; 
    }
}
コード例 #4
0
ファイル: sim-cache.c プロジェクト: mshzhb/ece552
/* 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;
    }
}
コード例 #5
0
ファイル: sim-safe.c プロジェクト: sattarab/hazard-lab
/* 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;
    }
}
コード例 #6
0
/* 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;
  }
}
コード例 #7
0
ファイル: sim-safe.c プロジェクト: isaiahtan/ece552
/* 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;
    }
}
コード例 #8
0
ファイル: sim-dis.c プロジェクト: k4v/CA614-Project
/* 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;
    }
}
コード例 #9
0
ファイル: sim-profile.c プロジェクト: bonzini/simplesim-arm
/* 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;
  int setPC;

  fprintf(stderr, "sim: ** starting functional simulation **\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 */

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

      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);

      if (op == NA)
        fatal("bogus opcode detected @ 0x%08p", regs.regs_PC);

      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 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;
	}

      /*
       * 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;
#if 0
	  else if (flags & F_UNCOND)
	    ic = ic_uncond;
	  else if (flags & F_COND)
	    ic = ic_cond;      
#endif
	  else if (flags & F_CTRL && COND == COND_AL)
	    ic = ic_uncond;
	  else if (flags & F_CTRL && COND != COND_AL)
	    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 FIXME
      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);
	    }
	}
#endif

#if FIXME
      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);
	    }
	}
#endif

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

      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;
    }
}
コード例 #10
0
ファイル: sim-bpred.c プロジェクト: k4v/CA614-Project
/* 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;
    }
}
コード例 #11
0
ファイル: sim-fast.c プロジェクト: plessl/zippy
/* start simulation, program loaded, processor precise state initialized */
void
sim_main(void)
{
#ifdef USE_JUMP_TABLE
  /* the jump table employs GNU GCC label extensions to construct an array
     of pointers to instruction implementation code, the simulator then uses
     the table to lookup the location of instruction's implementing code, a
     GNU GCC `goto' extension is then used to jump to the inst's implementing
     code through the op_jump table; as a result, there is no need for
     a main simulator loop, which eliminates one branch from the simulator
     interpreter - crazy, no!?!? */

  /* instruction jump table, this code is GNU GCC specific */
  static void *op_jump[/* max opcodes */] = {
    &&opcode_NA, /* NA */
#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
    &&opcode_##OP,
#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
    &&opcode_##OP,
#define CONNECT(OP)
#include "machine.def"
  };
#endif /* USE_JUMP_TABLE */

  /* register allocate instruction buffer */
  register md_inst_t inst;

  /* decoded opcode */
  register enum md_opcode op;

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

  /* must have natural byte/word ordering */
  if (sim_swap_bytes || sim_swap_words)
    fatal("sim: *fast* functional simulation cannot swap bytes or words");

#ifdef USE_JUMP_TABLE

  regs.regs_NPC = regs.regs_PC;

  /* load instruction */
  MD_FETCH_INST(inst, mem, regs.regs_NPC);

  /* jump to instruction implementation */
  MD_SET_OPCODE(op, inst);
  goto *op_jump[op];

#define DEFINST(OP,MSK,NAME,OPFORM,RES,FLAGS,O1,O2,I1,I2,I3)		\
  opcode_##OP:								\
    /* maintain $r0 semantics */					\
    regs.regs_R[MD_REG_ZERO] = 0;					\
    ZERO_FP_REG();							\
									\
    /* keep an instruction count */					\
    INC_INSN_CTR();							\
									\
    /* locate next instruction */					\
    regs.regs_PC = regs.regs_NPC;					\
									\
    /* set up default next PC */					\
    regs.regs_NPC += sizeof(md_inst_t);					\
									\
    /* execute the instruction */					\
    SYMCAT(OP,_IMPL);							\
									\
    /* get the next instruction */					\
    MD_FETCH_INST(inst, mem, regs.regs_NPC);				\
									\
    /* jump to instruction implementation */				\
    MD_SET_OPCODE(op, inst);						\
    goto *op_jump[op];

#define DEFLINK(OP,MSK,NAME,MASK,SHIFT)					\
  opcode_##OP:								\
    panic("attempted to execute a linking opcode");
#define CONNECT(OP)
#define DECLARE_FAULT(FAULT)						\
	  { /* uncaught... */break; }
#include "machine.def"

  opcode_NA:
    panic("attempted to execute a bogus opcode");

  /* should not get here... */
  panic("exited sim-fast main loop");

#else /* !USE_JUMP_TABLE */

  /* 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 */

      /* keep an instruction count */
#ifndef NO_INSN_COUNT
      sim_num_insn++;
#endif /* !NO_INSN_COUNT */

#ifdef TARGET_ALPHA
      /* load predecoded instruction */
      op = (enum md_opcode)__UNCHK_MEM_READ(dec, regs.regs_PC << 1, word_t);
      inst =
	__UNCHK_MEM_READ(dec, (regs.regs_PC << 1)+sizeof(word_t), md_inst_t);
#else /* !TARGET_ALPHA */
      /* load instruction */
      MD_FETCH_INST(inst, mem, regs.regs_PC);

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

      /* 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)						\
	  { /* uncaught... */break; }
#include "machine.def"
	default:
	  panic("attempted to execute a bogus opcode");
	}

      /* execute next instruction */
      regs.regs_PC = regs.regs_NPC;
      regs.regs_NPC += sizeof(md_inst_t);
    }

#endif /* USE_JUMP_TABLE */
}
コード例 #12
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 */
	  MD_FETCH_INST(inst, mem, regs.regs_PC);

	  /* 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_kind == one_shot_chkpt
	  && !range_cmp_range1(&chkpt_range, regs.regs_NPC,
			       sim_num_insn, sim_num_insn))
	{
	  myfprintf(stderr, "sim: writing checkpoint file `%s' @ inst %n...\n",
		  chkpt_fname, 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);
	}
      else if (chkpt_kind == periodic_chkpt
	       && sim_num_insn == next_chkpt_cycle)
	{
	  char this_chkpt_fname[256];

	  /* 'chkpt_fname' should be a printf format string */
	  sprintf(this_chkpt_fname, chkpt_fname, chkpt_num);
	  chkpt_fd = eio_create(this_chkpt_fname);

	  myfprintf(stderr, "sim: writing checkpoint file `%s' @ inst %n...\n",
		  this_chkpt_fname, sim_num_insn);

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

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

	  chkpt_num++;
	  next_chkpt_cycle += per_chkpt_interval;
	}

      /* 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("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;
    }
}
コード例 #13
0
ファイル: sim-safe.c プロジェクト: BingranLi/branch-predictor
/* 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;
    }