/* frv exception and interrupt support
   Copyright (C) 1999-2024 Free Software Foundation, Inc.
   Contributed by Red Hat.

This file is part of the GNU simulators.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* This must come before any other includes.  */
#include "defs.h"

#define WANT_CPU frvbf
#define WANT_CPU_FRVBF

#include "sim-main.h"
#include "sim-signal.h"
#include "bfd.h"
#include <stdlib.h>
#include "cgen-mem.h"

/* FR-V Interrupt table.
   Describes the interrupts supported by the FR-V.
   This table *must* be maintained in order of interrupt priority as defined by
   frv_interrupt_kind.  */
#define DEFERRED 1
#define PRECISE  1
#define ITABLE_ENTRY(name, class, deferral, precision, offset) \
  {FRV_##name, FRV_EC_##name, class, deferral, precision, offset}

struct frv_interrupt frv_interrupt_table[NUM_FRV_INTERRUPT_KINDS] =
{
  /* External interrupts */
  ITABLE_ENTRY(INTERRUPT_LEVEL_1,            FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x21),
  ITABLE_ENTRY(INTERRUPT_LEVEL_2,            FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x22),
  ITABLE_ENTRY(INTERRUPT_LEVEL_3,            FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x23),
  ITABLE_ENTRY(INTERRUPT_LEVEL_4,            FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x24),
  ITABLE_ENTRY(INTERRUPT_LEVEL_5,            FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x25),
  ITABLE_ENTRY(INTERRUPT_LEVEL_6,            FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x26),
  ITABLE_ENTRY(INTERRUPT_LEVEL_7,            FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x27),
  ITABLE_ENTRY(INTERRUPT_LEVEL_8,            FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x28),
  ITABLE_ENTRY(INTERRUPT_LEVEL_9,            FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x29),
  ITABLE_ENTRY(INTERRUPT_LEVEL_10,           FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x2a),
  ITABLE_ENTRY(INTERRUPT_LEVEL_11,           FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x2b),
  ITABLE_ENTRY(INTERRUPT_LEVEL_12,           FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x2c),
  ITABLE_ENTRY(INTERRUPT_LEVEL_13,           FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x2d),
  ITABLE_ENTRY(INTERRUPT_LEVEL_14,           FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x2e),
  ITABLE_ENTRY(INTERRUPT_LEVEL_15,           FRV_EXTERNAL_INTERRUPT, !DEFERRED, !PRECISE, 0x2f),
  /* Software interrupt */
  ITABLE_ENTRY(TRAP_INSTRUCTION,             FRV_SOFTWARE_INTERRUPT, !DEFERRED, !PRECISE, 0x80),
  /* Program interrupts */
  ITABLE_ENTRY(COMMIT_EXCEPTION,             FRV_PROGRAM_INTERRUPT,  !DEFERRED, !PRECISE, 0x19),
  ITABLE_ENTRY(DIVISION_EXCEPTION,           FRV_PROGRAM_INTERRUPT,  !DEFERRED, !PRECISE, 0x17),
  ITABLE_ENTRY(DATA_STORE_ERROR,             FRV_PROGRAM_INTERRUPT,  !DEFERRED, !PRECISE, 0x14),
  ITABLE_ENTRY(DATA_ACCESS_EXCEPTION,        FRV_PROGRAM_INTERRUPT,  !DEFERRED, !PRECISE, 0x13),
  ITABLE_ENTRY(DATA_ACCESS_MMU_MISS,         FRV_PROGRAM_INTERRUPT,  !DEFERRED, !PRECISE, 0x12),
  ITABLE_ENTRY(DATA_ACCESS_ERROR,            FRV_PROGRAM_INTERRUPT,  !DEFERRED, !PRECISE, 0x11),
  ITABLE_ENTRY(MP_EXCEPTION,                 FRV_PROGRAM_INTERRUPT,  !DEFERRED, !PRECISE, 0x0e),
  ITABLE_ENTRY(FP_EXCEPTION,                 FRV_PROGRAM_INTERRUPT,  !DEFERRED, !PRECISE, 0x0d),
  ITABLE_ENTRY(MEM_ADDRESS_NOT_ALIGNED,      FRV_PROGRAM_INTERRUPT,  !DEFERRED, !PRECISE, 0x10),
  ITABLE_ENTRY(REGISTER_EXCEPTION,           FRV_PROGRAM_INTERRUPT,  !DEFERRED,  PRECISE, 0x08),
  ITABLE_ENTRY(MP_DISABLED,                  FRV_PROGRAM_INTERRUPT,  !DEFERRED,  PRECISE, 0x0b),
  ITABLE_ENTRY(FP_DISABLED,                  FRV_PROGRAM_INTERRUPT,  !DEFERRED,  PRECISE, 0x0a),
  ITABLE_ENTRY(PRIVILEGED_INSTRUCTION,       FRV_PROGRAM_INTERRUPT,  !DEFERRED,  PRECISE, 0x06),
  ITABLE_ENTRY(ILLEGAL_INSTRUCTION,          FRV_PROGRAM_INTERRUPT,  !DEFERRED,  PRECISE, 0x07),
  ITABLE_ENTRY(INSTRUCTION_ACCESS_EXCEPTION, FRV_PROGRAM_INTERRUPT,  !DEFERRED,  PRECISE, 0x03),
  ITABLE_ENTRY(INSTRUCTION_ACCESS_ERROR,     FRV_PROGRAM_INTERRUPT,  !DEFERRED,  PRECISE, 0x02),
  ITABLE_ENTRY(INSTRUCTION_ACCESS_MMU_MISS,  FRV_PROGRAM_INTERRUPT,  !DEFERRED,  PRECISE, 0x01),
  ITABLE_ENTRY(COMPOUND_EXCEPTION,           FRV_PROGRAM_INTERRUPT,  !DEFERRED, !PRECISE, 0x20),
  /* Break interrupt */
  ITABLE_ENTRY(BREAK_EXCEPTION,              FRV_BREAK_INTERRUPT,    !DEFERRED, !PRECISE, 0xff),
  /* Reset interrupt */
  ITABLE_ENTRY(RESET,                        FRV_RESET_INTERRUPT,    !DEFERRED, !PRECISE, 0x00)
};

/* The current interrupt state.  */
struct frv_interrupt_state frv_interrupt_state;

/* maintain the address of the start of the previous VLIW insn sequence.  */
IADDR previous_vliw_pc;

/* Add a break interrupt to the interrupt queue.  */
struct frv_interrupt_queue_element *
frv_queue_break_interrupt (SIM_CPU *current_cpu)
{
  return frv_queue_interrupt (current_cpu, FRV_BREAK_EXCEPTION);
}

/* Add a software interrupt to the interrupt queue.  */
struct frv_interrupt_queue_element *
frv_queue_software_interrupt (SIM_CPU *current_cpu, SI offset)
{
  struct frv_interrupt_queue_element *new_element
    = frv_queue_interrupt (current_cpu, FRV_TRAP_INSTRUCTION);

  struct frv_interrupt *interrupt = & frv_interrupt_table[new_element->kind];
  interrupt->handler_offset = offset;

  return new_element;
}

/* Add a program interrupt to the interrupt queue.  */
struct frv_interrupt_queue_element *
frv_queue_program_interrupt (
  SIM_CPU *current_cpu, enum frv_interrupt_kind kind
)
{
  return frv_queue_interrupt (current_cpu, kind);
}

/* Add an external interrupt to the interrupt queue.  */
struct frv_interrupt_queue_element *
frv_queue_external_interrupt (
  SIM_CPU *current_cpu, enum frv_interrupt_kind kind
)
{
  if (! GET_H_PSR_ET ()
      || (kind != FRV_INTERRUPT_LEVEL_15 && kind < GET_H_PSR_PIL ()))
    return NULL; /* Leave it for later.  */

  return frv_queue_interrupt (current_cpu, kind);
}

/* Add any interrupt to the interrupt queue. It will be added in reverse
   priority order.  This makes it easy to find the highest priority interrupt
   at the end of the queue and to remove it after processing.  */
struct frv_interrupt_queue_element *
frv_queue_interrupt (SIM_CPU *current_cpu, enum frv_interrupt_kind kind)
{
  int i;
  int j;
  int limit = frv_interrupt_state.queue_index;
  struct frv_interrupt_queue_element *new_element;
  enum frv_interrupt_class iclass;

  if (limit >= FRV_INTERRUPT_QUEUE_SIZE)
    abort (); /* TODO: Make the queue dynamic */

  /* Find the right place in the queue.  */
  for (i = 0; i < limit; ++i)
    {
      if (frv_interrupt_state.queue[i].kind >= kind)
	break;
    }

  /* Don't queue two external interrupts of the same priority.  */
  iclass = frv_interrupt_table[kind].iclass;
  if (i < limit && iclass == FRV_EXTERNAL_INTERRUPT)
    {
      if (frv_interrupt_state.queue[i].kind == kind)
	return & frv_interrupt_state.queue[i];
    }

  /* Make room for the new interrupt in this spot.  */
  for (j = limit - 1; j >= i; --j)
    frv_interrupt_state.queue[j + 1] = frv_interrupt_state.queue[j];

  /* Add the new interrupt.  */
  frv_interrupt_state.queue_index++;
  new_element = & frv_interrupt_state.queue[i];
  new_element->kind = kind;
  new_element->vpc = CPU_PC_GET (current_cpu);
  new_element->u.data_written.length = 0;
  frv_set_interrupt_queue_slot (current_cpu, new_element);

  return new_element;
}

struct frv_interrupt_queue_element *
frv_queue_register_exception_interrupt (SIM_CPU *current_cpu, enum frv_rec rec)
{
  struct frv_interrupt_queue_element *new_element =
    frv_queue_program_interrupt (current_cpu, FRV_REGISTER_EXCEPTION);

  new_element->u.rec = rec;

  return new_element;
}

struct frv_interrupt_queue_element *
frv_queue_mem_address_not_aligned_interrupt (SIM_CPU *current_cpu, USI addr)
{
  struct frv_interrupt_queue_element *new_element;
  USI isr = GET_ISR ();

  /* Make sure that this exception is not masked.  */
  if (GET_ISR_EMAM (isr))
    return NULL;

  /* Queue the interrupt.  */
  new_element = frv_queue_program_interrupt (current_cpu,
					     FRV_MEM_ADDRESS_NOT_ALIGNED);
  new_element->eaddress = addr;
  new_element->u.data_written = frv_interrupt_state.data_written;
  frv_interrupt_state.data_written.length = 0;

  return new_element;
}

struct frv_interrupt_queue_element *
frv_queue_data_access_error_interrupt (SIM_CPU *current_cpu, USI addr)
{
  struct frv_interrupt_queue_element *new_element;
  new_element = frv_queue_program_interrupt (current_cpu,
					     FRV_DATA_ACCESS_ERROR);
  new_element->eaddress = addr;
  return new_element;
}

struct frv_interrupt_queue_element *
frv_queue_data_access_exception_interrupt (SIM_CPU *current_cpu)
{
  return frv_queue_program_interrupt (current_cpu, FRV_DATA_ACCESS_EXCEPTION);
}

struct frv_interrupt_queue_element *
frv_queue_instruction_access_error_interrupt (SIM_CPU *current_cpu)
{
  return frv_queue_program_interrupt (current_cpu, FRV_INSTRUCTION_ACCESS_ERROR);
}

struct frv_interrupt_queue_element *
frv_queue_instruction_access_exception_interrupt (SIM_CPU *current_cpu)
{
  return frv_queue_program_interrupt (current_cpu, FRV_INSTRUCTION_ACCESS_EXCEPTION);
}

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

struct frv_interrupt_queue_element *
frv_queue_privileged_instruction_interrupt (SIM_CPU *current_cpu, const CGEN_INSN *insn)
{
  /* The fr550 has no privileged instruction interrupt. It uses
     illegal_instruction.  */
  SIM_DESC sd = CPU_STATE (current_cpu);
  if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
    return frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);

  return frv_queue_program_interrupt (current_cpu, FRV_PRIVILEGED_INSTRUCTION);
}

