# Simulator main loop for m32r. -*- C -*-
#
# Copyright (C) 1996-2016 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*/);
	  CGEN_TRACE_INSN_INIT (current_cpu, abuf, 1);
	  CGEN_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);
	    }
	  CGEN_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
