/* frv trap support
   Copyright (C) 1999-2021 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 "targ-vals.h"
#include "cgen-engine.h"
#include "cgen-par.h"
#include "sim-fpu.h"
#include "sim-signal.h"
#include "sim/callback.h"

#include "bfd.h"
#include "libiberty.h"

#include <stdlib.h>

CGEN_ATTR_VALUE_ENUM_TYPE frv_current_fm_slot;

/* The semantic code invokes this for invalid (unrecognized) instructions.  */

SEM_PC
sim_engine_invalid_insn (SIM_CPU *current_cpu, IADDR cia, SEM_PC vpc)
{
  frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
  return vpc;
}

/* Process an address exception.  */

void
frv_core_signal (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia,
		  unsigned int map, int nr_bytes, address_word addr,
		  transfer_type transfer, sim_core_signals sig)
{
  if (sig == sim_core_unaligned_signal)
    {
      if (STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr400
	  || STATE_ARCHITECTURE (sd)->mach == bfd_mach_fr450)
	frv_queue_data_access_error_interrupt (current_cpu, addr);
      else
	frv_queue_mem_address_not_aligned_interrupt (current_cpu, addr);
    }

  frv_term (sd);
  sim_core_signal (sd, current_cpu, cia, map, nr_bytes, addr, transfer, sig);
}

void
frv_sim_engine_halt_hook (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia)
{
  int i;
  if (current_cpu != NULL)
    CPU_PC_SET (current_cpu, cia);

  /* Invalidate the insn and data caches of all cpus.  */
  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
    {
      current_cpu = STATE_CPU (sd, i);
      frv_cache_invalidate_all (CPU_INSN_CACHE (current_cpu), 0);
      frv_cache_invalidate_all (CPU_DATA_CACHE (current_cpu), 1);
    }
  frv_term (sd);
}

/* Read/write functions for system call interface.  */

static int
syscall_read_mem (host_callback *cb, struct cb_syscall *sc,
		  unsigned long taddr, char *buf, int bytes)
{
  SIM_DESC sd = (SIM_DESC) sc->p1;
  SIM_CPU *cpu = (SIM_CPU *) sc->p2;

  frv_cache_invalidate_all (CPU_DATA_CACHE (cpu), 1);
  return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
}

static int
syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
		   unsigned long taddr, const char *buf, int bytes)
{
  SIM_DESC sd = (SIM_DESC) sc->p1;
  SIM_CPU *cpu = (SIM_CPU *) sc->p2;

  frv_cache_invalidate_all (CPU_INSN_CACHE (cpu), 0);
  frv_cache_invalidate_all (CPU_DATA_CACHE (cpu), 1);
  return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
}

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

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

/* Handle the MTRAP insn.  */
void
frv_mtrap (SIM_CPU *current_cpu)
{
  SIM_DESC sd = CPU_STATE (current_cpu);

  /* Check the status of media exceptions in MSR0.  */
  SI msr = GET_MSR (0);
  if (GET_MSR_AOVF (msr)
      || (GET_MSR_MTT (msr) && STATE_ARCHITECTURE (sd)->mach != bfd_mach_fr550))
    frv_queue_program_interrupt (current_cpu, FRV_MP_EXCEPTION);
}

/* Handle the BREAK insn.  */
void
frv_break (SIM_CPU *current_cpu)
{
  SIM_DESC sd = CPU_STATE (current_cpu);

  if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT)
    {
      /* Invalidate the insn cache because the debugger will presumably
	 replace the breakpoint insn with the real one.  */
      sim_engine_halt (sd, current_cpu, NULL, NULL_CIA, sim_stopped,
		       SIM_SIGTRAP);
    }

  frv_queue_break_interrupt (current_cpu);
}