struct frv_interrupt_queue_element *
frv_queue_float_disabled_interrupt (SIM_CPU *current_cpu)
{
  /* The fr550 has no fp_disabled interrupt. It uses illegal_instruction.  */
  SIM_DESC sd = CPU_STATE (current_cpu);
  if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
    return frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
  
  return frv_queue_program_interrupt (current_cpu, FRV_FP_DISABLED);
}

struct frv_interrupt_queue_element *
frv_queue_media_disabled_interrupt (SIM_CPU *current_cpu)
{
  /* The fr550 has no mp_disabled interrupt. It uses illegal_instruction.  */
  SIM_DESC sd = CPU_STATE (current_cpu);
  if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
    return frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
  
  return frv_queue_program_interrupt (current_cpu, FRV_MP_DISABLED);
}

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

/* Queue the given fp_exception interrupt. Also update fp_info by removing
   masked interrupts and updating the 'slot' flield.  */
struct frv_interrupt_queue_element *
frv_queue_fp_exception_interrupt (
  SIM_CPU *current_cpu, struct frv_fp_exception_info *fp_info
)
{
  SI fsr0 = GET_FSR (0);
  int tem = GET_FSR_TEM (fsr0);
  int aexc = GET_FSR_AEXC (fsr0);
  struct frv_interrupt_queue_element *new_element = NULL;

  /* Update AEXC with the interrupts that are masked.  */
  aexc |= fp_info->fsr_mask & ~tem;
  SET_FSR_AEXC (fsr0, aexc);
  SET_FSR (0, fsr0);

  /* update fsr_mask with the exceptions that are enabled.  */
  fp_info->fsr_mask &= tem;

  /* If there is an unmasked interrupt then queue it, unless
     this was a non-excepting insn, in which case simply set the NE
     status registers.  */
  if (frv_interrupt_state.ne_index != NE_NOFLAG
      && fp_info->fsr_mask != FSR_NO_EXCEPTION)
    {
      SET_NE_FLAG (frv_interrupt_state.f_ne_flags, 
		   frv_interrupt_state.ne_index);
      /* TODO -- Set NESR for chips which support it.  */
      new_element = NULL;
    }
  else if (fp_info->fsr_mask != FSR_NO_EXCEPTION
	   || fp_info->ftt == FTT_UNIMPLEMENTED_FPOP
	   || fp_info->ftt == FTT_SEQUENCE_ERROR
	   || fp_info->ftt == FTT_INVALID_FR)
    {
      new_element = frv_queue_program_interrupt (current_cpu, FRV_FP_EXCEPTION);
      new_element->u.fp_info = *fp_info;
    }

  return new_element;
}

