# Simulator main loop for eBPF. -*- C -*-
#
# Copyright (C) 2020-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 mloop.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_WORD insn,
         ARGBUF *abuf, int fast_p)
{
  const IDESC *id = @prefix@_decode (current_cpu, pc, insn, abuf);
  @prefix@_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);
      @prefix@_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)
      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);
  else
    {
      ARGBUF *abuf = &sc->argbuf;
      const IDESC *idesc = abuf->idesc;
      const CGEN_INSN *idata = idesc->idata;
      int virtual_p = 0;

      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);
        }
      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc);
      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);
        }
    }

  return vpc;
}

EOF

;;

xinit)

# Nothing needed.

;;

xextract-scache)

cat <<EOF
{

  UDI insn = GETIMEMUDI (current_cpu, vpc);

  if (CURRENT_TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
    {
      UHI off16;
      USI imm32;

      /* eBPF instructions are little-endian, but GETIMEMUDI reads according
         to target byte order. Swap to little-endian. */
      insn = SWAP_8 (insn);

      /* But, the imm32 and offset16 fields within instructions follow target
         byte order. Swap those fields back. */
      off16 = (UHI) ((insn & 0x00000000ffff0000) >> 16);
      imm32 = (USI) ((insn & 0xffffffff00000000) >> 32);
      off16 = SWAP_2 (off16);
      imm32 = SWAP_4 (imm32);

      insn = (((UDI) imm32) << 32) | (((UDI) off16) << 16) | (insn & 0xffff);
    }

  extract (current_cpu, vpc, insn, SEM_ARGBUF (sc), FAST_P);

  //XXX  SEM_SKIP_COMPILE (current_cpu, sc, 1);
}
EOF

;;

xfull-exec-* | xfast-exec-*)

# Inputs: current_cpu, vpc, sc, FAST_P
# Outputs: vpc
# vpc is the virtual program counter.

cat <<EOF
   vpc = execute (current_cpu, sc, FAST_P);
EOF

;;

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

esac
