# Simulator main loop for frv. -*- C -*-
# Copyright (C) 1998-2025 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/>.

# Syntax:
# /bin/sh mainloop.in command
#
# Command is one of:
#
# init
# support
# extract-{simple,scache,pbb}
# {full,fast}-exec-{simple,scache,pbb}
#
# A target need only provide a "full" version of one of simple,scache,pbb.
# If the target wants it can also provide a fast version of same.
# It can't provide more than this.

# ??? After a few more ports are done, revisit.
# Will eventually need to machine generate a lot of this.

case "x$1" in

xsupport)

cat <<EOF
#line $LINENO "$0"

static INLINE const IDESC *
extract (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn, ARGBUF *abuf,
         int fast_p)
{
  const IDESC *id = @cpu@_decode (current_cpu, pc, insn, insn, abuf);
  @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
  if (! fast_p)
    {
      int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
      int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
      @cpu@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);
    }
  return id;
}

static INLINE SEM_PC
execute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p)
{
  SEM_PC vpc;

  /* Force gr0 to zero before every insn.  */
  @cpu@_h_gr_set (current_cpu, 0, 0);

  if (fast_p)
    {
      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);
    }
  else
    {
      ARGBUF *abuf = &sc->argbuf;
      const IDESC *idesc = abuf->idesc;
#if WITH_SCACHE_PBB
      int virtual_p = CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_VIRTUAL);
#else
      int virtual_p = 0;
#endif

      if (! virtual_p)
	{
	  /* FIXME: call x-before */
	  if (ARGBUF_PROFILE_P (abuf))
	    PROFILE_COUNT_INSN (current_cpu, abuf->addr, idesc->num);
	  /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}.  */
	  if (FRV_COUNT_CYCLES (current_cpu, ARGBUF_PROFILE_P (abuf)))
	    {
	      @cpu@_model_insn_before (current_cpu, sc->first_insn_p);
	      model_insn = FRV_INSN_MODEL_PASS_1;
	      if (idesc->timing->model_fn != NULL)
		(*idesc->timing->model_fn) (current_cpu, sc);
	    }
	  else
	    model_insn = FRV_INSN_NO_MODELING;
	  CGEN_TRACE_INSN_INIT (current_cpu, abuf, 1);
	  CGEN_TRACE_INSN (current_cpu, idesc->idata,
		      (const struct argbuf *) abuf, abuf->addr);
	}
#if WITH_SCACHE
      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc);
#else
      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, abuf);
#endif
      if (! virtual_p)
	{
	  /* FIXME: call x-after */
	  if (FRV_COUNT_CYCLES (current_cpu, ARGBUF_PROFILE_P (abuf)))
	    {
	      int cycles;
	      if (idesc->timing->model_fn != NULL)
		{
		  model_insn = FRV_INSN_MODEL_PASS_2;
		  cycles = (*idesc->timing->model_fn) (current_cpu, sc);
		}
	      else
		cycles = 1;
	      @cpu@_model_insn_after (current_cpu, sc->last_insn_p, cycles);
	    }
	  CGEN_TRACE_INSN_FINI (current_cpu, abuf, 1);
	}
    }

  return vpc;
}

static void
@cpu@_parallel_write_init (SIM_CPU *current_cpu)
{
  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (current_cpu);
  CGEN_WRITE_QUEUE_CLEAR (q);
  previous_vliw_pc = CPU_PC_GET(current_cpu);
  frv_interrupt_state.f_ne_flags[0] = 0;
  frv_interrupt_state.f_ne_flags[1] = 0;
  frv_interrupt_state.imprecise_interrupt = NULL;
}

