/* Main simulator loop for CGEN-based simulators.
   Copyright (C) 1998-2021 Free Software Foundation, Inc.
   Contributed by Cygnus Solutions.

This file is part of GDB, the GNU debugger.

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

/* ??? These are old notes, kept around for now.
   Collecting profile data and tracing slow us down so we don't do them in
   "fast mode".
   There are 6 possibilities on 2 axes:
   - no-scaching, insn-scaching, basic-block-scaching
   - run with full features or run fast
   Supporting all six possibilities in one executable is a bit much but
   supporting full/fast seems reasonable.
   If the scache is configured in it is always used.
   If pbb-scaching is configured in it is always used.
   ??? Sometimes supporting more than one set of semantic functions will make
   the simulator too large - this should be configurable.  Blah blah blah.
   ??? Supporting full/fast can be more modular, blah blah blah.
   When the framework is more modular, this can be.
*/

/* This must come before any other includes.  */
#include "defs.h"

#include "sim-main.h"
#include "sim-assert.h"
#include "sim-signal.h"

#ifndef SIM_ENGINE_PREFIX_HOOK
#define SIM_ENGINE_PREFIX_HOOK(sd)
#endif
#ifndef SIM_ENGINE_POSTFIX_HOOK
#define SIM_ENGINE_POSTFIX_HOOK(sd)
#endif

static sim_event_handler has_stepped;
static void prime_cpu (SIM_CPU *, int);
static void engine_run_1 (SIM_DESC, int, int);
static void engine_run_n (SIM_DESC, int, int, int, int);

/* If no profiling or tracing has been enabled, run in fast mode.  */
static int
cgen_get_fast_p (SIM_DESC sd)
{
  int i, c;
  int run_fast_p = 1;

  for (c = 0; c < MAX_NR_PROCESSORS; ++c)
    {
      SIM_CPU *cpu = STATE_CPU (sd, c);

      if (PROFILE_ANY_P (cpu) || TRACE_ANY_P (cpu))
	return 0;
    }

  return 1;
}

/* sim_resume for cgen */

void
sim_resume (SIM_DESC sd, int step, int siggnal)
{
  sim_engine *engine = STATE_ENGINE (sd);
  jmp_buf buf;
  int jmpval;
  static int fast_p = -1;

  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);

  if (fast_p == -1)
    fast_p = cgen_get_fast_p (sd);

  /* we only want to be single stepping the simulator once */
  if (engine->stepper != NULL)
    {
      sim_events_deschedule (sd, engine->stepper);
      engine->stepper = NULL;
    }
  if (step)
    engine->stepper = sim_events_schedule (sd, 1, has_stepped, sd);

  sim_module_resume (sd);

#if WITH_SCACHE
  if (USING_SCACHE_P (sd))
    scache_flush (sd);
#endif

  /* run/resume the simulator */

  sim_engine_set_run_state (sd, sim_running, 0);

  engine->jmpbuf = &buf;
  jmpval = setjmp (buf);
  if (jmpval == sim_engine_start_jmpval
      || jmpval == sim_engine_restart_jmpval)
    {
      int last_cpu_nr = sim_engine_last_cpu_nr (sd);
      int next_cpu_nr = sim_engine_next_cpu_nr (sd);
      int nr_cpus = sim_engine_nr_cpus (sd);
      /* ??? Setting max_insns to 0 allows pbb/jit code to run wild and is
	 useful if all one wants to do is run a benchmark.  Need some better
	 way to identify this case.  */
      int max_insns = (step
		       ? 1
		       : (nr_cpus == 1
			  /*&& wip:no-events*/
			  /* Don't do this if running under gdb, need to
			     poll ui for events.  */
			  && STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
		       ? 0
		       : 8); /*FIXME: magic number*/

      sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus);
      if (next_cpu_nr >= nr_cpus)
	next_cpu_nr = 0;
      if (nr_cpus == 1)
	engine_run_1 (sd, max_insns, fast_p);
      else
	engine_run_n (sd, next_cpu_nr, nr_cpus, max_insns, fast_p);
    }
