Ejemplo n.º 1
0
USI
fr30_inte (SIM_CPU *current_cpu, PCADDR pc, int num)
{
  /* The new pc is the trap #9 vector entry.
     We assume there's a branch there to some handler.  */
  USI new_pc;
  setup_int (current_cpu, pc);
  fr30bf_h_ilm_set (current_cpu, 4);
  new_pc = GETMEMSI (current_cpu, pc,
		     fr30bf_h_dr_get (current_cpu, H_DR_TBR)
		     + 1024 - ((9 + 1) * 4));
  return new_pc;
}
/* Set FSR0, FQ0-FQ9, depending on the interrupt.  */
static void
set_fp_exception_registers (
  SIM_CPU *current_cpu, struct frv_interrupt_queue_element *item
)
{
  int fq_index;
  SI fq;
  SI insn;
  SI fsr0;
  IADDR pc;
  struct frv_fp_exception_info *fp_info;
  SIM_DESC sd = CPU_STATE (current_cpu);

  /* No FQ registers on fr550 */
  if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
    {
      /* Update the fsr.  */
      fp_info = & item->u.fp_info;
      fsr0 = GET_FSR (0);
      SET_FSR_FTT (fsr0, fp_info->ftt);
      SET_FSR (0, fsr0);
      return;
    }

  /* Select an FQ and update it with the exception information.  */
  fq_index = fq_for_exception (current_cpu, item);
  if (fq_index == -1)
    return;

  fp_info = & item->u.fp_info;
  fq = GET_FQ (fq_index);
  SET_FQ_MIV (fq, MIV_FLOAT);
  SET_FQ_SIE (fq, SIE_NIL);
  SET_FQ_FTT (fq, fp_info->ftt);
  SET_FQ_CEXC (fq, fp_info->fsr_mask);
  SET_FQ_VALID (fq);
  SET_FQ (fq_index, fq);

  /* Write the failing insn into FQx.OPC.  */
  pc = item->vpc;
  insn = GETMEMSI (current_cpu, pc, pc);
  SET_FQ_OPC (fq_index, insn);

  /* Update the fsr.  */
  fsr0 = GET_FSR (0);
  SET_FSR_QNE (fsr0); /* FQ not empty */
  SET_FSR_FTT (fsr0, fp_info->ftt);
  SET_FSR (0, fsr0);
}
Ejemplo n.º 3
0
static SEM_PC
SEM_FN_NAME (lm32bf,lw) (SIM_CPU *current_cpu, SEM_ARG sem_arg)
{
#define FLD(f) abuf->fields.sfmt_addi.f
  ARGBUF *abuf = SEM_ARGBUF (sem_arg);
  int UNUSED written = 0;
  IADDR UNUSED pc = abuf->addr;
  SEM_PC vpc = SEM_NEXT_VPC (sem_arg, pc, 4);

  {
    SI opval = GETMEMSI (current_cpu, pc, ADDSI (CPU (h_gr[FLD (f_r0)]), EXTHISI (TRUNCSIHI (FLD (f_imm)))));
    CPU (h_gr[FLD (f_r1)]) = opval;
    TRACE_RESULT (current_cpu, abuf, "gr", 'x', opval);
  }

  return vpc;
#undef FLD
}
Ejemplo n.º 4
0
SI
frvbf_read_mem_SI (SIM_CPU *current_cpu, IADDR pc, SI address)
{
  FRV_CACHE *cache;
  USI hsr0;

  /* Check for access exceptions.  */
  address = check_data_read_address (current_cpu, address, 3);
  address = check_readwrite_address (current_cpu, address, 3);
  
  hsr0 = GET_HSR0 ();
  cache = CPU_DATA_CACHE (current_cpu);
  /* 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_LOAD_ADDRESS (current_cpu) = address;
      CPU_LOAD_LENGTH (current_cpu) = 4;
      return 0x37111319; /* any random value */
    }

  if (GET_HSR0_DCE (hsr0))
    {
      int cycles;
      /* Handle access which crosses cache line boundary */
      SIM_DESC sd = CPU_STATE (current_cpu);
      if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
	{
	  if (DATA_CROSSES_CACHE_LINE (cache, address, 4))
	    return read_mem_unaligned_SI (current_cpu, pc, address); 
	}
      cycles = frv_cache_read (cache, 0, address);
      if (cycles != 0)
	return CACHE_RETURN_DATA (cache, 0, address, SI, 4);
    }

  return GETMEMSI (current_cpu, pc, address);
}
Ejemplo n.º 5
0
USI
fr30_int (SIM_CPU *current_cpu, PCADDR pc, int num)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  host_callback *cb = STATE_CALLBACK (sd);

#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)
    {
      /* The new pc is the trap vector entry.
	 We assume there's a branch there to some handler.  */
      USI new_pc;
      setup_int (current_cpu, pc);
      fr30bf_h_ibit_set (current_cpu, 0);
      new_pc = GETMEMSI (current_cpu, pc,
			 fr30bf_h_dr_get (current_cpu, H_DR_TBR)
			 + 1024 - ((num + 1) * 4));
      return new_pc;
    }

  switch (num)
    {
    case TRAP_SYSCALL :
      {
	/* TODO: find out what the ABI for this is */
	CB_SYSCALL s;

	CB_SYSCALL_INIT (&s);
	s.func = fr30bf_h_gr_get (current_cpu, 0);
	s.arg1 = fr30bf_h_gr_get (current_cpu, 4);
	s.arg2 = fr30bf_h_gr_get (current_cpu, 5);
	s.arg3 = fr30bf_h_gr_get (current_cpu, 6);

	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);
	fr30bf_h_gr_set (current_cpu, 2, s.errcode); /* TODO: check this one */
	fr30bf_h_gr_set (current_cpu, 4, s.result);
	fr30bf_h_gr_set (current_cpu, 1, s.result2); /* TODO: check this one */
	break;
      }

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

    default :
      {
	USI new_pc;
	setup_int (current_cpu, pc);
	fr30bf_h_ibit_set (current_cpu, 0);
	new_pc = GETMEMSI (current_cpu, pc,
			   fr30bf_h_dr_get (current_cpu, H_DR_TBR)
			   + 1024 - ((num + 1) * 4));
	return new_pc;
      }
    }

  /* Fake an "reti" insn.
     Since we didn't push anything to stack, all we need to do is
     update pc.  */
  return pc + 2;
}