/* Return from trap.  */
USI
frv_rett (SIM_CPU *current_cpu, PCADDR pc, BI debug_field)
{
  USI new_pc;
  /* if (normal running mode and debug_field==0
       PC=PCSR
       PSR.ET=1
       PSR.S=PSR.PS
     else if (debug running mode and debug_field==1)
       PC=(BPCSR)
       PSR.ET=BPSR.BET
       PSR.S=BPSR.BS
       change to normal running mode
  */
  int psr_s = GET_H_PSR_S ();
  int psr_et = GET_H_PSR_ET ();

  /* Check for exceptions in the priority order listed in the FRV Architecture
     Volume 2.  */
  if (! psr_s)
    {
      /* Halt if PSR.ET is not set.  See chapter 6 of the LSI.  */
      if (! psr_et)
	{
	  SIM_DESC sd = CPU_STATE (current_cpu);
	  sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
	}

      /* privileged_instruction interrupt will have already been queued by
	 frv_detect_insn_access_interrupts.  */
      new_pc = pc + 4;
    }
  else if (psr_et)
    {
      /* Halt if PSR.S is set.  See chapter 6 of the LSI.  */
      if (psr_s)
	{
	  SIM_DESC sd = CPU_STATE (current_cpu);
	  sim_engine_halt (sd, current_cpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
	}

      frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
      new_pc = pc + 4;
    }
  else if (! CPU_DEBUG_STATE (current_cpu) && debug_field == 0)
    {
      USI psr = GET_PSR ();
      /* Return from normal running state.  */
      new_pc = GET_H_SPR (H_SPR_PCSR);
      SET_PSR_ET (psr, 1);
      SET_PSR_S (psr, GET_PSR_PS (psr));
      sim_queue_fn_si_write (current_cpu, frvbf_h_spr_set, H_SPR_PSR, psr);
    }
  else if (CPU_DEBUG_STATE (current_cpu) && debug_field == 1)
    {
      USI psr = GET_PSR ();
      /* Return from debug state.  */
      new_pc = GET_H_SPR (H_SPR_BPCSR);
      SET_PSR_ET (psr, GET_H_BPSR_BET ());
      SET_PSR_S (psr, GET_H_BPSR_BS ());
      sim_queue_fn_si_write (current_cpu, frvbf_h_spr_set, H_SPR_PSR, psr);
      CPU_DEBUG_STATE (current_cpu) = 0;
    }
  else
    new_pc = pc + 4;

  return new_pc;
}

/* Functions for handling non-excepting instruction side effects.  */
static SI next_available_nesr (SIM_CPU *current_cpu, SI current_index)
{
  FRV_REGISTER_CONTROL *control = CPU_REGISTER_CONTROL (current_cpu);
  if (control->spr[H_SPR_NECR].implemented)
    {
      int limit;
      USI necr = GET_NECR ();

      /* See if any NESRs are implemented. First need to check the validity of
	 the NECR.  */
      if (! GET_NECR_VALID (necr))
	return NO_NESR;

      limit = GET_NECR_NEN (necr);
      for (++current_index; current_index < limit; ++current_index)
	{
	  SI nesr = GET_NESR (current_index);
	  if (! GET_NESR_VALID (nesr))
	    return current_index;
	}
    }
  return NO_NESR;
}

static SI next_valid_nesr (SIM_CPU *current_cpu, SI current_index)
{
  FRV_REGISTER_CONTROL *control = CPU_REGISTER_CONTROL (current_cpu);
  if (control->spr[H_SPR_NECR].implemented)
    {
      int limit;
      USI necr = GET_NECR ();

      /* See if any NESRs are implemented. First need to check the validity of
	 the NECR.  */
      if (! GET_NECR_VALID (necr))
	return NO_NESR;

      limit = GET_NECR_NEN (necr);
      for (++current_index; current_index < limit; ++current_index)
	{
	  SI nesr = GET_NESR (current_index);
	  if (GET_NESR_VALID (nesr))
	    return current_index;
	}
    }
  return NO_NESR;
}

BI
frvbf_check_non_excepting_load (
  SIM_CPU *current_cpu, SI base_index, SI disp_index, SI target_index,
  SI immediate_disp, QI data_size, BI is_float
)
{
  BI rc = 1; /* perform the load.  */
  SIM_DESC sd = CPU_STATE (current_cpu);
  int daec = 0;
  int rec  = 0;
  int ec   = 0;
  USI necr;
  int do_elos;
  SI NE_flags[2];
  SI NE_base;
  SI nesr;
  SI ne_index;
  FRV_REGISTER_CONTROL *control;

  SI address = GET_H_GR (base_index);
  if (disp_index >= 0)
    address += GET_H_GR (disp_index);
  else
    address += immediate_disp;

  /* Check for interrupt factors.  */
  switch (data_size)
    {
    case NESR_UQI_SIZE:
    case NESR_QI_SIZE:
      break;
    case NESR_UHI_SIZE:
    case NESR_HI_SIZE:
      if (address & 1)
	ec = 1;
      break;
    case NESR_SI_SIZE:
      if (address & 3)
	ec = 1;
      break;
    case NESR_DI_SIZE:
      if (address & 7)
	ec = 1;
      if (target_index & 1)
	rec = 1;
      break;
    case NESR_XI_SIZE:
      if (address & 0xf)
	ec = 1;
      if (target_index & 3)
	rec = 1;
      break;
    default:
      {
	IADDR pc = GET_H_PC ();
	sim_engine_abort (sd, current_cpu, pc, 
			  "check_non_excepting_load: Incorrect data_size\n");
	break;
      }
    }

  control = CPU_REGISTER_CONTROL (current_cpu);
  if (control->spr[H_SPR_NECR].implemented)
    {
      necr = GET_NECR ();
      do_elos = GET_NECR_VALID (necr) && GET_NECR_ELOS (necr);
    }
  else
    do_elos = 0;

  /* NECR, NESR, NEEAR are only implemented for the full frv machine.  */
  if (do_elos)
    {
      ne_index = next_available_nesr (current_cpu, NO_NESR);
      if (ne_index == NO_NESR)
	{
	  IADDR pc = GET_H_PC ();
	  sim_engine_abort (sd, current_cpu, pc, 
			    "No available NESR register\n");
	}

      /* Fill in the basic fields of the NESR.  */
      nesr = GET_NESR (ne_index);
      SET_NESR_VALID (nesr);
      SET_NESR_EAV (nesr);
      SET_NESR_DRN (nesr, target_index);
      SET_NESR_SIZE (nesr, data_size);
      SET_NESR_NEAN (nesr, ne_index);
      if (is_float)
	SET_NESR_FR (nesr);
      else
	CLEAR_NESR_FR (nesr);

      /* Set the corresponding NEEAR.  */
      SET_NEEAR (ne_index, address);
  
      SET_NESR_DAEC (nesr, 0);
      SET_NESR_REC (nesr, 0);
      SET_NESR_EC (nesr, 0);
    }

  /* Set the NE flag corresponding to the target register if an interrupt
     factor was detected. 
     daec is not checked here yet, but is declared for future reference.  */
  if (is_float)
    NE_base = H_SPR_FNER0;
  else
    NE_base = H_SPR_GNER0;

  GET_NE_FLAGS (NE_flags, NE_base);
  if (rec)
    {
      SET_NE_FLAG (NE_flags, target_index);
      if (do_elos)
	SET_NESR_REC (nesr, NESR_REGISTER_NOT_ALIGNED);
    }

  if (ec)
    {
      SET_NE_FLAG (NE_flags, target_index);
      if (do_elos)
	SET_NESR_EC (nesr, NESR_MEM_ADDRESS_NOT_ALIGNED);
    }

  if (do_elos)
    SET_NESR (ne_index, nesr);

  /* If no interrupt factor was detected then set the NE flag on the
     target register if the NE flag on one of the input registers
     is already set.  */
  if (! rec && ! ec && ! daec)
    {
      BI ne_flag = GET_NE_FLAG (NE_flags, base_index);
      if (disp_index >= 0)
	ne_flag |= GET_NE_FLAG (NE_flags, disp_index);
      if (ne_flag)
	{
	  SET_NE_FLAG (NE_flags, target_index);
	  rc = 0; /* Do not perform the load.  */
	}
      else
	CLEAR_NE_FLAG (NE_flags, target_index);
    }

  SET_NE_FLAGS (NE_base, NE_flags);

  return rc; /* perform the load?  */
}

/* Record state for media exception: media_cr_not_aligned.  */
void
frvbf_media_cr_not_aligned (SIM_CPU *current_cpu)
{
  SIM_DESC sd = CPU_STATE (current_cpu);

  /* On some machines this generates an illegal_instruction interrupt.  */
  switch (STATE_ARCHITECTURE (sd)->mach)
    {
      /* Note: there is a discrepancy between V2.2 of the FR400
	 instruction manual and the various FR4xx LSI specs.  The former
	 claims that unaligned registers cause an mp_exception while the
	 latter say it's an illegal_instruction.  The LSI specs appear
	 to be correct since MTT is fixed at 1.  */
    case bfd_mach_fr400:
    case bfd_mach_fr450:
    case bfd_mach_fr550:
      frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
      break;
    default:
      frv_set_mp_exception_registers (current_cpu, MTT_CR_NOT_ALIGNED, 0);
      break;
    }
}

/* Record state for media exception: media_acc_not_aligned.  */
void
frvbf_media_acc_not_aligned (SIM_CPU *current_cpu)
{
  SIM_DESC sd = CPU_STATE (current_cpu);

  /* On some machines this generates an illegal_instruction interrupt.  */
  switch (STATE_ARCHITECTURE (sd)->mach)
    {
      /* See comment in frvbf_cr_not_aligned().  */
    case bfd_mach_fr400:
    case bfd_mach_fr450:
    case bfd_mach_fr550:
      frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
      break;
    default:
      frv_set_mp_exception_registers (current_cpu, MTT_ACC_NOT_ALIGNED, 0);
      break;
    }
}

/* Record state for media exception: media_register_not_aligned.  */
void
frvbf_media_register_not_aligned (SIM_CPU *current_cpu)
{
  SIM_DESC sd = CPU_STATE (current_cpu);

  /* On some machines this generates an illegal_instruction interrupt.  */
  switch (STATE_ARCHITECTURE (sd)->mach)
    {
      /* See comment in frvbf_cr_not_aligned().  */
    case bfd_mach_fr400:
    case bfd_mach_fr450:
    case bfd_mach_fr550:
      frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
      break;
    default:
      frv_set_mp_exception_registers (current_cpu, MTT_INVALID_FR, 0);
      break;
    }
}

/* Record state for media exception: media_overflow.  */
void
frvbf_media_overflow (SIM_CPU *current_cpu, int sie)
{
  frv_set_mp_exception_registers (current_cpu, MTT_OVERFLOW, sie);
}

/* Queue a division exception.  */
enum frv_dtt
frvbf_division_exception (SIM_CPU *current_cpu, enum frv_dtt dtt,
			  int target_index, int non_excepting)
{
  /* If there was an overflow and it is masked, then record it in
     ISR.AEXC.  */
  USI isr = GET_ISR ();
  if ((dtt & FRV_DTT_OVERFLOW) && GET_ISR_EDE (isr))
    {
      dtt &= ~FRV_DTT_OVERFLOW;
      SET_ISR_AEXC (isr);
      SET_ISR (isr);
    }
  if (dtt != FRV_DTT_NO_EXCEPTION)
    {
      if (non_excepting)
	{
	  /* Non excepting instruction, simply set the NE flag for the target
	     register.  */
	  SI NE_flags[2];
	  GET_NE_FLAGS (NE_flags, H_SPR_GNER0);
	  SET_NE_FLAG (NE_flags, target_index);
	  SET_NE_FLAGS (H_SPR_GNER0, NE_flags);
	}
      else
	frv_queue_division_exception_interrupt (current_cpu, dtt);
    }
  return dtt;
}

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.  */
}

