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

# 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 *
extract (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT base_insn,
	 CGEN_INSN_INT insn, ARGBUF *abuf,
	 int fast_p)
{
  const IDESC *id = @cpu@_decode (current_cpu, pc, /*base_*/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 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
{
  /* ??? FIXME: doesn't handle zero overhead loops.  */
  UHI high = GETIMEMUHI (current_cpu, vpc);
  UHI low  = GETIMEMUHI (current_cpu, vpc + 2);
  USI insn = (high << 16) + low;

  extract (current_cpu, vpc, high, 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;
  PCADDR loop_end = @cpu@_h_auxr_get (current_cpu, 3);

  /* Reserve one slot for a delay slot insn or zero overhead loop.  */
  max_insns--;
  if (max_insns < 1)
    max_insns = 1;
  while (max_insns > 0)
    {
      UHI high = GETIMEMUHI (current_cpu, pc);
      UHI low;
      USI insn = (high << 16);

      if ((high & ((HI) high >> 1)) & 0xa000)
	{
	  /* 16 bit opcode */
	  idesc = extract (current_cpu, pc, high, insn, SEM_ARGBUF (sc),
			   FAST_P);
	  pc += 2;
	  /* Check for mov/cmp/add with long immediate.  */
	  if ((high & 0xf8e7) == 0x70c7 && (high & 24) < 24)
	    pc += 4;
	}
      else
	{
	  /* 32 bit opcode */
	  low  = GETIMEMUHI (current_cpu, pc + 2);
	  insn = insn + low;
	  idesc = extract (current_cpu, pc, high, insn, SEM_ARGBUF (sc),
			   FAST_P);
	  pc += 4;
	  /* Check for long immediate.  */
	  switch (CGEN_ATTR_CGEN_INSN_LIMM_VALUE (&(idesc->idata->base->attrs)))
	    {
	    case LIMM_H: abort ();
	    case LIMM_C:
	      if ((insn & 0x00000fc0) == 0x00000f80)
		pc += 4;
	      break;
	    case LIMM_BC:
	      if ((insn & 0x00000fc0) != 0x00000f80)
		{
	    case LIMM_B:
		  if ((insn & 0x07007000) != 0x06007000)
		    break;
		}
	      pc += 4;
	      break;
	    case LIMM_NONE: break; /* Nothing to do.  */

	    }
	}
      ++sc;
      --max_insns;
      ++icount;

      /* Handle zero overhead loops.  For ARCtangent-A5, these take
	 precendence over branches.  */
      if (pc == loop_end && !_cti_sc)
	{
	  const IDESC *id =
	    & CPU_IDESC (current_cpu) [@CPU@_INSN_CURRENT_LOOP_END];

	  SEM_SET_CODE (&sc->argbuf, id, FAST_P);
	  sc->argbuf.idesc = id;
	  sc->argbuf.addr = pc;
	  sc->argbuf.fields.chain.insn_count = _insn_count;
	  sc->argbuf.fields.chain.next = 0;
	  sc->argbuf.fields.chain.branch_target = 0;
	  ++sc;
	  SET_CTI_VPC (sc - 1);
	  break;
	}
      else if (IDESC_CTI_P (idesc))
	{
	  /* Must not have a CTI in a delay slot.  That is not only invalid
	     in a program, it also could potentially overfill the scache.  */
	  if (_cti_sc)
	    {
	      const IDESC *id =
		& CPU_IDESC (current_cpu) [@CPU@_INSN_X_INVALID];

	      SEM_SET_CODE (&sc->argbuf, id, FAST_P);
	      sc->argbuf.idesc = id;
	      break;
	    }
	  SET_CTI_VPC (sc - 1);
	  if (CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_DELAY_SLOT))
	    max_insns = 1;
	  else
	    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 "sem5-switch.c"
#else
  vpc = execute (current_cpu, vpc, FAST_P);
#endif
EOF

;;

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

esac