struct frv_interrupt_queue_element *
frv_queue_division_exception_interrupt (SIM_CPU *current_cpu, enum frv_dtt dtt)
{
  struct frv_interrupt_queue_element *new_element =
    frv_queue_program_interrupt (current_cpu, FRV_DIVISION_EXCEPTION);

  new_element->u.dtt = dtt;

  return new_element;
}

/* Check for interrupts caused by illegal insn access.  These conditions are
   checked in the order specified by the fr400 and fr500 LSI specs.  */
void
frv_detect_insn_access_interrupts (SIM_CPU *current_cpu, SCACHE *sc)
{

  const CGEN_INSN *insn = sc->argbuf.idesc->idata;
  FRV_VLIW *vliw = CPU_VLIW (current_cpu);

  /* Check for vliw constraints.  */
  if (vliw->constraint_violation)
    frv_queue_illegal_instruction_interrupt (current_cpu, insn);
  /* Check for non-excepting insns.  */
  else if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_NON_EXCEPTING)
      && ! GET_H_PSR_NEM ())
    frv_queue_non_implemented_instruction_interrupt (current_cpu, insn);
  /* Check for conditional insns.  */
  else if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONDITIONAL)
      && ! GET_H_PSR_CM ())
    frv_queue_non_implemented_instruction_interrupt (current_cpu, insn);
  /* Make sure floating point support is enabled.  */
  else if (! GET_H_PSR_EF ())
    {
      /* Generate fp_disabled if it is a floating point insn or if PSR.EM is
	 off and the insns accesses a fp register.  */
      if (frv_is_float_insn (insn)
	  || (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR_ACCESS)
	      && ! GET_H_PSR_EM ()))
	frv_queue_float_disabled_interrupt (current_cpu);
    }
  /* Make sure media support is enabled.  */
  else if (! GET_H_PSR_EM ())
    {
      /* Generate mp_disabled if it is a media insn.  */
      if (frv_is_media_insn (insn) || CGEN_INSN_NUM (insn) == FRV_INSN_MTRAP)
	frv_queue_media_disabled_interrupt (current_cpu);
    }
  /* Check for privileged insns.  */
  else if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_PRIVILEGED) &&
	   ! GET_H_PSR_S ())
    frv_queue_privileged_instruction_interrupt (current_cpu, insn);
#if 0 /* disable for now until we find out how FSR0.QNE gets reset.  */
  else
    {
      /* Enter the halt state if FSR0.QNE is set and we are executing a
	 floating point insn, a media insn or an insn which access a FR
	 register.  */
      SIM_DESC sd = CPU_STATE (current_cpu);
      SI fsr0 = GET_FSR (0);
      if (GET_FSR_QNE (fsr0)
	  && (frv_is_float_insn (insn) || frv_is_media_insn (insn)
	      || CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_FR_ACCESS)))
	{
	  sim_engine_halt (sd, current_cpu, NULL, GET_H_PC (), sim_stopped,
			   SIM_SIGINT);
	}
    }
#endif
}

/* Record the current VLIW slot in the given interrupt queue element.  */
void
frv_set_interrupt_queue_slot (
  SIM_CPU *current_cpu, struct frv_interrupt_queue_element *item
)
{
  FRV_VLIW *vliw = CPU_VLIW (current_cpu);
  int slot = vliw->next_slot - 1;
  item->slot = (*vliw->current_vliw)[slot];
}

