# Simulator main loop for m32r. -*- C -*-
#
# Copyright (C) 1996-1998, 2007-2012 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