static void
@cpu@_parallel_write_queued (SIM_CPU *current_cpu)
{
  int i;

  CGEN_WRITE_QUEUE *q = CPU_WRITE_QUEUE (current_cpu);

  /* Loop over the queued writes, executing them. Set the pc to the address
     of the insn which queued each write for the proper context in case an
     interrupt is caused. Restore the proper pc after the writes are
     completed.  */
  IADDR save_pc = CPU_PC_GET (current_cpu);
  IADDR new_pc  = save_pc;
  int branch_taken = 0;
  int limit = CGEN_WRITE_QUEUE_INDEX (q);
  frv_interrupt_state.data_written.length = 0;

  for (i = 0; i < limit; ++i)
    {
      CGEN_WRITE_QUEUE_ELEMENT *item = CGEN_WRITE_QUEUE_ELEMENT (q, i);

      /* If an imprecise interrupt was generated, then, check whether the
	 result should still be written.  */
      if (frv_interrupt_state.imprecise_interrupt != NULL)
	{
	  /* Only check writes by the insn causing the exception.  */
	  if (CGEN_WRITE_QUEUE_ELEMENT_IADDR (item)
	      == frv_interrupt_state.imprecise_interrupt->vpc)
	    {
	      /* Execute writes of floating point operations resulting in
		 overflow, underflow or inexact.  */
	      if (frv_interrupt_state.imprecise_interrupt->kind
		  == FRV_FP_EXCEPTION)
		{
		  if ((frv_interrupt_state.imprecise_interrupt
		       ->u.fp_info.fsr_mask
		       & ~(FSR_INEXACT | FSR_OVERFLOW | FSR_UNDERFLOW)))
		    continue; /* Don't execute */
		}
	      /* Execute writes marked as 'forced'.  */
	      else if (! (CGEN_WRITE_QUEUE_ELEMENT_FLAGS (item)
			  & FRV_WRITE_QUEUE_FORCE_WRITE))
		continue; /* Don't execute */
	    }
	}

      /* Only execute the first branch on the queue.  */
      if (CGEN_WRITE_QUEUE_ELEMENT_KIND (item) == CGEN_PC_WRITE
          || CGEN_WRITE_QUEUE_ELEMENT_KIND (item) == CGEN_FN_PC_WRITE)
	{
	  if (branch_taken)
	    continue;
	  branch_taken = 1;
	  if (CGEN_WRITE_QUEUE_ELEMENT_KIND (item) == CGEN_PC_WRITE)
	    new_pc = item->kinds.pc_write.value;
          else
	    new_pc = item->kinds.fn_pc_write.value;
	}

      CPU_PC_SET (current_cpu, CGEN_WRITE_QUEUE_ELEMENT_IADDR (item));
      frv_save_data_written_for_interrupts (current_cpu, item);
      cgen_write_queue_element_execute (current_cpu, item);
    }

  /* Update the LR with the address of the next insn if the flag is set.
     This flag gets set in frvbf_set_write_next_vliw_to_LR by the JMPL,
     JMPIL and CALL insns.  */
  if (frvbf_write_next_vliw_addr_to_LR)
    {
      frvbf_h_spr_set_handler (current_cpu, H_SPR_LR, save_pc);
      frvbf_write_next_vliw_addr_to_LR = 0;
    }

  CPU_PC_SET (current_cpu, new_pc);
  CGEN_WRITE_QUEUE_CLEAR (q);
}

void
@cpu@_perform_writeback (SIM_CPU *current_cpu)
{
  @cpu@_parallel_write_queued (current_cpu);
}

static unsigned cache_reqno = 0x80000000; /* Start value is for debugging.  */

#if 0 /* experimental */
/* FR400 has single prefetch.  */
static void
fr400_simulate_insn_prefetch (SIM_CPU *current_cpu, IADDR vpc)
{
  int cur_ix;
  FRV_CACHE *cache;

/* The cpu receives 8 bytes worth of insn data for each fetch aligned
   on 8 byte boundary.  */
#define FR400_FETCH_SIZE 8

  cur_ix = LS;
  vpc &= ~(FR400_FETCH_SIZE - 1);
  cache = CPU_INSN_CACHE (current_cpu);

  /* Request a load of the current address buffer, if necessary.  */
  if (frv_insn_fetch_buffer[cur_ix].address != vpc)
    {
      frv_insn_fetch_buffer[cur_ix].address = vpc;
      frv_insn_fetch_buffer[cur_ix].reqno = cache_reqno++;
      if (FRV_COUNT_CYCLES (current_cpu, 1))
	frv_cache_request_load (cache, frv_insn_fetch_buffer[cur_ix].reqno,
				frv_insn_fetch_buffer[cur_ix].address,
				UNIT_I0 + cur_ix);
    }

  /* Wait for the current address buffer to be loaded, if necessary.  */
  if (FRV_COUNT_CYCLES (current_cpu, 1))
    {
      FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu);
      int wait;

      /* Account for any branch penalty.  */
      if (ps->branch_penalty > 0 && ! ps->past_first_p)
	{
	  frv_model_advance_cycles (current_cpu, ps->branch_penalty);
	  frv_model_trace_wait_cycles (current_cpu, ps->branch_penalty,
				       "Branch penalty:");
	  ps->branch_penalty = 0;
	}

      /* Account for insn fetch latency.  */
      wait = 0;
      while (frv_insn_fetch_buffer[cur_ix].reqno != NO_REQNO)
	{
	  frv_model_advance_cycles (current_cpu, 1);
	  ++wait;
	}
      frv_model_trace_wait_cycles (current_cpu, wait, "Insn fetch:");
      return;
    }

  /* Otherwise just load the insns directly from the cache.
   */
  if (frv_insn_fetch_buffer[cur_ix].reqno != NO_REQNO)
    {
      frv_cache_read (cache, cur_ix, vpc);
      frv_insn_fetch_buffer[cur_ix].reqno = NO_REQNO;
    }
}
#endif /* experimental */