/* Handle an individual interrupt.  */
static void
handle_interrupt (SIM_CPU *current_cpu, IADDR pc)
{
  struct frv_interrupt *interrupt;
  int writeback_done = 0;
  while (1)
    {
      /* Interrupts are queued in priority order with the highest priority
	 last.  */
      int index = frv_interrupt_state.queue_index - 1;
      struct frv_interrupt_queue_element *item
	= & frv_interrupt_state.queue[index];
      interrupt = & frv_interrupt_table[item->kind];

      switch (interrupt->iclass)
	{
	case FRV_EXTERNAL_INTERRUPT:
	  /* Perform writeback first. This may cause a higher priority
	     interrupt.  */
	  if (! writeback_done)
	    {
	      frvbf_perform_writeback (current_cpu);
	      writeback_done = 1;
	      continue;
	    }
	  frv_external_interrupt (current_cpu, item, pc);
	  return;
	case FRV_SOFTWARE_INTERRUPT:
	  frv_interrupt_state.queue_index = index;
	  frv_software_interrupt (current_cpu, item, pc);
	  return;
	case FRV_PROGRAM_INTERRUPT:
	  /* If the program interrupt is not strict (imprecise), then perform
	     writeback first. This may, in turn, cause a higher priority
	     interrupt.  */
	  if (! interrupt->precise && ! writeback_done)
	    {
	      frv_interrupt_state.imprecise_interrupt = item;
	      frvbf_perform_writeback (current_cpu);
	      writeback_done = 1;
	      continue;
	    }
	  frv_interrupt_state.queue_index = index;
	  frv_program_interrupt (current_cpu, item, pc);
	  return;
	case FRV_BREAK_INTERRUPT:
	  frv_interrupt_state.queue_index = index;
	  frv_break_interrupt (current_cpu, interrupt, pc);
	  return;
	case FRV_RESET_INTERRUPT:
	  break;
	default:
	  break;
	}
      frv_interrupt_state.queue_index = index;
      break; /* out of loop.  */
    }

  /* We should never get here.  */
  {
    SIM_DESC sd = CPU_STATE (current_cpu);
    sim_engine_abort (sd, current_cpu, pc,
		      "interrupt class not supported %d\n",
		      interrupt->iclass);
  }
}

/* Check to see the if the RSTR.HR or RSTR.SR bits have been set.  If so, handle
   the appropriate reset interrupt.  */
static int
check_reset (SIM_CPU *current_cpu, IADDR pc)
{
  int hsr0;
  int hr;
  int sr;
  SI rstr;
  FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
  IADDR address = RSTR_ADDRESS;

  /* We don't want this to show up in the cache statistics, so read the
     cache passively.  */
  if (! frv_cache_read_passive_SI (cache, address, & rstr))
    rstr = sim_core_read_unaligned_4 (current_cpu, pc, read_map, address);

  hr = GET_RSTR_HR (rstr);
  sr = GET_RSTR_SR (rstr);

  if (! hr && ! sr)
    return 0; /* no reset.  */

  /* Reinitialize the machine state.  */
  if (hr)
    frv_hardware_reset (current_cpu);
  else
    frv_software_reset (current_cpu);

  /* Branch to the reset address.  */
  hsr0 = GET_HSR0 ();
  if (GET_HSR0_SA (hsr0))
    SET_H_PC (0xff000000);
  else
    SET_H_PC (0);

  return 1; /* reset */
}

/* Process any pending interrupt(s) after a group of parallel insns.  */
void
frv_process_interrupts (SIM_CPU *current_cpu)
{
  SI NE_flags[2];
  /* Need to save the pc here because writeback may change it (due to a
     branch).  */
  IADDR pc = CPU_PC_GET (current_cpu);

  /* Check for a reset before anything else.  */
  if (check_reset (current_cpu, pc))
    return;

  /* First queue the writes for any accumulated NE flags.  */
  if (frv_interrupt_state.f_ne_flags[0] != 0
      || frv_interrupt_state.f_ne_flags[1] != 0)
    {
      GET_NE_FLAGS (NE_flags, H_SPR_FNER0);
      NE_flags[0] |= frv_interrupt_state.f_ne_flags[0];
      NE_flags[1] |= frv_interrupt_state.f_ne_flags[1];
      SET_NE_FLAGS (H_SPR_FNER0, NE_flags);
    }

  /* If there is no interrupt pending, then perform parallel writeback.  This
     may cause an interrupt.  */
  if (frv_interrupt_state.queue_index <= 0)
    frvbf_perform_writeback (current_cpu);

  /* If there is an interrupt pending, then process it.  */
  if (frv_interrupt_state.queue_index > 0)
    handle_interrupt (current_cpu, pc);
}

/* Find the next available ESR and return its index */
static int
esr_for_data_access_exception (
  SIM_CPU *current_cpu, struct frv_interrupt_queue_element *item
)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
    return 8; /* Use ESR8, EPCR8.  */

  if (item->slot == UNIT_I0)
    return 8; /* Use ESR8, EPCR8, EAR8, EDR8.  */

  return 9; /* Use ESR9, EPCR9, EAR9.  */
}

/* Set the next available EDR register with the data which was to be stored
   and return the index of the register.  */
static int
set_edr_register (
  SIM_CPU *current_cpu, struct frv_interrupt_queue_element *item, int edr_index
)
{
  /* EDR0, EDR4 and EDR8 are available as blocks of 4.
       SI data uses EDR3, EDR7 and EDR11
       DI data uses EDR2, EDR6 and EDR10
       XI data uses EDR0, EDR4 and EDR8.  */
  int i;
  edr_index += 4 - item->u.data_written.length;
  for (i = 0; i < item->u.data_written.length; ++i)
    SET_EDR (edr_index + i, item->u.data_written.words[i]);

  return edr_index;
};

/* Clear ESFR0, EPCRx, ESRx, EARx and EDRx.  */
static void
clear_exception_status_registers (SIM_CPU *current_cpu)
{
  int i;
  /* It is only necessary to clear the flag bits indicating which registers
     are valid.  */
  SET_ESFR (0, 0);
  SET_ESFR (1, 0);

  for (i = 0; i <= 2; ++i)
    {
      SI esr = GET_ESR (i);
      CLEAR_ESR_VALID (esr);
      SET_ESR (i, esr);
    }
  for (i = 8; i <= 15; ++i)
    {
      SI esr = GET_ESR (i);
      CLEAR_ESR_VALID (esr);
      SET_ESR (i, esr);
    }
}

