# Simulator main loop for m32rx. -*- C -*-
#
# Copyright 1996-2024 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.

# ??? 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
#line $LINENO "$0"

/* Emit insns to write back the results of insns executed in parallel.
   SC points to a sufficient number of scache entries for the writeback
   handlers.
   SC1/ID1 is the first insn (left slot, lower address).
   SC2/ID2 is the second insn (right slot, higher address).  */

static INLINE void
emit_par_finish (SIM_CPU *current_cpu, PCADDR pc, SCACHE *sc,
		 SCACHE *sc1, const IDESC *id1, SCACHE *sc2, const IDESC *id2)
{
  ARGBUF *abuf;

  abuf = &sc->argbuf;
  id1 = id1->par_idesc;
  abuf->fields.write.abuf = &sc1->argbuf;
  @cpu@_fill_argbuf (current_cpu, abuf, id1, pc, 0);
  /* no need to set trace_p,profile_p */
#if 0 /* not currently needed for id2 since results written directly */
  abuf = &sc[1].argbuf;
  id2 = id2->par_idesc;
  abuf->fields.write.abuf = &sc2->argbuf;
  @cpu@_fill_argbuf (current_cpu, abuf, id2, pc + 2, 0);
  /* no need to set trace_p,profile_p */
#endif
}

static INLINE const IDESC *
emit_16 (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
	 SCACHE *sc, int fast_p, int parallel_p)
{
  ARGBUF *abuf = &sc->argbuf;
  const IDESC *id = @cpu@_decode (current_cpu, pc, insn, insn, abuf);

  if (parallel_p)
    id = id->par_idesc;
  @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
  return id;
}

static INLINE const IDESC *
emit_full16 (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn, SCACHE *sc,
	     int trace_p, int profile_p)
{
  const IDESC *id;

  @cpu@_emit_before (current_cpu, sc, pc, 1);
  id = emit_16 (current_cpu, pc, insn, sc + 1, 0, 0);
  @cpu@_emit_after (current_cpu, sc + 2, pc);
  @cpu@_fill_argbuf_tp (current_cpu, &sc[1].argbuf, trace_p, profile_p);
  return id;
}

static INLINE const IDESC *
emit_parallel (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
	       SCACHE *sc, int fast_p)
{
  const IDESC *id,*id2;

  /* Emit both insns, then emit a finisher-upper.
     We speed things up by handling the second insn serially
     [not parallelly].  Then the writeback only has to deal
     with the first insn.  */
  /* ??? Revisit to handle exceptions right.  */

  /* FIXME: No need to handle this parallely if second is nop.  */
  id = emit_16 (current_cpu, pc, insn >> 16, sc, fast_p, 1);

  /* Note that this can never be a cti.  No cti's go in the S pipeline.  */
  id2 = emit_16 (current_cpu, pc + 2, insn & 0x7fff, sc + 1, fast_p, 0);

  /* Set sc/snc insns notion of where to skip to.  */
  if (IDESC_SKIP_P (id))
    SEM_SKIP_COMPILE (current_cpu, sc, 1);

  /* Emit code to finish executing the semantics
     (write back the results).  */
  emit_par_finish (current_cpu, pc, sc + 2, sc, id, sc + 1, id2);

  return id;
}

static INLINE const IDESC *
emit_full_parallel (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
		    SCACHE *sc, int trace_p, int profile_p)
{
  const IDESC *id,*id2;

  /* Emit both insns, then emit a finisher-upper.
     We speed things up by handling the second insn serially
     [not parallelly].  Then the writeback only has to deal
     with the first insn.  */
  /* ??? Revisit to handle exceptions right.  */

  @cpu@_emit_before (current_cpu, sc, pc, 1);

  /* FIXME: No need to handle this parallelly if second is nop.  */
  id = emit_16 (current_cpu, pc, insn >> 16, sc + 1, 0, 1);
  @cpu@_fill_argbuf_tp (current_cpu, &sc[1].argbuf, trace_p, profile_p);

  @cpu@_emit_before (current_cpu, sc + 2, pc, 0);

  /* Note that this can never be a cti.  No cti's go in the S pipeline.  */
  id2 = emit_16 (current_cpu, pc + 2, insn & 0x7fff, sc + 3, 0, 0);
  @cpu@_fill_argbuf_tp (current_cpu, &sc[3].argbuf, trace_p, profile_p);

  /* Set sc/snc insns notion of where to skip to.  */
  if (IDESC_SKIP_P (id))
    SEM_SKIP_COMPILE (current_cpu, sc, 4);

  /* Emit code to finish executing the semantics
     (write back the results).  */
  emit_par_finish (current_cpu, pc, sc + 4, sc + 1, id, sc + 3, id2);

  @cpu@_emit_after (current_cpu, sc + 5, pc);

  return id;
}

static INLINE const IDESC *
emit_32 (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
	 SCACHE *sc, int fast_p)
{
  ARGBUF *abuf = &sc->argbuf;
  const IDESC *id = @cpu@_decode (current_cpu, pc,
				  (USI) insn >> 16, insn, abuf);

  @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
  return id;
}