/* FR500 has dual prefetch.  */
static void
simulate_dual_insn_prefetch (SIM_CPU *current_cpu, IADDR vpc, int fetch_size)
{
  int i;
  int cur_ix, pre_ix;
  SI pre_address;
  FRV_CACHE *cache;

  /* See if the pc is within the addresses specified by either of the
     fetch buffers.  If so, that will be the current buffer. Otherwise,
     arbitrarily select the LD buffer as the current one since it gets
     priority in the case of interfering load requests.  */
  cur_ix = LD;
  vpc &= ~(fetch_size - 1);
  for (i = LS; i < FRV_CACHE_PIPELINES; ++i)
    {
      if (frv_insn_fetch_buffer[i].address == vpc)
	{
	  cur_ix = i;
	  break;
	}
    }
  cache = CPU_INSN_CACHE (current_cpu);

  /* Request a load of the current address buffer, if necessary.  */
  if (frv_insn_fetch_buffer[cur_ix].address != vpc)
    {
      frv_insn_fetch_buffer[cur_ix].address = vpc;
      frv_insn_fetch_buffer[cur_ix].reqno = cache_reqno++;
      if (FRV_COUNT_CYCLES (current_cpu, 1))
	frv_cache_request_load (cache, frv_insn_fetch_buffer[cur_ix].reqno,
				frv_insn_fetch_buffer[cur_ix].address,
				UNIT_I0 + cur_ix);
    }

  /* If the prefetch buffer does not represent the next sequential address, then
     request a load of the next sequential address.  */
  pre_ix = (cur_ix + 1) % FRV_CACHE_PIPELINES;
  pre_address = vpc + fetch_size;
  if (frv_insn_fetch_buffer[pre_ix].address != pre_address)
    {
      frv_insn_fetch_buffer[pre_ix].address = pre_address;
      frv_insn_fetch_buffer[pre_ix].reqno = cache_reqno++;
      if (FRV_COUNT_CYCLES (current_cpu, 1))
	frv_cache_request_load (cache, frv_insn_fetch_buffer[pre_ix].reqno,
				frv_insn_fetch_buffer[pre_ix].address,
				UNIT_I0 + pre_ix);
    }

  /* If counting cycles, account for any branch penalty and/or insn fetch
     latency here.  */
  if (FRV_COUNT_CYCLES (current_cpu, 1))
    {
      FRV_PROFILE_STATE *ps = CPU_PROFILE_STATE (current_cpu);
      int wait;

      /* Account for any branch penalty.  */
      if (ps->branch_penalty > 0 && ! ps->past_first_p)
	{
	  frv_model_advance_cycles (current_cpu, ps->branch_penalty);
	  frv_model_trace_wait_cycles (current_cpu, ps->branch_penalty,
				       "Branch penalty:");
	  ps->branch_penalty = 0;
	}

      /* Account for insn fetch latency.  */
      wait = 0;
      while (frv_insn_fetch_buffer[cur_ix].reqno != NO_REQNO)
	{
	  frv_model_advance_cycles (current_cpu, 1);
	  ++wait;
	}
      frv_model_trace_wait_cycles (current_cpu, wait, "Insn fetch:");
      return;
    }

  /* Otherwise just load the insns directly from the cache.
   */
  if (frv_insn_fetch_buffer[cur_ix].reqno != NO_REQNO)
    {
      frv_cache_read (cache, cur_ix, vpc);
      frv_insn_fetch_buffer[cur_ix].reqno = NO_REQNO;
    }
  if (frv_insn_fetch_buffer[pre_ix].reqno != NO_REQNO)
    {
      frv_cache_read (cache, pre_ix, pre_address);
      frv_insn_fetch_buffer[pre_ix].reqno = NO_REQNO;
    }
}

static void
@cpu@_simulate_insn_prefetch (SIM_CPU *current_cpu, IADDR vpc)
{
  SI hsr0;
  SIM_DESC sd;

  /* Nothing to do if not counting cycles and the cache is not enabled.  */
  hsr0 = GET_HSR0 ();
  if (! GET_HSR0_ICE (hsr0) && ! FRV_COUNT_CYCLES (current_cpu, 1))
    return;

  /* Different machines handle prefetch defferently.  */
  sd = CPU_STATE (current_cpu);
  switch (STATE_ARCHITECTURE (sd)->mach)
    {
    case bfd_mach_fr400:
    case bfd_mach_fr450:
      simulate_dual_insn_prefetch (current_cpu, vpc, 8);
      break;
    case bfd_mach_frvtomcat:
    case bfd_mach_fr500:
    case bfd_mach_fr550:
    case bfd_mach_frv:
      simulate_dual_insn_prefetch (current_cpu, vpc, 16);
      break;
    default:
      break;
    }
}