/* Record state for media exception.  */
void
frv_set_mp_exception_registers (
  SIM_CPU *current_cpu, enum frv_msr_mtt mtt, int sie
)
{
  /* Record the interrupt factor in MSR0.  */
  SI msr0 = GET_MSR (0);
  if (GET_MSR_MTT (msr0) == MTT_NONE)
    SET_MSR_MTT (msr0, mtt);

  /* Also set the OVF bit in the appropriate MSR as well as MSR0.AOVF.  */
  if (mtt == MTT_OVERFLOW)
    {
      FRV_VLIW *vliw = CPU_VLIW (current_cpu);
      int slot = vliw->next_slot - 1;
      SIM_DESC sd = CPU_STATE (current_cpu);

      /* If this insn is in the M2 slot, then set MSR1.OVF and MSR1.SIE,
	 otherwise set MSR0.OVF and MSR0.SIE.  */
      if (STATE_ARCHITECTURE (sd)->mach != bfd_mach_fr550 && (*vliw->current_vliw)[slot] == UNIT_FM1)
	{
	  SI msr = GET_MSR (1);
	  OR_MSR_SIE (msr, sie);
	  SET_MSR_OVF (msr);
	  SET_MSR (1, msr);
	}
      else
	{
	  OR_MSR_SIE (msr0, sie);
	  SET_MSR_OVF (msr0);
	}

      /* Generate the interrupt now if MSR0.MPEM is set on fr550 */
      if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550 && GET_MSR_MPEM (msr0))
	frv_queue_program_interrupt (current_cpu, FRV_MP_EXCEPTION);
      else
	{
	  /* Regardless of the slot, set MSR0.AOVF.  */
	  SET_MSR_AOVF (msr0);
	}
    }

  SET_MSR (0, msr0);
}

/* Determine the correct FQ register to use for the given exception.
   Return -1 if a register is not available.  */
static int
fq_for_exception (
  SIM_CPU *current_cpu, struct frv_interrupt_queue_element *item
)
{
  SI fq;
  struct frv_fp_exception_info *fp_info = & item->u.fp_info;

  /* For fp_exception overflow, underflow or inexact, use FQ0 or FQ1.  */
  if (fp_info->ftt == FTT_IEEE_754_EXCEPTION
      && (fp_info->fsr_mask & (FSR_OVERFLOW | FSR_UNDERFLOW | FSR_INEXACT)))
    {
      fq = GET_FQ (0);
      if (! GET_FQ_VALID (fq))
	return 0; /* FQ0 is available.  */
      fq = GET_FQ (1);
      if (! GET_FQ_VALID (fq))
	return 1; /* FQ1 is available.  */

      /* No FQ register is available */
      {
	SIM_DESC sd = CPU_STATE (current_cpu);
	IADDR pc = CPU_PC_GET (current_cpu);
	sim_engine_abort (sd, current_cpu, pc, "No FQ register available\n");
      }
      return -1;
    }
  /* For other exceptions, use FQ2 if the insn was in slot F0/I0 and FQ3
     otherwise.  */
  if (item->slot == UNIT_FM0 || item->slot == UNIT_I0)
    return 2;

  return 3;
}

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

/* Record the state of a division exception in the ISR.  */
static void
set_isr_exception_fields (
  SIM_CPU *current_cpu, struct frv_interrupt_queue_element *item
)
{
  USI isr = GET_ISR ();
  int dtt = GET_ISR_DTT (isr);
  dtt |= item->u.dtt;
  SET_ISR_DTT (isr, dtt);
  SET_ISR (isr);
}

/* Set ESFR0, EPCRx, ESRx, EARx and EDRx, according to the given program
   interrupt.  */
static void
set_exception_status_registers (
  SIM_CPU *current_cpu, struct frv_interrupt_queue_element *item
)
{
  struct frv_interrupt *interrupt = & frv_interrupt_table[item->kind];
  int reg_index = -1;
  int set_ear = 0;
  int set_edr = 0;
  int set_daec = 0;
  int set_epcr = 0;
  SI esr = 0;
  SIM_DESC sd = CPU_STATE (current_cpu);

  /* If the interrupt is strict (precise) or the interrupt is on the insns
     in the I0 pipe, then set the 0 registers.  */
  if (interrupt->precise)
    {
      reg_index = 0;
      if (interrupt->kind == FRV_REGISTER_EXCEPTION)
	SET_ESR_REC (esr, item->u.rec);
      else if (interrupt->kind == FRV_INSTRUCTION_ACCESS_EXCEPTION)
	SET_ESR_IAEC (esr, item->u.iaec);
      /* For fr550, don't set epcr for precise interrupts.  */
      if (STATE_ARCHITECTURE (sd)->mach != bfd_mach_fr550)
	set_epcr = 1;
    }
  else
    {
      switch (interrupt->kind)
	{
	case FRV_DIVISION_EXCEPTION:
	  set_isr_exception_fields (current_cpu, item);
	  ATTRIBUTE_FALLTHROUGH;  /* To set reg_index.  */
	case FRV_COMMIT_EXCEPTION:
	  /* For fr550, always use ESR0.  */
	  if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
	    reg_index = 0;
	  else if (item->slot == UNIT_I0)
	    reg_index = 0;
	  else if (item->slot == UNIT_I1)
	    reg_index = 1;
	  set_epcr = 1;
	  break;
	case FRV_DATA_STORE_ERROR:
	  reg_index = 14; /* Use ESR14.  */
	  break;
	case FRV_DATA_ACCESS_ERROR:
	  reg_index = 15; /* Use ESR15, EPCR15.  */
	  set_ear = 1;
	  break;
	case FRV_DATA_ACCESS_EXCEPTION:
	  set_daec = 1;
	  ATTRIBUTE_FALLTHROUGH;
	case FRV_DATA_ACCESS_MMU_MISS:
	case FRV_MEM_ADDRESS_NOT_ALIGNED:
	  /* Get the appropriate ESR, EPCR, EAR and EDR.
	     EAR will be set. EDR will not be set if this is a store insn.  */
	  set_ear = 1;
	  /* For fr550, never use EDRx.  */
	  if (STATE_ARCHITECTURE (sd)->mach != bfd_mach_fr550)
	    if (item->u.data_written.length != 0)
	      set_edr = 1;
	  reg_index = esr_for_data_access_exception (current_cpu, item);
	  set_epcr = 1;
	  break;
	case FRV_MP_EXCEPTION:
	  /* For fr550, use EPCR2 and ESR2.  */
	  if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
	    {
	      reg_index = 2;
	      set_epcr = 1;
	    }
	  break; /* MSR0-1, FQ0-9 are already set.  */
	case FRV_FP_EXCEPTION:
	  set_fp_exception_registers (current_cpu, item);
	  /* For fr550, use EPCR2 and ESR2.  */
	  if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr550)
	    {
	      reg_index = 2;
	      set_epcr = 1;
	    }
	  break;
	default:
	  {
	    IADDR pc = CPU_PC_GET (current_cpu);
	    sim_engine_abort (sd, current_cpu, pc,
			      "invalid non-strict program interrupt kind: %d\n",
			      interrupt->kind);
	    break;
	  }
	}
    } /* non-strict (imprecise) interrupt */

  /* Now fill in the selected exception status registers.  */
  if (reg_index != -1)
    {
      /* Now set the exception status registers.  */
      SET_ESFR_FLAG (reg_index);
      SET_ESR_EC (esr, interrupt->ec);

      if (set_epcr)
	{
	  if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400)
	    SET_EPCR (reg_index, previous_vliw_pc);
	  else
	    SET_EPCR (reg_index, item->vpc);
	}

      if (set_ear)
	{
	  SET_EAR (reg_index, item->eaddress);
	  SET_ESR_EAV (esr);
	}
      else
	CLEAR_ESR_EAV (esr);

      if (set_edr)
	{
	  int edn = set_edr_register (current_cpu, item, 0/* EDR0-3 */);
	  SET_ESR_EDN (esr, edn);
	  SET_ESR_EDV (esr);
	}
      else
	CLEAR_ESR_EDV (esr);

      if (set_daec)
	SET_ESR_DAEC (esr, item->u.daec);

      SET_ESR_VALID (esr);
      SET_ESR (reg_index, esr);
    }
}

