# Simulator main loop for CRIS. -*- C -*-
# Copyright (C) 2004-2024 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
#line $LINENO "$0"
#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;
}

/* This might not be used directly depending on the fast compile mode.  */
ATTRIBUTE_UNUSED 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
#line $LINENO "$0"
  /* 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
#line $LINENO "$0"
{
  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
#line $LINENO "$0"
{
  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))
	    {
	      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
#line $LINENO "$0"
{
#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