static INLINE const IDESC *
emit_full32 (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn, SCACHE *sc,
	     int trace_p, int profile_p)
{
  const IDESC *id;

  @cpu@_emit_before (current_cpu, sc, pc, 1);
  id = emit_32 (current_cpu, pc, insn, sc + 1, 0);
  @cpu@_emit_after (current_cpu, sc + 2, pc);
  @cpu@_fill_argbuf_tp (current_cpu, &sc[1].argbuf, trace_p, profile_p);
  return id;
}

EOF

;;

xinit)

# Nothing needed.

;;

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
#line $LINENO "$0"
{
  const IDESC *idesc;
  int icount = 0;

  if ((pc & 3) != 0)
    {
      /* This occurs when single stepping and when compiling the not-taken
	 part of conditional branches.  */
      UHI insn = GETIMEMUHI (current_cpu, pc);
      int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
      int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
      SCACHE *cti_sc; /* ??? tmp hack */

      /* A parallel insn isn't allowed here, but we don't mind nops.
	 ??? We need to wait until the insn is executed before signalling
	 the error, for situations where such signalling is wanted.  */
#if 0
      if ((insn & 0x8000) != 0
	  && (insn & 0x7fff) != 0x7000) /* parallel nops are ok */
	sim_engine_invalid_insn (current_cpu, pc, 0);
#endif

      /* Only emit before/after handlers if necessary.  */
      if (FAST_P || (! trace_p && ! profile_p))
	{
	  idesc = emit_16 (current_cpu, pc, insn & 0x7fff, sc, FAST_P, 0);
	  cti_sc = sc;
	  ++sc;
	  --max_insns;
	}
      else
	{
	  idesc = emit_full16 (current_cpu, pc, insn & 0x7fff, sc,
			       trace_p, profile_p);
	  cti_sc = sc + 1;
	  sc += 3;
	  max_insns -= 3;
	}
      ++icount;
      pc += 2;
      if (IDESC_CTI_P (idesc))
	{
	  SET_CTI_VPC (cti_sc);
	  goto Finish;
	}
    }

  /* There are two copies of the compiler: full(!fast) and fast.
     The "full" case emits before/after handlers for each insn.
     Having two copies of this code is a tradeoff, having one copy
     seemed a bit more difficult to read (due to constantly testing
     FAST_P).  ??? On the other hand, with address ranges we'll want to
     omit before/after handlers for unwanted insns.  Having separate loops
     for FAST/!FAST avoids constantly doing the test in the loop, but
     typically FAST_P is a constant and such tests will get optimized out.  */

  if (FAST_P)
    {
      while (max_insns > 0)
	{
	  USI insn = GETIMEMUSI (current_cpu, pc);
	  if ((SI) insn < 0)
	    {
	      /* 32 bit insn */
	      idesc = emit_32 (current_cpu, pc, insn, sc, 1);
	      ++sc;
	      --max_insns;
	      ++icount;
	      pc += 4;
	      if (IDESC_CTI_P (idesc))
		{
		  SET_CTI_VPC (sc - 1);
		  break;
		}
	    }
	  else
	    {
	      if ((insn & 0x8000) != 0) /* parallel? */
		{
		  int up_count;

		  if (((insn >> 16) & 0xfff0) == 0x10f0)
		    {
		      /* FIXME: No need to handle this sequentially if system
		         calls will be able to execute after second insn in
		         parallel. ( trap #num || insn ) */
		      /* insn */
		      idesc = emit_16 (current_cpu, pc + 2, insn & 0x7fff,
 				       sc, 1, 0);
		      /* trap */
		      emit_16 (current_cpu, pc, insn >> 16, sc + 1, 1, 0);
		      up_count = 2;
		    }
		  else
		    {
		      /* Yep.  Here's the "interesting" [sic] part.  */
		      idesc = emit_parallel (current_cpu, pc, insn, sc, 1);
		      up_count = 3;
		    }
		  sc += up_count;
		  max_insns -= up_count;
		  icount += 2;
		  pc += 4;
		  if (IDESC_CTI_P (idesc))
		    {
		      SET_CTI_VPC (sc - up_count);
		      break;
		    }
		}
	      else /* 2 serial 16 bit insns */
		{
		  idesc = emit_16 (current_cpu, pc, insn >> 16, sc, 1, 0);
		  ++sc;
		  --max_insns;
		  ++icount;
		  pc += 2;
		  if (IDESC_CTI_P (idesc))
		    {
		      SET_CTI_VPC (sc - 1);
		      break;
		    }
		  /* While we're guaranteed that there's room to extract the
		     insn, when single stepping we can't; the pbb must stop
		     after the first insn.  */
		  if (max_insns == 0)
		    break;
		  idesc = emit_16 (current_cpu, pc, insn & 0x7fff, sc, 1, 0);
		  ++sc;
		  --max_insns;
		  ++icount;
		  pc += 2;
		  if (IDESC_CTI_P (idesc))
		    {
		      SET_CTI_VPC (sc - 1);
		      break;
		    }
		}
	    }
	}
    }
  else /* ! FAST_P */
    {
      while (max_insns > 0)
	{
	  USI insn = GETIMEMUSI (current_cpu, pc);
	  int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
	  int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
	  SCACHE *cti_sc; /* ??? tmp hack */
	  if ((SI) insn < 0)
	    {
	      /* 32 bit insn
		 Only emit before/after handlers if necessary.  */
	      if (trace_p || profile_p)
		{
		  idesc = emit_full32 (current_cpu, pc, insn, sc,
				       trace_p, profile_p);
		  cti_sc = sc + 1;
		  sc += 3;
		  max_insns -= 3;
		}
	      else
		{
		  idesc = emit_32 (current_cpu, pc, insn, sc, 0);
		  cti_sc = sc;
		  ++sc;
		  --max_insns;
		}
	      ++icount;
	      pc += 4;
	      if (IDESC_CTI_P (idesc))
		{
		  SET_CTI_VPC (cti_sc);
		  break;
		}
	    }
	  else
	    {
	      if ((insn & 0x8000) != 0) /* parallel? */
		{
		  /* Yep.  Here's the "interesting" [sic] part.
		     Only emit before/after handlers if necessary.  */
		  if (trace_p || profile_p)
		    {
		      if (((insn >> 16) & 0xfff0) == 0x10f0)
			{
			  /* FIXME: No need to handle this sequentially if
			     system calls will be able to execute after second
			     insn in parallel. ( trap #num || insn ) */
			  /* insn */
			  idesc = emit_full16 (current_cpu, pc + 2,
					       insn & 0x7fff, sc, 0, 0);
			  /* trap */
			  emit_full16 (current_cpu, pc, insn >> 16, sc + 3,
				       0, 0);
			}
		      else
			{
		          idesc = emit_full_parallel (current_cpu, pc, insn,
						      sc, trace_p, profile_p);
			}
		      cti_sc = sc + 1;
		      sc += 6;
		      max_insns -= 6;
		    }
		  else
		    {
		      int up_count;

		      if (((insn >> 16) & 0xfff0) == 0x10f0)
			{
                          /* FIXME: No need to handle this sequentially if
                             system calls will be able to execute after second
                             insn in parallel. ( trap #num || insn ) */
                          /* insn */
                          idesc = emit_16 (current_cpu, pc + 2, insn & 0x7fff,
                                           sc, 0, 0);
                          /* trap */
                          emit_16 (current_cpu, pc, insn >> 16, sc + 1, 0, 0);
                          up_count = 2;
			}
		      else
			{
		          idesc = emit_parallel (current_cpu, pc, insn, sc, 0);
                          up_count = 3;
			}
		      cti_sc = sc;
		      sc += up_count;
		      max_insns -= up_count;
		    }
		  icount += 2;
		  pc += 4;
		  if (IDESC_CTI_P (idesc))
		    {
		      SET_CTI_VPC (cti_sc);
		      break;
		    }
		}
	      else /* 2 serial 16 bit insns */
		{
		  /* Only emit before/after handlers if necessary.  */
		  if (trace_p || profile_p)
		    {
		      idesc = emit_full16 (current_cpu, pc, insn >> 16, sc,
					   trace_p, profile_p);
		      cti_sc = sc + 1;
		      sc += 3;
		      max_insns -= 3;
		    }
		  else
		    {
		      idesc = emit_16 (current_cpu, pc, insn >> 16, sc, 0, 0);
		      cti_sc = sc;
		      ++sc;
		      --max_insns;
		    }
		  ++icount;
		  pc += 2;
		  if (IDESC_CTI_P (idesc))
		    {
		      SET_CTI_VPC (cti_sc);
		      break;
		    }
		  /* While we're guaranteed that there's room to extract the
		     insn, when single stepping we can't; the pbb must stop
		     after the first insn.  */
		  if (max_insns <= 0)
		    break;
		  /* Use the same trace/profile address for the 2nd insn.
		     Saves us having to compute it and they come in pairs
		     anyway (e.g. can never branch to the 2nd insn).  */
		  if (trace_p || profile_p)
		    {
		      idesc = emit_full16 (current_cpu, pc, insn & 0x7fff, sc,
					   trace_p, profile_p);
		      cti_sc = sc + 1;
		      sc += 3;
		      max_insns -= 3;
		    }
		  else
		    {
		      idesc = emit_16 (current_cpu, pc, insn & 0x7fff, sc, 0, 0);
		      cti_sc = sc;
		      ++sc;
		      --max_insns;
		    }
		  ++icount;
		  pc += 2;
		  if (IDESC_CTI_P (idesc))
		    {
		      SET_CTI_VPC (cti_sc);
		      break;
		    }
		}
	    }
	}
    }

 Finish:
  SET_INSN_COUNT (icount);
}
EOF

;;

xfull-exec-pbb)

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

cat <<EOF
#line $LINENO "$0"
#define DEFINE_SWITCH
#include "semx-switch.c"
EOF

;;

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

esac
