# Simulator main loop for CRIS. -*- C -*-
# Copyright (C) 2004-2021 Free Software Foundation, Inc.
# Contributed by Axis Communications.
#
# 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/>.

# Based on the fr30 file.

# 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, however for illustration's sake the CRIS
# port provides examples of all.

# ??? 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
#include <stdlib.h>

/* It seems we don't have a templated header file corresponding to
   cris-tmpl.c, so we have to get out declarations the hackish way.  */
extern void @cpu@_specific_init (SIM_CPU *current_cpu);

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,
#if CGEN_INT_INSN_P
				  insn,
#endif
				  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;

  if (fast_p)
    {
#if ! WITH_SEM_SWITCH_FAST
#if WITH_SCACHE
      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);
#else
      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, &sc->argbuf);
#endif
#else
      abort ();
#endif /* WITH_SEM_SWITCH_FAST */
    }
  else
    {
#if ! WITH_SEM_SWITCH_FULL
      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 (PROFILE_MODEL_P (current_cpu)
	      && ARGBUF_PROFILE_P (abuf))
	    @cpu@_model_insn_before (current_cpu, 1 /*first_p*/);
	  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 (PROFILE_MODEL_P (current_cpu)
	      && ARGBUF_PROFILE_P (abuf))
	    {
	      int cycles;

	      cycles = (*idesc->timing->model_fn) (current_cpu, sc);
	      @cpu@_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
	    }
	  CGEN_TRACE_INSN_FINI (current_cpu, abuf, 1);
	}
#else
      abort ();
#endif /* WITH_SEM_SWITCH_FULL */
    }

  return vpc;
}

EOF

;;

xinit)

cat <<EOF
  /* This seemed the only sane location to emit a call to a
     model-specific init function.  It may not work for all simulator
     types.  FIXME: Introduce a model-init hook.  */

  /* We use the same condition as the code that's expected to follow, so
     GCC can consolidate the code with only one conditional.  */
  if (! CPU_IDESC_SEM_INIT_P (current_cpu))
    @cpu@_specific_init (current_cpu);
EOF

;;

xextract-simple | xextract-scache)

# Inputs:  current_cpu, vpc, sc, FAST_P
# Outputs: sc filled in

cat <<EOF
{
  CGEN_INSN_INT insn = GETIMEMUHI (current_cpu, vpc);
  extract (current_cpu, vpc, insn, SEM_ARGBUF (sc), FAST_P);
}
EOF

;;

xextract-pbb)

# Inputs:  current_cpu, pc, sc, max_insns, FAST_P
# Outputs: sc, pc
# sc must be left pointing past the last created entry.
# pc must be left pointing past the last created entry.
# If the pbb is terminated by a cti insn, SET_CTI_VPC(sc) must be called
# to record the vpc of the cti insn.
# SET_INSN_COUNT(n) must be called to record number of real insns.

cat <<EOF
{
  const IDESC *idesc;
  int icount = 0;

  /* Make sure the buffer doesn't overflow for profiled insns if
     max_insns happens to not be a multiple of 3.  */
  if (!FAST_P)
     max_insns -= 2 + 3;
  else
     /* There might be two real insns handled per loop.  */
     max_insns--;

  while (max_insns > 0)
    {
      UHI insn = GETIMEMUHI (current_cpu, pc);
      int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
      int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
      int befaft_p = profile_p || trace_p;

      if (befaft_p)
	{
	  @cpu@_emit_before (current_cpu, sc, pc, 1);
	  ++sc;
	  sc->argbuf.trace_p = trace_p;
	  sc->argbuf.profile_p = profile_p;
	  --max_insns;
	}

      idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);
      ++sc;
      --max_insns;
      ++icount;

      if (befaft_p)
	{
	  @cpu@_emit_after (current_cpu, sc, pc);
	  ++sc;
	  --max_insns;
	}

      pc += idesc->length;

      if (IDESC_CTI_P (idesc))
	{
	  SET_CTI_VPC (sc - 1);

	  /* Delay slot?  Ignore for zero-instructions (bcc .+2) since
	     those are treated as exit insns to avoid runaway sessions
	     for invalid programs.  */
	  if (insn != 0 && CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_DELAY_SLOT))
	    {
	      UHI insn;
	      trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
	      profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
	      befaft_p = profile_p || trace_p;

	      if (befaft_p)
		{
		  @cpu@_emit_before (current_cpu, sc, pc, 1);
		  ++sc;
		  sc->argbuf.trace_p = trace_p;
		  sc->argbuf.profile_p = profile_p;
		  --max_insns;
		}

	      insn = GETIMEMUHI (current_cpu, pc);
	      idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);
	      ++sc;
	      --max_insns;
	      ++icount;

	      if (befaft_p)
		{
		  @cpu@_emit_after (current_cpu, sc, pc);
		  ++sc;
		  --max_insns;
		}
	      pc += idesc->length;
	    }
	  break;
	}
    }

 Finish:
  SET_INSN_COUNT (icount);
}
EOF

;;

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

# Inputs: current_cpu, sc, FAST_P
# Outputs: vpc
# vpc contains the address of the next insn to execute

cat <<EOF
{
#if (! FAST_P && WITH_SEM_SWITCH_FULL) || (FAST_P && WITH_SEM_SWITCH_FAST)
#define DEFINE_SWITCH
#include "sem@cpu@-switch.c"
#else
  vpc = execute (current_cpu, vpc, FAST_P);
#endif
}
EOF

;;

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

esac