SI
frvbf_check_acc_range (SIM_CPU *current_cpu, SI regno)
{
  /* Only applicable to fr550 */
  SIM_DESC sd = CPU_STATE (current_cpu);
  if (STATE_ARCHITECTURE (sd)->mach != bfd_mach_fr550)
    return 0;

  /* On the fr550, media insns in slots 0 and 2 can only access
     accumulators acc0-acc3. Insns in slots 1 and 3 can only access
     accumulators acc4-acc7 */
  switch (frv_current_fm_slot)
    {
    case UNIT_FM0:
    case UNIT_FM2:
      if (regno <= 3)
	return 1; /* all is ok */
      break;
    case UNIT_FM1:
    case UNIT_FM3:
      if (regno >= 4)
	return 1; /* all is ok */
      break;
    }
  
  /* The specified accumulator is out of range. Queue an illegal_instruction
     interrupt.  */
  frv_queue_program_interrupt (current_cpu, FRV_ILLEGAL_INSTRUCTION);
  return 0;
}

void
frvbf_check_swap_address (SIM_CPU *current_cpu, SI address)
{
  /* Only applicable to fr550 */
  SIM_DESC sd = CPU_STATE (current_cpu);
  if (STATE_ARCHITECTURE (sd)->mach != bfd_mach_fr550)
    return;

  /* Adress must be aligned on a word boundary.  */
  if (address & 0x3)
    frv_queue_data_access_exception_interrupt (current_cpu);
}

