Exemplo n.º 1
0
/* Handle TRA and TIRA insns.  */
void
frv_itrap (SIM_CPU *current_cpu, PCADDR pc, USI base, SI offset)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  host_callback *cb = STATE_CALLBACK (sd);
  USI num = ((base + offset) & 0x7f) + 0x80;

#ifdef SIM_HAVE_BREAKPOINTS
  /* Check for breakpoints "owned" by the simulator first, regardless
     of --environment.  */
  if (num == TRAP_BREAKPOINT)
    {
      /* First try sim-break.c.  If it's a breakpoint the simulator "owns"
	 it doesn't return.  Otherwise it returns and let's us try.  */
      sim_handle_breakpoint (sd, current_cpu, pc);
      /* Fall through.  */
    }
#endif

  if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)
    {
      frv_queue_software_interrupt (current_cpu, num);
      return;
    }

  switch (num)
    {
    case TRAP_SYSCALL :
      {
	CB_SYSCALL s;
	CB_SYSCALL_INIT (&s);
	s.func = GET_H_GR (7);
	s.arg1 = GET_H_GR (8);
	s.arg2 = GET_H_GR (9);
	s.arg3 = GET_H_GR (10);

	if (s.func == TARGET_SYS_exit)
	  {
	    sim_engine_halt (sd, current_cpu, NULL, pc, sim_exited, s.arg1);
	  }

	s.p1 = (PTR) sd;
	s.p2 = (PTR) current_cpu;
	s.read_mem = syscall_read_mem;
	s.write_mem = syscall_write_mem;
	cb_syscall (cb, &s);
	SET_H_GR (8, s.result);
	SET_H_GR (9, s.result2);
	SET_H_GR (10, s.errcode);
	break;
      }

    case TRAP_BREAKPOINT:
      sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
      break;

      /* Add support for dumping registers, either at fixed traps, or all
	 unknown traps if configured with --enable-sim-trapdump.  */
    default:
#if !TRAPDUMP
      frv_queue_software_interrupt (current_cpu, num);
      return;
#endif

#ifdef TRAP_REGDUMP1
    case TRAP_REGDUMP1:
#endif

#ifdef TRAP_REGDUMP2
    case TRAP_REGDUMP2:
#endif

#if TRAPDUMP || (defined (TRAP_REGDUMP1)) || (defined (TRAP_REGDUMP2))
      {
	char buf[256];
	int i, j;

	buf[0] = 0;
	if (STATE_TEXT_SECTION (sd)
	    && pc >= STATE_TEXT_START (sd)
	    && pc < STATE_TEXT_END (sd))
	  {
	    const char *pc_filename = (const char *)0;
	    const char *pc_function = (const char *)0;
	    unsigned int pc_linenum = 0;

	    if (bfd_find_nearest_line (STATE_PROG_BFD (sd),
				       STATE_TEXT_SECTION (sd),
				       (struct bfd_symbol **) 0,
				       pc - STATE_TEXT_START (sd),
				       &pc_filename, &pc_function, &pc_linenum)
		&& (pc_function || pc_filename))
	      {
		char *p = buf+2;
		buf[0] = ' ';
		buf[1] = '(';
		if (pc_function)
		  {
		    strcpy (p, pc_function);
		    p += strlen (p);
		  }
		else
		  {
		    char *q = (char *) strrchr (pc_filename, '/');
		    strcpy (p, (q) ? q+1 : pc_filename);
		    p += strlen (p);
		  }

		if (pc_linenum)
		  {
		    sprintf (p, " line %d", pc_linenum);
		    p += strlen (p);
		  }

		p[0] = ')';
		p[1] = '\0';
		if ((p+1) - buf > sizeof (buf))
		  abort ();
	      }
	  }

	sim_io_printf (sd,
		       "\nRegister dump,    pc = 0x%.8x%s, base = %u, offset = %d\n",
		       (unsigned)pc, buf, (unsigned)base, (int)offset);

	for (i = 0; i < 64; i += 8)
	  {
	    long g0 = (long)GET_H_GR (i);
	    long g1 = (long)GET_H_GR (i+1);
	    long g2 = (long)GET_H_GR (i+2);
	    long g3 = (long)GET_H_GR (i+3);
	    long g4 = (long)GET_H_GR (i+4);
	    long g5 = (long)GET_H_GR (i+5);
	    long g6 = (long)GET_H_GR (i+6);
	    long g7 = (long)GET_H_GR (i+7);

	    if ((g0 | g1 | g2 | g3 | g4 | g5 | g6 | g7) != 0)
	      sim_io_printf (sd,
			     "\tgr%02d - gr%02d:   0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx\n",
			     i, i+7, g0, g1, g2, g3, g4, g5, g6, g7);
	  }

	for (i = 0; i < 64; i += 8)
	  {
	    long f0 = (long)GET_H_FR (i);
	    long f1 = (long)GET_H_FR (i+1);
	    long f2 = (long)GET_H_FR (i+2);
	    long f3 = (long)GET_H_FR (i+3);
	    long f4 = (long)GET_H_FR (i+4);
	    long f5 = (long)GET_H_FR (i+5);
	    long f6 = (long)GET_H_FR (i+6);
	    long f7 = (long)GET_H_FR (i+7);

	    if ((f0 | f1 | f2 | f3 | f4 | f5 | f6 | f7) != 0)
	      sim_io_printf (sd,
			     "\tfr%02d - fr%02d:   0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx\n",
			     i, i+7, f0, f1, f2, f3, f4, f5, f6, f7);
	  }

	sim_io_printf (sd,
		       "\tlr/lcr/cc/ccc: 0x%.8lx 0x%.8lx 0x%.8lx 0x%.8lx\n",
		       (long)GET_H_SPR (272),
		       (long)GET_H_SPR (273),
		       (long)GET_H_SPR (256),
		       (long)GET_H_SPR (263));
      }
      break;
#endif
    }
}
Exemplo n.º 2
0
void
frvbf_check_recovering_store (
  SIM_CPU *current_cpu, PCADDR address, SI regno, int size, int is_float
)
{
  FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
  int reg_ix;

  CPU_RSTR_INVALIDATE(current_cpu) = 0;

  for (reg_ix = next_valid_nesr (current_cpu, NO_NESR);
       reg_ix != NO_NESR;
       reg_ix = next_valid_nesr (current_cpu, reg_ix))
    {
      if (address == GET_H_SPR (H_SPR_NEEAR0 + reg_ix))
	{
	  SI nesr = GET_NESR (reg_ix);
	  int nesr_drn = GET_NESR_DRN (nesr);
	  BI nesr_fr = GET_NESR_FR (nesr);
	  SI remain;

	  /* Invalidate cache block containing this address.
	     If we need to count cycles, then the cache operation will be
	     initiated from the model profiling functions.
	     See frvbf_model_....  */
	  if (model_insn)
	    {
	      CPU_RSTR_INVALIDATE(current_cpu) = 1;
	      CPU_LOAD_ADDRESS (current_cpu) = address;
	    }
	  else
	    frv_cache_invalidate (cache, address, 1/* flush */);

	  /* Copy the stored value to the register indicated by NESR.DRN.  */
	  for (remain = size; remain > 0; remain -= 4)
	    {
	      SI value;

	      if (is_float)
		value = GET_H_FR (regno);
	      else
		value = GET_H_GR (regno);

	      switch (size)
		{
		case 1:
		  value &= 0xff;
		  break;
		case 2:
		  value &= 0xffff;
		  break;
		default:
		  break;
		}

	      if (nesr_fr)
		sim_queue_fn_sf_write (current_cpu, frvbf_h_fr_set, nesr_drn,
				       value);
	      else
		sim_queue_fn_si_write (current_cpu, frvbf_h_gr_set, nesr_drn,
				       value);

	      nesr_drn++;
	      regno++;
	    }
	  break; /* Only consider the first matching register.  */
	}
    } /* loop over active neear registers.  */
}
Exemplo n.º 3
0
SF
frvbf_h_fr_get (SIM_CPU *current_cpu, UINT regno)
{
  return GET_H_FR (regno);
}