#if 1 /*wip*/
  else
    {
      /* Account for the last insn executed.  */
      SIM_CPU *cpu = STATE_CPU (sd, sim_engine_last_cpu_nr (sd));
      ++ CPU_INSN_COUNT (cpu);
      CGEN_TRACE_INSN_FINI (cpu, NULL, 1);
    }
#endif

  engine->jmpbuf = NULL;

  {
    int i;
    int nr_cpus = sim_engine_nr_cpus (sd);

#if 0 /*wip,ignore*/
    /* If the loop exits, either we single-stepped or @cpu@_engine_stop
       was called.  */
    if (step)
      sim_engine_set_run_state (sd, sim_stopped, SIM_SIGTRAP);
    else
      sim_engine_set_run_state (sd, pending_reason, pending_sigrc);
#endif

    for (i = 0; i < nr_cpus; ++i)
      {
	SIM_CPU *cpu = STATE_CPU (sd, i);

	PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu)) += CPU_INSN_COUNT (cpu);
      }
  }

  sim_module_suspend (sd);
}

/* Halt the simulator after just one instruction.  */

static void
has_stepped (SIM_DESC sd, void *data)
{
  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP);
}

/* Prepare a cpu for running.
   MAX_INSNS is the number of insns to execute per time slice.
   If 0 it means the cpu can run as long as it wants (e.g. until the
   program completes).
   ??? Perhaps this should be an argument to the engine_fn.  */

static void
prime_cpu (SIM_CPU *cpu, int max_insns)
{
  CPU_MAX_SLICE_INSNS (cpu) = max_insns;
  CPU_INSN_COUNT (cpu) = 0;

  /* Initialize the insn descriptor table.
     This has to be done after all initialization so we just defer it to
     here.  */

  if (MACH_PREPARE_RUN (CPU_MACH (cpu)))
    (* MACH_PREPARE_RUN (CPU_MACH (cpu))) (cpu);
}

/* Main loop, for 1 cpu.  */

static void
engine_run_1 (SIM_DESC sd, int max_insns, int fast_p)
{
  sim_cpu *cpu = STATE_CPU (sd, 0);
  ENGINE_FN *fn = fast_p ? CPU_FAST_ENGINE_FN (cpu) : CPU_FULL_ENGINE_FN (cpu);

  prime_cpu (cpu, max_insns);

  while (1)
    {
      SIM_ENGINE_PREFIX_HOOK (sd);

      (*fn) (cpu);

      SIM_ENGINE_POSTFIX_HOOK (sd);

      /* process any events */
      if (sim_events_tick (sd))
	sim_events_process (sd);
    }
}

/* Main loop, for multiple cpus.  */

static void
engine_run_n (SIM_DESC sd, int next_cpu_nr, int nr_cpus, int max_insns, int fast_p)
{
  int i;
  ENGINE_FN *engine_fns[MAX_NR_PROCESSORS];

  SIM_ASSERT (nr_cpus <= MAX_NR_PROCESSORS);
  SIM_ASSERT (next_cpu_nr >= 0 && next_cpu_nr < nr_cpus);

  for (i = 0; i < nr_cpus; ++i)
    {
      SIM_CPU *cpu = STATE_CPU (sd, i);

      engine_fns[i] = fast_p ? CPU_FAST_ENGINE_FN (cpu) : CPU_FULL_ENGINE_FN (cpu);
      prime_cpu (cpu, max_insns);
    }

  while (1)
    {
      SIM_ENGINE_PREFIX_HOOK (sd);

      /* FIXME: proper cycling of all of them, blah blah blah.  */
      while (next_cpu_nr < nr_cpus)
	{
	  SIM_CPU *cpu = STATE_CPU (sd, next_cpu_nr);

	  (* engine_fns[next_cpu_nr]) (cpu);
	  ++next_cpu_nr;
	}

      SIM_ENGINE_POSTFIX_HOOK (sd);

      /* process any events */
      if (sim_events_tick (sd))
	sim_events_process (sd);
    }
}