static void
clear_nesr_neear (SIM_CPU *current_cpu, SI target_index, BI is_float)
{
  int reg_ix;

  /* Only implemented for full frv.  */
  SIM_DESC sd = CPU_STATE (current_cpu);
  if (STATE_ARCHITECTURE (sd)->mach != bfd_mach_frv)
    return;

  /* Clear the appropriate NESR and NEEAR registers.  */
  for (reg_ix = next_valid_nesr (current_cpu, NO_NESR);
       reg_ix != NO_NESR;
       reg_ix = next_valid_nesr (current_cpu, reg_ix))
    {
      SI nesr;
      /* The register is available, now check if it is active.  */
      nesr = GET_NESR (reg_ix);
      if (GET_NESR_FR (nesr) == is_float)
	{
	  if (target_index < 0 || GET_NESR_DRN (nesr) == target_index)
	    {
	      SET_NESR (reg_ix, 0);
	      SET_NEEAR (reg_ix, 0);
	    }
	}
    }
}

static void
clear_ne_flags (
  SIM_CPU *current_cpu,
  SI target_index,
  int hi_available,
  int lo_available,
  SI NE_base
)
{
  SI NE_flags[2];
  int exception;

  GET_NE_FLAGS (NE_flags, NE_base);
  if (target_index >= 0)
    CLEAR_NE_FLAG (NE_flags, target_index);
  else
    {
      if (lo_available)
	NE_flags[1] = 0;
      if (hi_available)
	NE_flags[0] = 0;
    }
  SET_NE_FLAGS (NE_base, NE_flags);
}

