# Simulator main loop for or1k. -*- C -*-
#
# Copyright (C) 2017-2021 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
#include <stdlib.h>

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
