/* Main simulator loop for CGEN-based simulators.
   Copyright (C) 1998-2016 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.
*/

#include "sim-main.h"
#include "sim-assert.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);

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

  ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);

  /* 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*/
      int fast_p = STATE_RUN_FAST_P (sd);

      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];

  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);
    }
}