/* Check for compound interrupts.
   Returns NULL if no interrupt is to be processed.  */
static struct frv_interrupt *
check_for_compound_interrupt (
  SIM_CPU *current_cpu, struct frv_interrupt_queue_element *item
)
{
  struct frv_interrupt *interrupt;

  /* Set the exception status registers for the original interrupt.  */
  set_exception_status_registers (current_cpu, item);
  interrupt = & frv_interrupt_table[item->kind];

  if (! interrupt->precise)
    {
      IADDR vpc = 0;
      int mask = 0;

      vpc = item->vpc;
      mask = (1 << item->kind);

      /* Look for more queued program interrupts which are non-deferred
	 (pending inhibit), imprecise (non-strict) different than an interrupt
	 already found and caused by a different insn.  A bit mask is used
	 to keep track of interrupts which have already been detected.  */
      while (item != frv_interrupt_state.queue)
	{
	  enum frv_interrupt_kind kind;
	  struct frv_interrupt *next_interrupt;
	  --item;
	  kind = item->kind;
	  next_interrupt = & frv_interrupt_table[kind];

	  if (next_interrupt->iclass != FRV_PROGRAM_INTERRUPT)
	    break; /* no program interrupts left.  */

	  if (item->vpc == vpc)
	    continue; /* caused by the same insn.  */

	  vpc = item->vpc;
	  if (! next_interrupt->precise && ! next_interrupt->deferred)
	    {
	      if (! (mask & (1 << kind)))
		{
		  /* Set the exception status registers for the additional
		     interrupt.  */
		  set_exception_status_registers (current_cpu, item);
		  mask |= (1 << kind);
		  interrupt = & frv_interrupt_table[FRV_COMPOUND_EXCEPTION];
		}
	    }
	}
    }

  /* Return with either the original interrupt, a compound_exception,
     or no exception.  */
  return interrupt;
}

/* Handle a program interrupt.  */
void
frv_program_interrupt (
  SIM_CPU *current_cpu, struct frv_interrupt_queue_element *item, IADDR pc
)
{
  struct frv_interrupt *interrupt;

  clear_exception_status_registers (current_cpu);
  /* If two or more non-deferred imprecise (non-strict) interrupts occur
     on two or more insns, then generate a compound_exception.  */
  interrupt = check_for_compound_interrupt (current_cpu, item);
  if (interrupt != NULL)
    {
      frv_program_or_software_interrupt (current_cpu, interrupt, pc);
      frv_clear_interrupt_classes (FRV_SOFTWARE_INTERRUPT,
				   FRV_PROGRAM_INTERRUPT);
    }
}

/* Handle a software interrupt.  */
void
frv_software_interrupt (
  SIM_CPU *current_cpu, struct frv_interrupt_queue_element *item, IADDR pc
)
{
  struct frv_interrupt *interrupt = & frv_interrupt_table[item->kind];
  frv_program_or_software_interrupt (current_cpu, interrupt, pc);
}

