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); }
/* 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); } }