# Simulator main loop for i960. -*- C -*-
# Copyright (C) 1996, 1997, 1998, 1999 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.
# It can't provide more than this, however for illustration's sake the M32R
# port 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 *
extract32 (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
	   ARGBUF *abuf, int fast_p)
{
  /* ??? wilson, instructions are 32 bits.  */
  const IDESC *d = @cpu@_decode (current_cpu, pc, (USI) insn, abuf);
  @cpu@_fill_argbuf (current_cpu, abuf, d, 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 d;
}

#if 0
/*static INLINE*/ const IDESC *
/* ??? wilson, Some instructions are 64 bits.  */
extract64 (SIM_CPU *current_cpu, PCADDR pc, insn_t insn,
	   ARGBUF *abuf, int fast_p)
{
  const IDESC *d = @cpu@_decode (current_cpu, pc, (UDI) insn >> 32, abuf);
  SEM_SET_CODE (abuf, d, fast_p);
  abuf->idesc = d;
  abuf->addr = pc;
  return d;
}
#endif

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 *insn = idesc->idata;
#if WITH_SCACHE_PBB
      int virtual_p = CGEN_INSN_ATTR_VALUE (insn, 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))
	    @cpu@_model_insn_before (current_cpu, 1 /*first_p*/);
	  TRACE_INSN_INIT (current_cpu, abuf, 1);
	  TRACE_INSN (current_cpu, insn,
		      (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))
	    {
	      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)

cat <<EOF
/*xxxinit*/
EOF

;;

xextract-simple | xextract-scache)

cat <<EOF
{
  if ((pc & 3) != 0)
    {
      abort ();
#if 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);
#endif
    }
  else
    {
      USI insn = GETIMEMUSI (current_cpu, pc);
      /* ??? wilson, insns are 32 bits, unless MEMB with displacement, which
	 has high bit set, bit 12 set, and mode of 5, 12, 13, 14, or 15.  */
      if (((SI) insn > 0)
	  || ! (((insn & 0x3000) == 0x3000)
		|| ((insn & 0x3C00) == 0x1400)))
	{
	  extract32 (current_cpu, pc, insn, sc, FAST_P);
	}
      else
	{
	  UDI llinsn = (((UDI) insn << 32) || GETIMEMUSI (current_cpu, pc+4));
	  extract64 (current_cpu, pc, llinsn, 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;

  if ((pc & 3) != 0)
    {
      abort ();
#if 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;
	}
#endif
    }

  while (max_insns > 0)
    {
      USI insn = GETIMEMUSI (current_cpu, pc);
#if 0
      /* ??? wilson, insns are 32 bits, unless MEMB with displacement, which
	 has high bit set, bit 12 set, and mode of 5, 12, 13, 14, or 15.  */
      if (((SI) insn > 0)
	  || ! (((insn & 0x3000) == 0x3000)
		|| ((insn & 0x3C00) == 0x1400)))
	{
	  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 = extract64 (current_cpu, pc, insn, &sc->argbuf, FAST_P);
	  ++sc;
	  --max_insns;
	  ++icount;
	  pc += 8;
	  if (IDESC_CTI_P (idesc))
	    {
	      SET_CTI_VPC (sc - 1);
	      break;
	    }
	}
#else
      idesc = extract32 (current_cpu, pc, insn, &sc->argbuf, FAST_P);
      ++sc;
      --max_insns;
      ++icount;
      pc += idesc->length;
      if (IDESC_CTI_P (idesc))
        {
          SET_CTI_VPC (sc - 1);
          break;
        }
    }
#endif
 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
