# Simulator main loop for CRIS. -*- C -*-
# Copyright (C) 2004, 2005 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 2, 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, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

# 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
