Exemplo n.º 1
0
/* Perform a hardware reset.  */
void
frv_hardware_reset (SIM_CPU *cpu)
{
  /* GR, FR and CPR registers are undefined at hardware reset.  */
  frv_initialize_spr (cpu);
  /* Reset the RSTR register (in memory).  */
  if (frv_cache_enabled (CPU_DATA_CACHE (cpu)))
    frvbf_mem_set_SI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_HARDWARE_RESET);
  else
    SETMEMSI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_HARDWARE_RESET);
  /* Reset the insn and data caches.  */
  frv_cache_invalidate_all (CPU_INSN_CACHE (cpu), 0/* no flush */);
  frv_cache_invalidate_all (CPU_DATA_CACHE (cpu), 0/* no flush */);
}
Exemplo n.º 2
0
UQI
frvbf_read_mem_UQI (SIM_CPU *current_cpu, IADDR pc, SI address)
{
  USI hsr0 = GET_HSR0 ();
  FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);

  /* Check for access exceptions.  */
  address = check_data_read_address (current_cpu, address, 0);
  address = check_readwrite_address (current_cpu, address, 0);
  
  /* 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) = 1;
      CPU_LOAD_SIGNED (current_cpu) = 0;
      return 0xb7; /* any random value */
    }

  if (GET_HSR0_DCE (hsr0))
    {
      int cycles;
      cycles = frv_cache_read (cache, 0, address);
      if (cycles != 0)
	return CACHE_RETURN_DATA (cache, 0, address, UQI, 1);
    }

  return GETMEMUQI (current_cpu, pc, address);
}
Exemplo n.º 3
0
void
frvbf_mem_set_XI (SIM_CPU *current_cpu, IADDR pc, SI address, SI *value)
{
  int i;
  FRV_CACHE *cache;

  /* Check for access errors.  */
  address = check_write_address (current_cpu, address, 0xf);
  address = check_readwrite_address (current_cpu, address, 0xf);

  /* TODO -- reverse word order as well?  */
  for (i = 0; i < 4; ++i)
    value[i] = H2T_4 (value[i]);

  /* If we need to count cycles, then submit the write request to the cache
     and let it prioritize the request.  Otherwise perform the write now.  */
  cache = CPU_DATA_CACHE (current_cpu);
  if (model_insn)
    {
      int slot = UNIT_I0;
      frv_cache_request_store (cache, address, slot, (char*)value, 16);
    }
  else
    frv_cache_write (cache, address, (char*)value, 16);
}
Exemplo n.º 4
0
void
frvbf_mem_set_DF (SIM_CPU *current_cpu, IADDR pc, SI address, DF value)
{
  FRV_CACHE *cache;

  /* Check for access errors.  */
  address = check_write_address (current_cpu, address, 7);
  address = check_readwrite_address (current_cpu, address, 7);

  /* If we need to count cycles, then submit the write request to the cache
     and let it prioritize the request.  Otherwise perform the write now.  */
  value = H2T_8 (value);
  cache = CPU_DATA_CACHE (current_cpu);
  if (model_insn)
    {
      int slot = UNIT_I0;
      frv_cache_request_store (cache, address, slot,
			       (char *)&value, sizeof (value));
    }
  else
    {
      /* 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, 8))
	    {
	      mem_set_unaligned_DI (current_cpu, pc, address, value); 
	      return;
	    }
	}
      frv_cache_write (cache, address, (char *)&value, sizeof (value));
    }
}
Exemplo n.º 5
0
static void
parse_cache_option (SIM_DESC sd, char *arg, char *cache_name, int is_data_cache)
{
  int i;
  address_word ways = 0, sets = 0, linesize = 0;
  if (arg != NULL)
    {
      char *chp = arg;
      /* parse the arguments */
      chp = parse_size (chp, &ways);
      ways = check_pow2 (ways, "WAYS", cache_name, sd);
      if (*chp == ',')
	{
	  chp = parse_size (chp + 1, &sets);
	  sets = check_pow2 (sets, "SETS", cache_name, sd);
	  if (*chp == ',')
	    {
	      chp = parse_size (chp + 1, &linesize);
	      linesize = check_pow2 (linesize, "LINESIZE", cache_name, sd);
	    }
	}
    }
  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
    {
      SIM_CPU *current_cpu = STATE_CPU (sd, i);
      FRV_CACHE *cache = is_data_cache ? CPU_DATA_CACHE (current_cpu)
	                               : CPU_INSN_CACHE (current_cpu);
      cache->ways = ways;
      cache->sets = sets;
      cache->line_size = linesize;
      frv_cache_init (current_cpu, cache);
    }
}
Exemplo n.º 6
0
/* Write a HI which spans two cache lines */
static void
mem_set_unaligned_HI (SIM_CPU *current_cpu, IADDR pc, SI address, HI value)
{
  FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
  /* value is already in target byte order */
  frv_cache_write (cache, address, (char *)&value, 1);
  frv_cache_write (cache, address + 1, ((char *)&value + 1), 1);
}
Exemplo n.º 7
0
/* Write a DI which spans two cache lines */
static void
mem_set_unaligned_DI (SIM_CPU *current_cpu, IADDR pc, SI address, DI value)
{
  FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
  unsigned hi_len = cache->line_size - (address & (cache->line_size - 1));
  /* value is already in target byte order */
  frv_cache_write (cache, address, (char *)&value, hi_len);
  frv_cache_write (cache, address + hi_len, (char *)&value + hi_len, 8 - hi_len);
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
0
/* Determine whether the given cache is enabled.  */
int
frv_cache_enabled (FRV_CACHE *cache)
{
  SIM_CPU *current_cpu = cache->cpu;
  int hsr0 = GET_HSR0 ();
  if (GET_HSR0_ICE (hsr0) && cache == CPU_INSN_CACHE (current_cpu))
    return 1;
  if (GET_HSR0_DCE (hsr0) && cache == CPU_DATA_CACHE (current_cpu))
    return 1;
  return 0;
}
Exemplo n.º 10
0
/* Perform a software reset.  */
void
frv_software_reset (SIM_CPU *cpu)
{
  /* GR, FR and CPR registers are undefined at software reset.  */
  frv_reset_spr (cpu);
  /* Reset the RSTR register (in memory).  */
  if (frv_cache_enabled (CPU_DATA_CACHE (cpu)))
    frvbf_mem_set_SI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_SOFTWARE_RESET);
  else
    SETMEMSI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_SOFTWARE_RESET);
}
Exemplo n.º 11
0
/* Perform a power on reset.  */
void
frv_power_on_reset (SIM_CPU *cpu)
{
  /* GR, FR and CPR registers are undefined at initialization time.  */
  frv_initialize_spr (cpu);
  /* Initialize the RSTR register (in memory).  */
  if (frv_cache_enabled (CPU_DATA_CACHE (cpu)))
    frvbf_mem_set_SI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_INITIAL_VALUE);
  else
    SETMEMSI (cpu, CPU_PC_GET (cpu), RSTR_ADDRESS, RSTR_INITIAL_VALUE);
}
Exemplo n.º 12
0
void
frv_sim_engine_halt_hook (SIM_DESC sd, SIM_CPU *current_cpu, sim_cia cia)
{
  int i;
  if (current_cpu != NULL)
    CIA_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);
}
Exemplo n.º 13
0
/* Memory writes.  These do the actual writing through the cache.  */
void
frvbf_mem_set_QI (SIM_CPU *current_cpu, IADDR pc, SI address, QI value)
{
  FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);

  /* Check for access errors.  */
  address = check_write_address (current_cpu, address, 0);
  address = check_readwrite_address (current_cpu, address, 0);

  /* If we need to count cycles, then submit the write request to the cache
     and let it prioritize the request.  Otherwise perform the write now.  */
  if (model_insn)
    {
      int slot = UNIT_I0;
      frv_cache_request_store (cache, address, slot, (char *)&value,
			       sizeof (value));
    }
  else
    frv_cache_write (cache, address, (char *)&value, sizeof (value));
}
Exemplo n.º 14
0
UHI
frvbf_read_mem_UHI (SIM_CPU *current_cpu, IADDR pc, SI address)
{
  USI hsr0;
  FRV_CACHE *cache;

  /* Check for access exceptions.  */
  address = check_data_read_address (current_cpu, address, 1);
  address = check_readwrite_address (current_cpu, address, 1);
  
  /* If we need to count cycles, then the cache operation will be
     initiated from the model profiling functions.
     See frvbf_model_....  */
  hsr0 = GET_HSR0 ();
  cache = CPU_DATA_CACHE (current_cpu);
  if (model_insn)
    {
      CPU_LOAD_ADDRESS (current_cpu) = address;
      CPU_LOAD_LENGTH (current_cpu) = 2;
      CPU_LOAD_SIGNED (current_cpu) = 0;
      return 0xb711; /* 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, 2))
	    return read_mem_unaligned_HI (current_cpu, pc, address); 
	}
      cycles = frv_cache_read (cache, 0, address);
      if (cycles != 0)
	return CACHE_RETURN_DATA (cache, 0, address, UHI, 2);
    }

  return GETMEMUHI (current_cpu, pc, address);
}
/* 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 */
}
Exemplo n.º 16
0
/* Read a SI which spans two cache lines */
static SI
read_mem_unaligned_SI (SIM_CPU *current_cpu, IADDR pc, SI address)
{
  FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
  unsigned hi_len = cache->line_size - (address & (cache->line_size - 1));
  char valarray[4];
  SI SIvalue;
  HI HIvalue;

  switch (hi_len)
    {
    case 1:
      valarray[0] = frvbf_read_mem_QI (current_cpu, pc, address);
      SIvalue = frvbf_read_mem_SI (current_cpu, pc, address + 1);
      SIvalue = H2T_4 (SIvalue);
      memcpy (valarray + 1, (char*)&SIvalue, 3);
      break;
    case 2:
      HIvalue = frvbf_read_mem_HI (current_cpu, pc, address);
      HIvalue = H2T_2 (HIvalue);
      memcpy (valarray, (char*)&HIvalue, 2);
      HIvalue = frvbf_read_mem_HI (current_cpu, pc, address + 2);
      HIvalue = H2T_2 (HIvalue);
      memcpy (valarray + 2, (char*)&HIvalue, 2);
      break;
    case 3:
      SIvalue = frvbf_read_mem_SI (current_cpu, pc, address - 1);
      SIvalue = H2T_4 (SIvalue);
      memcpy (valarray, (char*)&SIvalue, 3);
      valarray[3] = frvbf_read_mem_QI (current_cpu, pc, address + 3);
      break;
    default:
      abort (); /* can't happen */
    }
  return T2H_4 (*(SI*)valarray);
}
Exemplo n.º 17
0
/* Read a SI which spans two cache lines */
static DI
read_mem_unaligned_DI (SIM_CPU *current_cpu, IADDR pc, SI address)
{
  FRV_CACHE *cache = CPU_DATA_CACHE (current_cpu);
  unsigned hi_len = cache->line_size - (address & (cache->line_size - 1));
  DI value, value1;

  switch (hi_len)
    {
    case 1:
      value = frvbf_read_mem_QI (current_cpu, pc, address);
      value <<= 56;
      value1 = frvbf_read_mem_DI (current_cpu, pc, address + 1);
      value1 = H2T_8 (value1);
      value |= value1 & ((DI)0x00ffffff << 32);
      value |= value1 & 0xffffffffu;
      break;
    case 2:
      value = frvbf_read_mem_HI (current_cpu, pc, address);
      value = H2T_2 (value);
      value <<= 48;
      value1 = frvbf_read_mem_DI (current_cpu, pc, address + 2);
      value1 = H2T_8 (value1);
      value |= value1 & ((DI)0x0000ffff << 32);
      value |= value1 & 0xffffffffu;
      break;
    case 3:
      value = frvbf_read_mem_SI (current_cpu, pc, address - 1);
      value = H2T_4 (value);
      value <<= 40;
      value1 = frvbf_read_mem_DI (current_cpu, pc, address + 3);
      value1 = H2T_8 (value1);
      value |= value1 & ((DI)0x000000ff << 32);
      value |= value1 & 0xffffffffu;
      break;
    case 4:
      value = frvbf_read_mem_SI (current_cpu, pc, address);
      value = H2T_4 (value);
      value <<= 32;
      value1 = frvbf_read_mem_SI (current_cpu, pc, address + 4);
      value1 = H2T_4 (value1);
      value |= value1 & 0xffffffffu;
      break;
    case 5:
      value = frvbf_read_mem_DI (current_cpu, pc, address - 3);
      value = H2T_8 (value);
      value <<= 24;
      value1 = frvbf_read_mem_SI (current_cpu, pc, address + 5);
      value1 = H2T_4 (value1);
      value |= value1 & 0x00ffffff;
      break;
    case 6:
      value = frvbf_read_mem_DI (current_cpu, pc, address - 2);
      value = H2T_8 (value);
      value <<= 16;
      value1 = frvbf_read_mem_HI (current_cpu, pc, address + 6);
      value1 = H2T_2 (value1);
      value |= value1 & 0x0000ffff;
      break;
    case 7:
      value = frvbf_read_mem_DI (current_cpu, pc, address - 1);
      value = H2T_8 (value);
      value <<= 8;
      value1 = frvbf_read_mem_QI (current_cpu, pc, address + 7);
      value |= value1 & 0x000000ff;
      break;
    default:
      abort (); /* can't happen */
    }
  return T2H_8 (value);
}
Exemplo n.º 18
0
static SIM_RC
frv_option_handler (SIM_DESC sd, sim_cpu *current_cpu, int opt,
		    char *arg, int is_command)
{
  switch (opt)
    {
    case 'p' :
      if (! WITH_PROFILE)
	sim_io_eprintf (sd, "Profiling not compiled in, `-p' ignored\n");
      else
	{
	  unsigned mask = PROFILE_USEFUL_MASK;
	  if (WITH_PROFILE_CACHE_P)
	    mask |= (1 << PROFILE_CACHE_IDX);
	  if (WITH_PROFILE_PARALLEL_P)
	    mask |= (1 << PROFILE_PARALLEL_IDX);
	  return set_profile_option_mask (sd, "profile", mask, arg);
	}
      break;

    case OPTION_FRV_DATA_CACHE:
      parse_cache_option (sd, arg, "data_cache", 1/*is_data_cache*/);
      return SIM_RC_OK;

    case OPTION_FRV_INSN_CACHE:
      parse_cache_option (sd, arg, "insn_cache", 0/*is_data_cache*/);
      return SIM_RC_OK;

    case OPTION_FRV_PROFILE_CACHE:
      if (WITH_PROFILE_CACHE_P)
	return sim_profile_set_option (sd, "-cache", PROFILE_CACHE_IDX, arg);
      else
	sim_io_eprintf (sd, "Cache profiling not compiled in, `--profile-cache' ignored\n");
      break;

    case OPTION_FRV_PROFILE_PARALLEL:
      if (WITH_PROFILE_PARALLEL_P)
	{
	  unsigned mask
	    = (1 << PROFILE_MODEL_IDX) | (1 << PROFILE_PARALLEL_IDX);
	  return set_profile_option_mask (sd, "-parallel", mask, arg);
	}
      else
	sim_io_eprintf (sd, "Parallel profiling not compiled in, `--profile-parallel' ignored\n");
      break;

    case OPTION_FRV_TIMER:
      {
	char *chp = arg;
	address_word cycles, interrupt;
	chp = parse_size (chp, &cycles);
	if (chp == arg)
	  {
	    sim_io_eprintf (sd, "Cycle count required for --timer\n");
	    return SIM_RC_FAIL;
	  }
	if (*chp != ',')
	  {
	    sim_io_eprintf (sd, "Interrupt number required for --timer\n");
	    return SIM_RC_FAIL;
	  }
	chp = parse_size (chp + 1, &interrupt);
	if (interrupt < 1 || interrupt > 15)
	  {
	    sim_io_eprintf (sd, "Interrupt number for --timer must be greater than 0 and less that 16\n");
	    return SIM_RC_FAIL;
	  }
	frv_interrupt_state.timer.enabled = 1;
	frv_interrupt_state.timer.value = cycles;
	frv_interrupt_state.timer.current = 0;
	frv_interrupt_state.timer.interrupt =
	  FRV_INTERRUPT_LEVEL_1 + interrupt - 1;
      }
      return SIM_RC_OK;

    case OPTION_FRV_MEMORY_LATENCY:
      {
	int i;
	char *chp = arg;
	address_word cycles;
	chp = parse_size (chp, &cycles);
	if (chp == arg)
	  {
	    sim_io_eprintf (sd, "Cycle count required for --memory-latency\n");
	    return SIM_RC_FAIL;
	  }
	for (i = 0; i < MAX_NR_PROCESSORS; ++i)
	  {
	    SIM_CPU *current_cpu = STATE_CPU (sd, i);
	    FRV_CACHE *insn_cache = CPU_INSN_CACHE (current_cpu);
	    FRV_CACHE *data_cache = CPU_DATA_CACHE (current_cpu);
	    insn_cache->memory_latency = cycles;
	    data_cache->memory_latency = cycles;
	  }
      }
      return SIM_RC_OK;

    default:
      sim_io_eprintf (sd, "Unknown FRV option %d\n", opt);
      return SIM_RC_FAIL;

    }

  return SIM_RC_FAIL;
}
Exemplo n.º 19
0
/* Initialize the frv simulator.  */
void
frv_initialize (SIM_CPU *current_cpu, SIM_DESC sd)
{
  FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu);
  PROFILE_DATA *p = CPU_PROFILE_DATA (current_cpu);
  FRV_CACHE *insn_cache = CPU_INSN_CACHE (current_cpu);
  FRV_CACHE *data_cache = CPU_DATA_CACHE (current_cpu);
  int insn_cache_enabled = CACHE_INITIALIZED (insn_cache);
  int data_cache_enabled = CACHE_INITIALIZED (data_cache);
  USI hsr0;

  /* Initialize the register control information first since some of the
     register values are used in further configuration.  */
  frv_register_control_init (current_cpu);

  /* We need to ensure that the caches are initialized even if they are not
     initially enabled (via commandline) because they can be enabled by
     software.  */
  if (! insn_cache_enabled)
    frv_cache_init (current_cpu, CPU_INSN_CACHE (current_cpu));
  if (! data_cache_enabled)
    frv_cache_init (current_cpu, CPU_DATA_CACHE (current_cpu));

  /* Set the default cpu frequency if it has not been set on the command
     line.  */
  if (PROFILE_CPU_FREQ (p) == 0)
    PROFILE_CPU_FREQ (p) = 266000000; /* 266MHz */

  /* Allocate one cache line of memory containing the address of the reset
     register Use the largest of the insn cache line size and the data cache
     line size.  */
  {
    int addr = RSTR_ADDRESS;
    void *aligned_buffer;
    int bytes;

    if (CPU_INSN_CACHE (current_cpu)->line_size
	> CPU_DATA_CACHE (current_cpu)->line_size)
      bytes = CPU_INSN_CACHE (current_cpu)->line_size;
    else
      bytes = CPU_DATA_CACHE (current_cpu)->line_size;

    /* 'bytes' is a power of 2. Calculate the starting address of the
       cache line.  */
    addr &= ~(bytes - 1);
    aligned_buffer = zalloc (bytes); /* clear */
    sim_core_attach (sd, NULL, 0, access_read_write, 0, addr, bytes,
		     0, NULL, aligned_buffer);
  }

  PROFILE_INFO_CPU_CALLBACK(p) = frv_profile_info;
  ps->insn_fetch_address = -1;
  ps->branch_address = -1;

  cgen_init_accurate_fpu (current_cpu, CGEN_CPU_FPU (current_cpu),
			  frvbf_fpu_error);

  /* Now perform power-on reset.  */
  frv_power_on_reset (current_cpu);

  /* Make sure that HSR0.ICE and HSR0.DCE are set properly.  */
  hsr0 = GET_HSR0 ();
  if (insn_cache_enabled)
    SET_HSR0_ICE (hsr0);
  else
    CLEAR_HSR0_ICE (hsr0);
  if (data_cache_enabled)
    SET_HSR0_DCE (hsr0);
  else
    CLEAR_HSR0_DCE (hsr0);
  SET_HSR0 (hsr0);
}
Exemplo n.º 20
0
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.  */
}