struct frv_interrupt_queue_element *
frv_queue_non_implemented_instruction_interrupt (
  SIM_CPU *current_cpu, const CGEN_INSN *insn
)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  switch (STATE_ARCHITECTURE (sd)->mach)
    {
    case bfd_mach_fr400:
    case bfd_mach_fr450:
    case bfd_mach_fr550:
      break;
    default:
      /* Some machines generate fp_exception or mp_exception for this case.  */
      if (frv_is_float_insn (insn))
	{
	  struct frv_fp_exception_info fp_info = {
	    FSR_NO_EXCEPTION, FTT_UNIMPLEMENTED_FPOP
	  };
	  return frv_queue_fp_exception_interrupt (current_cpu, & fp_info);
	}
      if (frv_is_media_insn (insn))
	{
	  frv_set_mp_exception_registers (current_cpu, MTT_UNIMPLEMENTED_MPOP,
					  0);
	  return NULL; /* no interrupt queued at this time.  */
	}
      break;
    }

  return frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
}
struct frv_interrupt_queue_element *
frv_queue_illegal_instruction_interrupt (
  SIM_CPU *current_cpu, const CGEN_INSN *insn
)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  switch (STATE_ARCHITECTURE (sd)->mach)
    {
    case bfd_mach_fr400:
    case bfd_mach_fr450:
    case bfd_mach_fr550:
      break;
    default:
      /* Some machines generate fp_exception for this case.  */
      if (frv_is_float_insn (insn) || frv_is_media_insn (insn))
	{
	  struct frv_fp_exception_info fp_info = {
	    FSR_NO_EXCEPTION, FTT_SEQUENCE_ERROR
	  };
	  return frv_queue_fp_exception_interrupt (current_cpu, & fp_info);
	}
      break;
    }

  return frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
}
Exemple #3
0
/* Generate the appropriate fp_exception(s) based on the given status code.  */
void
frvbf_fpu_error (CGEN_FPU* fpu, int status)
{
  struct frv_fp_exception_info fp_info = {
    FSR_NO_EXCEPTION, FTT_IEEE_754_EXCEPTION
  };

  if (status &
      (sim_fpu_status_invalid_snan |
       sim_fpu_status_invalid_qnan |
       sim_fpu_status_invalid_isi |
       sim_fpu_status_invalid_idi |
       sim_fpu_status_invalid_zdz |
       sim_fpu_status_invalid_imz |
       sim_fpu_status_invalid_cvi |
       sim_fpu_status_invalid_cmp |
       sim_fpu_status_invalid_sqrt))
    fp_info.fsr_mask |= FSR_INVALID_OPERATION;

  if (status & sim_fpu_status_invalid_div0)
    fp_info.fsr_mask |= FSR_DIVISION_BY_ZERO;

  if (status & sim_fpu_status_inexact)
    fp_info.fsr_mask |= FSR_INEXACT;

  if (status & sim_fpu_status_overflow)
    fp_info.fsr_mask |= FSR_OVERFLOW;

  if (status & sim_fpu_status_underflow)
    fp_info.fsr_mask |= FSR_UNDERFLOW;

  if (status & sim_fpu_status_denorm)
    {
      fp_info.fsr_mask |= FSR_DENORMAL_INPUT;
      fp_info.ftt = FTT_DENORMAL_INPUT;
    }

  if (fp_info.fsr_mask != FSR_NO_EXCEPTION)
    {
      SIM_CPU *current_cpu = (SIM_CPU *)fpu->owner;
      frv_queue_fp_exception_interrupt (current_cpu, & fp_info);
    }
}