# Simulator main loop for CRIS. -*- C -*-
# Copyright (C) 2004, 2005, 2007, 2008, 2009 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
/* 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*/);
	  TRACE_INSN_INIT (current_cpu, abuf, 1);
	  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);
	    }
	  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