/* Return 1 if the given register is available, 0 otherwise.  TARGET_INDEX==-1
   means to check for any register available.  */
static void
which_registers_available (
  SIM_CPU *current_cpu, int *hi_available, int *lo_available, int is_float
)
{
  if (is_float)
    frv_fr_registers_available (current_cpu, hi_available, lo_available);
  else
    frv_gr_registers_available (current_cpu, hi_available, lo_available);
}

void
frvbf_clear_ne_flags (SIM_CPU *current_cpu, SI target_index, BI is_float)
{
  int hi_available;
  int lo_available;
  int exception;
  SI NE_base;
  USI necr;
  FRV_REGISTER_CONTROL *control;

  /* Check for availability of the target register(s).  */
  which_registers_available (current_cpu, & hi_available, & lo_available,
			     is_float);

  /* Check to make sure that the target register is available.  */
  if (! frv_check_register_access (current_cpu, target_index,
				   hi_available, lo_available))
    return;

  /* Determine whether we're working with GR or FR registers.  */
  if (is_float)
    NE_base = H_SPR_FNER0;
  else
    NE_base = H_SPR_GNER0;

  /* Always clear the appropriate NE flags.  */
  clear_ne_flags (current_cpu, target_index, hi_available, lo_available,
		  NE_base);

  /* Clear the appropriate NESR and NEEAR registers.  */
  control = CPU_REGISTER_CONTROL (current_cpu);
  if (control->spr[H_SPR_NECR].implemented)
    {
      necr = GET_NECR ();
      if (GET_NECR_VALID (necr) && GET_NECR_ELOS (necr))
	clear_nesr_neear (current_cpu, target_index, is_float);
    }
}

void
frvbf_commit (SIM_CPU *current_cpu, SI target_index, BI is_float)
{
  SI NE_base;
  SI NE_flags[2];
  BI NE_flag;
  int exception;
  int hi_available;
  int lo_available;
  USI necr;
  FRV_REGISTER_CONTROL *control;

  /* Check for availability of the target register(s).  */
  which_registers_available (current_cpu, & hi_available, & lo_available,
			     is_float);

  /* Check to make sure that the target register is available.  */
  if (! frv_check_register_access (current_cpu, target_index,
				   hi_available, lo_available))
    return;

  /* Determine whether we're working with GR or FR registers.  */
  if (is_float)
    NE_base = H_SPR_FNER0;
  else
    NE_base = H_SPR_GNER0;

  /* Determine whether a ne exception is pending.  */
  GET_NE_FLAGS (NE_flags, NE_base);
  if (target_index >= 0)
    NE_flag = GET_NE_FLAG (NE_flags, target_index);
  else
    {
      NE_flag = (hi_available && NE_flags[0] != 0)
		|| (lo_available && NE_flags[1] != 0);
    }

  /* Always clear the appropriate NE flags.  */
  clear_ne_flags (current_cpu, target_index, hi_available, lo_available,
		  NE_base);

  control = CPU_REGISTER_CONTROL (current_cpu);
  if (control->spr[H_SPR_NECR].implemented)
    {
      necr = GET_NECR ();
      if (GET_NECR_VALID (necr) && GET_NECR_ELOS (necr) && NE_flag)
	{
	  /* Clear the appropriate NESR and NEEAR registers.  */
	  clear_nesr_neear (current_cpu, target_index, is_float);
	  frv_queue_program_interrupt (current_cpu, FRV_COMMIT_EXCEPTION);
	}
    }
}

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