/* Handle a program interrupt or a software interrupt in non-operating mode.  */
void
frv_non_operating_interrupt (
  SIM_CPU *current_cpu, enum frv_interrupt_kind kind, IADDR pc
)
{
  SIM_DESC sd = CPU_STATE (current_cpu);
  switch (kind)
    {
    case FRV_INTERRUPT_LEVEL_1:
    case FRV_INTERRUPT_LEVEL_2:
    case FRV_INTERRUPT_LEVEL_3:
    case FRV_INTERRUPT_LEVEL_4:
    case FRV_INTERRUPT_LEVEL_5:
    case FRV_INTERRUPT_LEVEL_6:
    case FRV_INTERRUPT_LEVEL_7:
    case FRV_INTERRUPT_LEVEL_8:
    case FRV_INTERRUPT_LEVEL_9:
    case FRV_INTERRUPT_LEVEL_10:
    case FRV_INTERRUPT_LEVEL_11:
    case FRV_INTERRUPT_LEVEL_12:
    case FRV_INTERRUPT_LEVEL_13:
    case FRV_INTERRUPT_LEVEL_14:
    case FRV_INTERRUPT_LEVEL_15:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: external %d\n", kind + 1);
      break;
    case FRV_TRAP_INSTRUCTION:
      break; /* handle as in operating mode.  */
    case FRV_COMMIT_EXCEPTION:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: commit_exception\n");
      break;
    case FRV_DIVISION_EXCEPTION:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: division_exception\n");
      break;
    case FRV_DATA_STORE_ERROR:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: data_store_error\n");
      break;
    case FRV_DATA_ACCESS_EXCEPTION:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: data_access_exception\n");
      break;
    case FRV_DATA_ACCESS_MMU_MISS:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: data_access_mmu_miss\n");
      break;
    case FRV_DATA_ACCESS_ERROR:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: data_access_error\n");
      break;
    case FRV_MP_EXCEPTION:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: mp_exception\n");
      break;
    case FRV_FP_EXCEPTION:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: fp_exception\n");
      break;
    case FRV_MEM_ADDRESS_NOT_ALIGNED:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: mem_address_not_aligned\n");
      break;
    case FRV_REGISTER_EXCEPTION:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: register_exception\n");
      break;
    case FRV_MP_DISABLED:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: mp_disabled\n");
      break;
    case FRV_FP_DISABLED:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: fp_disabled\n");
      break;
    case FRV_PRIVILEGED_INSTRUCTION:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: privileged_instruction\n");
      break;
    case FRV_ILLEGAL_INSTRUCTION:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: illegal_instruction\n");
      break;
    case FRV_INSTRUCTION_ACCESS_EXCEPTION:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: instruction_access_exception\n");
      break;
    case FRV_INSTRUCTION_ACCESS_MMU_MISS:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: instruction_access_mmu_miss\n");
      break;
    case FRV_INSTRUCTION_ACCESS_ERROR:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: insn_access_error\n");
      break;
    case FRV_COMPOUND_EXCEPTION:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: compound_exception\n");
      break;
    case FRV_BREAK_EXCEPTION:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: break_exception\n");
      break;
    case FRV_RESET:
      sim_engine_abort (sd, current_cpu, pc,
			"interrupt: reset\n");
      break;
    default:
      sim_engine_abort (sd, current_cpu, pc,
			"unhandled interrupt kind: %d\n", kind);
      break;
    }
}

/* Handle a break interrupt.  */
void
frv_break_interrupt (
  SIM_CPU *current_cpu, struct frv_interrupt *interrupt, IADDR current_pc
)
{
  IADDR new_pc;

  /* BPCSR=PC
     BPSR.BS=PSR.S
     BPSR.BET=PSR.ET
     PSR.S=1
     PSR.ET=0
     TBR.TT=0xff
     PC=TBR
  */
  /* Must set PSR.S first to allow access to supervisor-only spr registers.  */
  SET_H_BPSR_BS (GET_H_PSR_S ());
  SET_H_BPSR_BET (GET_H_PSR_ET ());
  SET_H_PSR_S (1);
  SET_H_PSR_ET (0);
  /* Must set PSR.S first to allow access to supervisor-only spr registers.  */
  SET_H_SPR (H_SPR_BPCSR, current_pc);

  /* Set the new PC in the TBR.  */
  SET_H_TBR_TT (interrupt->handler_offset);
  new_pc = GET_H_SPR (H_SPR_TBR);
  SET_H_PC (new_pc);

  CPU_DEBUG_STATE (current_cpu) = 1;
}

/* Handle a program interrupt or a software interrupt.  */
void
frv_program_or_software_interrupt (
  SIM_CPU *current_cpu, struct frv_interrupt *interrupt, IADDR current_pc
)
{
  USI new_pc;
  int original_psr_et;

  /* PCSR=PC
     PSR.PS=PSR.S
     PSR.ET=0
     PSR.S=1
     if PSR.ESR==1
       SR0 through SR3=GR4 through GR7
       TBR.TT=interrupt handler offset
       PC=TBR
  */
  original_psr_et = GET_H_PSR_ET ();

  SET_H_PSR_PS (GET_H_PSR_S ());
  SET_H_PSR_ET (0);
  SET_H_PSR_S (1);

  /* Must set PSR.S first to allow access to supervisor-only spr registers.  */
  /* The PCSR depends on the precision of the interrupt.  */
  if (interrupt->precise)
    SET_H_SPR (H_SPR_PCSR, previous_vliw_pc);
  else
    SET_H_SPR (H_SPR_PCSR, current_pc);

  /* Set the new PC in the TBR.  */
  SET_H_TBR_TT (interrupt->handler_offset);
  new_pc = GET_H_SPR (H_SPR_TBR);
  SET_H_PC (new_pc);

  /* If PSR.ET was not originally set, then enter the stopped state.  */
  if (! original_psr_et)
    {
      SIM_DESC sd = CPU_STATE (current_cpu);
      frv_non_operating_interrupt (current_cpu, interrupt->kind, current_pc);
      sim_engine_halt (sd, current_cpu, NULL, new_pc, sim_stopped, SIM_SIGINT);
    }
}

/* Handle a program interrupt or a software interrupt.  */
void
frv_external_interrupt (
  SIM_CPU *current_cpu, struct frv_interrupt_queue_element *item, IADDR pc
)
{
  USI new_pc;
  struct frv_interrupt *interrupt = & frv_interrupt_table[item->kind];

  /* Don't process the interrupt if PSR.ET is not set or if it is masked.
     Interrupt 15 is processed even if it appears to be masked.  */
  if (! GET_H_PSR_ET ()
      || (interrupt->kind != FRV_INTERRUPT_LEVEL_15
	  && interrupt->kind < GET_H_PSR_PIL ()))
    return; /* Leave it for later.  */

  /* Remove the interrupt from the queue.  */
  --frv_interrupt_state.queue_index;

  /* PCSR=PC
     PSR.PS=PSR.S
     PSR.ET=0
     PSR.S=1
     if PSR.ESR==1
       SR0 through SR3=GR4 through GR7
       TBR.TT=interrupt handler offset
       PC=TBR
  */
  SET_H_PSR_PS (GET_H_PSR_S ());
  SET_H_PSR_ET (0);
  SET_H_PSR_S (1);
  /* Must set PSR.S first to allow access to supervisor-only spr registers.  */
  SET_H_SPR (H_SPR_PCSR, GET_H_PC ());

  /* Set the new PC in the TBR.  */
  SET_H_TBR_TT (interrupt->handler_offset);
  new_pc = GET_H_SPR (H_SPR_TBR);
  SET_H_PC (new_pc);
}

