# Simulator main loop for or1k. -*- C -*-
#
# Copyright (C) 2017-2019 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 *
extract (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 SEM_PC
execute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p)
{
  SEM_PC vpc = sc;

  @cpu@_insn_before (current_cpu, vpc, sc->argbuf.idesc);

  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 */
    }

  @cpu@_insn_after (current_cpu, vpc, sc->argbuf.idesc);

  return vpc;
}

EOF

;;

xinit)

# Nothing needed.

;;

xextract-simple | xextract-scache)

cat <<EOF
{
  USI insn = GETIMEMUSI (current_cpu, pc);
  extract (current_cpu, pc, insn, sc, FAST_P);
  SEM_SKIP_COMPILE (current_cpu, sc, 1);
}
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;

  while (max_insns > 0) {

    USI insn = GETIMEMUSI (current_cpu, pc);

    idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);

    SEM_SKIP_COMPILE (current_cpu, sc, 1);

    ++sc;
    --max_insns;
    ++icount;
    pc += 4;

    if (CGEN_ATTR_BOOLS (CGEN_INSN_ATTRS ((idesc)->idata)) & CGEN_ATTR_MASK (CGEN_INSN_FORCED_CTI))
      {

        SET_CTI_VPC (sc - 1);

        break;

      }
    else if (CGEN_ATTR_BOOLS (CGEN_INSN_ATTRS ((idesc)->idata)) & CGEN_ATTR_MASK (CGEN_INSN_DELAYED_CTI))
      {

        /* handle delay slot */
        SET_CTI_VPC (sc - 1);

        insn = GETIMEMUSI (current_cpu, pc);

        idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);

        ++sc;
        --max_insns;
        ++icount;
        pc += 4;

        break;
      }
  }

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

;;

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

esac
