# Simulator main loop for m32r. -*- C -*-
# Copyright (C) 1996, 1997, 1998, 2007, 2008, 2009
  Free Software Foundation, Inc.
#
# 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, or if
# the slow (full featured) version is `simple', then the fast version can be
# one of scache/pbb.
# A target can't provide more than this.
# However for illustration's sake this file 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

static INLINE const IDESC *
extract16 (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 const IDESC *
extract32 (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
	   ARGBUF *abuf, int fast_p)
{
  const IDESC *id = @cpu@_decode (current_cpu, pc, (USI) insn >> 16, 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;

  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;
      const CGEN_INSN *idata = idesc->idata;
#if WITH_SCACHE_PBB
      int virtual_p = CGEN_INSN_ATTR_VALUE (idata, 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, 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)

# Nothing needed.

;;

xextract-simple | xextract-scache)

cat <<EOF
{
  if ((pc & 3) != 0)
    {
      /* This only occurs when single stepping.
	 The test is unnecessary otherwise, but the cost is teensy,
	 compared with decoding/extraction.  */
      UHI insn = GETIMEMUHI (current_cpu, pc);
      extract16 (current_cpu, pc, insn & 0x7fff, sc, FAST_P);
    }
  else
    {
      USI insn = GETIMEMUSI (current_cpu, pc);
      if ((SI) insn < 0)
	{
	  extract32 (current_cpu, pc, insn, sc, FAST_P);
	}
      else
	{
	  extract16 (current_cpu, pc, insn >> 16, sc, FAST_P);
	  extract16 (current_cpu, pc + 2, insn & 0x7fff, sc + 1, FAST_P);
	  /* The m32r doesn't support parallel execution.  */
	  if ((insn & 0x8000) != 0
	      && (insn & 0x7fff) != 0x7000) /* parallel nops are ok */
	    sim_engine_illegal_insn (current_cpu, pc);
	}
    }
}
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;

  if ((pc & 3) != 0)
    {
      /* This only occurs when single stepping.
	 The test is unnecessary otherwise, but the cost is teensy,
	 compared with decoding/extraction.  */
      UHI insn = GETIMEMUHI (current_cpu, pc);
      idesc = extract16 (current_cpu, pc, insn & 0x7fff, &sc->argbuf, FAST_P);
      ++sc;
      --max_insns;
      ++icount;
      pc += 2;
      if (IDESC_CTI_P (idesc))
	{
	  SET_CTI_VPC (sc - 1);
	  goto Finish;
	}
    }

  while (max_insns > 0)
    {
      USI insn = GETIMEMUSI (current_cpu, pc);
      if ((SI) insn < 0)
	{
	  idesc = extract32 (current_cpu, pc, insn, &sc->argbuf, FAST_P);
	  ++sc;
	  --max_insns;
	  ++icount;
	  pc += 4;
	  if (IDESC_CTI_P (idesc))
	    {
	      SET_CTI_VPC (sc - 1);
	      break;
	    }
	}
      else
	{
	  idesc = extract16 (current_cpu, pc, insn >> 16, &sc->argbuf, FAST_P);
	  ++sc;
	  --max_insns;
	  ++icount;
	  pc += 2;
	  if (IDESC_CTI_P (idesc))
	    {
	      SET_CTI_VPC (sc - 1);
	      break;
	    }
	  /* The m32r doesn't support parallel execution.  */
	  if ((insn & 0x8000) != 0)
	    {
	      /* ??? Defer signalling to execution.  */
	      if ((insn & 0x7fff) != 0x7000) /* parallel nops are ok */
		sim_engine_invalid_insn (current_cpu, pc - 2, 0);
	      /* There's no point in processing parallel nops in fast mode.
		 We might as well do this test since we've already tested
		 that we have a parallel nop.  */
	      if (0 && FAST_P)
		{
		  pc += 2;
		  continue;
		}
	    }
	  else
	    {
	      /* Non-parallel case.
		 While we're guaranteed that there's room to extract the
		 insn, when single stepping we can't; the pbb must stop
		 after the first insn.  */
	      if (max_insns == 0)
		break;
	    }
	  /* We're guaranteed that we can always process 16 bit insns in
	     pairs.  */
	  idesc = extract16 (current_cpu, pc, insn & 0x7fff, &sc->argbuf, FAST_P);
	  ++sc;
	  --max_insns;
	  ++icount;
	  pc += 2;
	  if (IDESC_CTI_P (idesc))
	    {
	      SET_CTI_VPC (sc - 1);
	      break;
	    }
	}
    }

 Finish:
  SET_INSN_COUNT (icount);
}
EOF

;;

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

# Inputs: current_cpu, vpc, FAST_P
# Outputs: vpc
# vpc is the virtual program counter.

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

;;

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

esac
