# 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 two slots for a delay slot insn and zero overhead loop.  */
  max_insns -= 2;
  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;

      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
	    max_insns = 0;
	}
      /* Handle zero overhead loops.  ARC 600 and ARC 700 suppress
	 zero overhead loops if a branch is pending.  */
      if (pc == loop_end)
	{
	  const IDESC *id =
	    & CPU_IDESC (current_cpu)
	      [_cti_sc ? @CPU@_INSN_ARC600_CURRENT_LOOP_END_AFTER_BRANCH
	       : @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;
	}
    }

 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 "sem6-switch.c"
#else
  vpc = execute (current_cpu, vpc, FAST_P);
#endif
EOF

;;

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

esac