/* Clear interrupts which fall within the range of classes given.  */
void
frv_clear_interrupt_classes (
  enum frv_interrupt_class low_class, enum frv_interrupt_class high_class
)
{
  int i;
  int j;
  int limit = frv_interrupt_state.queue_index;

  /* Find the lowest priority interrupt to be removed.  */
  for (i = 0; i < limit; ++i)
    {
      enum frv_interrupt_kind kind = frv_interrupt_state.queue[i].kind;
      struct frv_interrupt* interrupt = & frv_interrupt_table[kind];
      if (interrupt->iclass >= low_class)
	break;
    }

  /* Find the highest priority interrupt to be removed.  */
  for (j = limit - 1; j >= i; --j)
    {
      enum frv_interrupt_kind kind = frv_interrupt_state.queue[j].kind;
      struct frv_interrupt* interrupt = & frv_interrupt_table[kind];
      if (interrupt->iclass <= high_class)
	break;
    }

  /* Shuffle the remaining high priority interrupts down into the empty space
     left by the deleted interrupts.  */
  if (j >= i)
    {
      for (++j; j < limit; ++j)
	frv_interrupt_state.queue[i++] = frv_interrupt_state.queue[j];
      frv_interrupt_state.queue_index -= (j - i);
    }
}

/* Save data written to memory into the interrupt state so that it can be
   copied to the appropriate EDR register, if necessary, in the event of an
   interrupt.  */
void
frv_save_data_written_for_interrupts (
  SIM_CPU *current_cpu, CGEN_WRITE_QUEUE_ELEMENT *item
)
{
  /* Record the slot containing the insn doing the write in the
     interrupt state.  */
  frv_interrupt_state.slot = CGEN_WRITE_QUEUE_ELEMENT_PIPE (item);

  /* Now record any data written to memory in the interrupt state.  */
  switch (CGEN_WRITE_QUEUE_ELEMENT_KIND (item))
    {
    case CGEN_BI_WRITE:
    case CGEN_QI_WRITE:
    case CGEN_SI_WRITE:
    case CGEN_SF_WRITE:
    case CGEN_PC_WRITE:
    case CGEN_FN_HI_WRITE:
    case CGEN_FN_SI_WRITE:
    case CGEN_FN_SF_WRITE:
    case CGEN_FN_DI_WRITE:
    case CGEN_FN_DF_WRITE:
    case CGEN_FN_XI_WRITE:
    case CGEN_FN_PC_WRITE:
      break; /* Ignore writes to registers.  */
    case CGEN_MEM_QI_WRITE:
      frv_interrupt_state.data_written.length = 1;
      frv_interrupt_state.data_written.words[0]
	= item->kinds.mem_qi_write.value;
      break;
    case CGEN_MEM_HI_WRITE:
      frv_interrupt_state.data_written.length = 1;
      frv_interrupt_state.data_written.words[0]
	= item->kinds.mem_hi_write.value;
      break;
    case CGEN_MEM_SI_WRITE:
      frv_interrupt_state.data_written.length = 1;
      frv_interrupt_state.data_written.words[0]
	= item->kinds.mem_si_write.value;
      break;
    case CGEN_MEM_DI_WRITE:
      frv_interrupt_state.data_written.length = 2;
      frv_interrupt_state.data_written.words[0]
	= item->kinds.mem_di_write.value >> 32;
      frv_interrupt_state.data_written.words[1]
	= item->kinds.mem_di_write.value;
      break;
    case CGEN_MEM_DF_WRITE:
      frv_interrupt_state.data_written.length = 2;
      frv_interrupt_state.data_written.words[0]
	= item->kinds.mem_df_write.value >> 32;
      frv_interrupt_state.data_written.words[1]
	= item->kinds.mem_df_write.value;
      break;
    case CGEN_MEM_XI_WRITE:
      frv_interrupt_state.data_written.length = 4;
      frv_interrupt_state.data_written.words[0]
	= item->kinds.mem_xi_write.value[0];
      frv_interrupt_state.data_written.words[1]
	= item->kinds.mem_xi_write.value[1];
      frv_interrupt_state.data_written.words[2]
	= item->kinds.mem_xi_write.value[2];
      frv_interrupt_state.data_written.words[3]
	= item->kinds.mem_xi_write.value[3];
      break;
    case CGEN_FN_MEM_QI_WRITE:
      frv_interrupt_state.data_written.length = 1;
      frv_interrupt_state.data_written.words[0]
	= item->kinds.fn_mem_qi_write.value;
      break;
    case CGEN_FN_MEM_HI_WRITE:
      frv_interrupt_state.data_written.length = 1;
      frv_interrupt_state.data_written.words[0]
	= item->kinds.fn_mem_hi_write.value;
      break;
    case CGEN_FN_MEM_SI_WRITE:
      frv_interrupt_state.data_written.length = 1;
      frv_interrupt_state.data_written.words[0]
	= item->kinds.fn_mem_si_write.value;
      break;
    case CGEN_FN_MEM_DI_WRITE:
      frv_interrupt_state.data_written.length = 2;
      frv_interrupt_state.data_written.words[0]
	= item->kinds.fn_mem_di_write.value >> 32;
      frv_interrupt_state.data_written.words[1]
	= item->kinds.fn_mem_di_write.value;
      break;
    case CGEN_FN_MEM_DF_WRITE:
      frv_interrupt_state.data_written.length = 2;
      frv_interrupt_state.data_written.words[0]
	= item->kinds.fn_mem_df_write.value >> 32;
      frv_interrupt_state.data_written.words[1]
	= item->kinds.fn_mem_df_write.value;
      break;
    case CGEN_FN_MEM_XI_WRITE:
      frv_interrupt_state.data_written.length = 4;
      frv_interrupt_state.data_written.words[0]
	= item->kinds.fn_mem_xi_write.value[0];
      frv_interrupt_state.data_written.words[1]
	= item->kinds.fn_mem_xi_write.value[1];
      frv_interrupt_state.data_written.words[2]
	= item->kinds.fn_mem_xi_write.value[2];
      frv_interrupt_state.data_written.words[3]
	= item->kinds.fn_mem_xi_write.value[3];
      break;
    default:
      {
	SIM_DESC sd = CPU_STATE (current_cpu);
	IADDR pc = CPU_PC_GET (current_cpu);
	sim_engine_abort (sd, current_cpu, pc,
			  "unknown write kind during save for interrupt\n");
      }
      break;
    }
}