int frv_save_profile_model_p;
EOF

;;

xinit)

cat <<EOF
#line $LINENO "$0"
/*xxxinit*/
  /* If the timer is enabled, then we will enable model profiling during
     execution.  This is because the timer needs accurate cycles counts to
     work properly.  Save the original setting of model profiling.  */
  if (frv_interrupt_state.timer.enabled)
    frv_save_profile_model_p = PROFILE_MODEL_P (current_cpu);
EOF

;;

xextract-simple | xextract-scache)

# Inputs:  current_cpu, vpc, sc, FAST_P
# Outputs: sc filled in
# SET_LAST_INSN_P(last_p) called to indicate whether insn is last one

cat <<EOF
#line $LINENO "$0"
{
  CGEN_INSN_INT insn = frvbf_read_imem_USI (current_cpu, vpc);
  extract (current_cpu, vpc, insn, SEM_ARGBUF (sc), FAST_P);
  SET_LAST_INSN_P ((insn & 0x80000000) != 0);
}
EOF

;;

xfull-exec-* | xfast-exec-*)

# Inputs: current_cpu, vpc, FAST_P
# Outputs:
#   vpc contains the address of the next insn to execute
#   pc of current_cpu must be up to date (=vpc) upon exit
#   CPU_INSN_COUNT (current_cpu) must be updated by number of insns executed
#
# Unlike the non-parallel case, this version is responsible for doing the
# scache lookup.

cat <<EOF
#line $LINENO "$0"
{
  FRV_VLIW *vliw;
  int first_insn_p = 1;
  int last_insn_p = 0;
  int ninsns;
  CGEN_ATTR_VALUE_ENUM_TYPE slot;

  /* If the timer is enabled, then enable model profiling.  This is because
     the timer needs accurate cycles counts to work properly.  */
  if (frv_interrupt_state.timer.enabled && ! frv_save_profile_model_p)
    sim_profile_set_option (current_state, "-model", PROFILE_MODEL_IDX, "1");

  /* Init parallel-write queue and vliw.  */
  @cpu@_parallel_write_init (current_cpu);
  vliw = CPU_VLIW (current_cpu);
  frv_vliw_reset (vliw, STATE_ARCHITECTURE (CPU_STATE (current_cpu))->mach,
                  CPU_ELF_FLAGS (current_cpu));
  frv_current_fm_slot = UNIT_NIL;

  for (ninsns = 0; ! last_insn_p && ninsns < FRV_VLIW_SIZE; ++ninsns)
    {
      SCACHE *sc;
      const CGEN_INSN *insn;
      int error;
      /* Go through the motions of finding the insns in the cache.  */
      @cpu@_simulate_insn_prefetch (current_cpu, vpc);

      sc = @cpu@_scache_lookup (current_cpu, vpc, scache, hash_mask, FAST_P);
      sc->first_insn_p = first_insn_p;
      last_insn_p = sc->last_insn_p;

      /* Add the insn to the vliw and set up the interrupt state.  */
      insn = sc->argbuf.idesc->idata;
      error = frv_vliw_add_insn (vliw, insn);
      if (! error)
        frv_vliw_setup_insn (current_cpu, insn);
      frv_detect_insn_access_interrupts (current_cpu, sc);
      slot = (*vliw->current_vliw)[vliw->next_slot - 1];
      if (slot >= UNIT_FM0 && slot <= UNIT_FM3)
        frv_current_fm_slot = slot;

      vpc = execute (current_cpu, sc, FAST_P);

      SET_H_PC (vpc); /* needed for interrupt handling */
      first_insn_p = 0;
    }

  /* If the timer is enabled, and model profiling was not originally enabled,
     then turn it off again.  This is the only place we can currently gain
     control to do this.  */
  if (frv_interrupt_state.timer.enabled && ! frv_save_profile_model_p)
    sim_profile_set_option (current_state, "-model", PROFILE_MODEL_IDX, "0");

  /* Check for interrupts.  Also handles writeback if necessary.  */
  frv_process_interrupts (current_cpu);

  CPU_INSN_COUNT (current_cpu) += ninsns;
}
EOF

;;

*)
  echo "Invalid argument to mainloop.in: $1" >&2
  exit 1
  ;;

esac
