xref: /netbsd-src/external/gpl3/gdb/dist/sim/lm32/mloop.in (revision 71f621822dbfd5073a314948bec169b7bb05f7be)
14e98e3e1Schristos# Simulator main loop for lm32. -*- C -*-
24e98e3e1Schristos# Contributed by Jon Beniston <jon@beniston.com>
34e98e3e1Schristos#
44e98e3e1Schristos# This file is part of the GNU Simulators.
54e98e3e1Schristos#
64e98e3e1Schristos# This program is free software; you can redistribute it and/or modify
74e98e3e1Schristos# it under the terms of the GNU General Public License as published by
8a2e2270fSchristos# the Free Software Foundation; either version 3, or (at your option)
94e98e3e1Schristos# any later version.
104e98e3e1Schristos#
114e98e3e1Schristos# This program is distributed in the hope that it will be useful,
124e98e3e1Schristos# but WITHOUT ANY WARRANTY; without even the implied warranty of
134e98e3e1Schristos# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
144e98e3e1Schristos# GNU General Public License for more details.
154e98e3e1Schristos#
164e98e3e1Schristos# You should have received a copy of the GNU General Public License along
17a2e2270fSchristos# with this program; if not, see <http://www.gnu.org/licenses/>.
184e98e3e1Schristos
194e98e3e1Schristos# Syntax:
204e98e3e1Schristos# /bin/sh mainloop.in command
214e98e3e1Schristos#
224e98e3e1Schristos# Command is one of:
234e98e3e1Schristos#
244e98e3e1Schristos# init
254e98e3e1Schristos# support
264e98e3e1Schristos# extract-{simple,scache,pbb}
274e98e3e1Schristos# {full,fast}-exec-{simple,scache,pbb}
284e98e3e1Schristos#
294e98e3e1Schristos
304e98e3e1Schristoscase "x$1" in
314e98e3e1Schristos
324e98e3e1Schristosxsupport)
334e98e3e1Schristos
344e98e3e1Schristoscat <<EOF
35*71f62182Schristos#line $LINENO "$0"
364b169a6bSchristos#include <stdlib.h>
374e98e3e1Schristos
384e98e3e1Schristosstatic INLINE const IDESC *
394e98e3e1Schristosextract (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
404e98e3e1Schristos	   ARGBUF *abuf, int fast_p)
414e98e3e1Schristos{
424e98e3e1Schristos  const IDESC *id = @cpu@_decode (current_cpu, pc, insn, insn, abuf);
434e98e3e1Schristos
444e98e3e1Schristos  @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
454e98e3e1Schristos  if (! fast_p)
464e98e3e1Schristos    {
474e98e3e1Schristos      int trace_p = PC_IN_TRACE_RANGE_P (current_cpu, pc);
484e98e3e1Schristos      int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
494e98e3e1Schristos      @cpu@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);
504e98e3e1Schristos    }
514e98e3e1Schristos  return id;
524e98e3e1Schristos}
534e98e3e1Schristos
544e98e3e1Schristosstatic INLINE SEM_PC
554e98e3e1Schristosexecute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p)
564e98e3e1Schristos{
574e98e3e1Schristos  SEM_PC vpc;
584e98e3e1Schristos
594e98e3e1Schristos  if (fast_p)
604e98e3e1Schristos    {
614e98e3e1Schristos#if ! WITH_SEM_SWITCH_FAST
624e98e3e1Schristos#if WITH_SCACHE
634e98e3e1Schristos      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);
644e98e3e1Schristos#else
654e98e3e1Schristos      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, &sc->argbuf);
664e98e3e1Schristos#endif
674e98e3e1Schristos#else
684e98e3e1Schristos      abort ();
694e98e3e1Schristos#endif /* WITH_SEM_SWITCH_FAST */
704e98e3e1Schristos    }
714e98e3e1Schristos  else
724e98e3e1Schristos    {
734e98e3e1Schristos#if ! WITH_SEM_SWITCH_FULL
744e98e3e1Schristos      ARGBUF *abuf = &sc->argbuf;
754e98e3e1Schristos      const IDESC *idesc = abuf->idesc;
764e98e3e1Schristos      const CGEN_INSN *idata = idesc->idata;
774e98e3e1Schristos#if WITH_SCACHE_PBB
784e98e3e1Schristos      int virtual_p = CGEN_INSN_ATTR_VALUE (idata, CGEN_INSN_VIRTUAL);
794e98e3e1Schristos#else
804e98e3e1Schristos      int virtual_p = 0;
814e98e3e1Schristos#endif
824e98e3e1Schristos      if (! virtual_p)
834e98e3e1Schristos	{
844e98e3e1Schristos	  /* FIXME: call x-before */
854e98e3e1Schristos	  if (ARGBUF_PROFILE_P (abuf))
864e98e3e1Schristos	    PROFILE_COUNT_INSN (current_cpu, abuf->addr, idesc->num);
874e98e3e1Schristos	  /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}.  */
884e98e3e1Schristos	  if (PROFILE_MODEL_P (current_cpu)
894e98e3e1Schristos	      && ARGBUF_PROFILE_P (abuf))
904e98e3e1Schristos	    @cpu@_model_insn_before (current_cpu, 1 /*first_p*/);
91212397c6Schristos	  CGEN_TRACE_INSN_INIT (current_cpu, abuf, 1);
92212397c6Schristos	  CGEN_TRACE_INSN (current_cpu, idata,
934e98e3e1Schristos		      (const struct argbuf *) abuf, abuf->addr);
944e98e3e1Schristos	}
954e98e3e1Schristos#if WITH_SCACHE
964e98e3e1Schristos      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc);
974e98e3e1Schristos#else
984e98e3e1Schristos      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, abuf);
994e98e3e1Schristos#endif
1004e98e3e1Schristos      if (! virtual_p)
1014e98e3e1Schristos	{
1024e98e3e1Schristos	  /* FIXME: call x-after */
1034e98e3e1Schristos	  if (PROFILE_MODEL_P (current_cpu)
1044e98e3e1Schristos	      && ARGBUF_PROFILE_P (abuf))
1054e98e3e1Schristos	    {
1064e98e3e1Schristos	      int cycles;
1074e98e3e1Schristos
1084e98e3e1Schristos	      cycles = (*idesc->timing->model_fn) (current_cpu, sc);
1094e98e3e1Schristos	      @cpu@_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
1104e98e3e1Schristos	    }
111212397c6Schristos	  CGEN_TRACE_INSN_FINI (current_cpu, abuf, 1);
1124e98e3e1Schristos	}
1134e98e3e1Schristos#else
1144e98e3e1Schristos      abort ();
1154e98e3e1Schristos#endif /* WITH_SEM_SWITCH_FULL */
1164e98e3e1Schristos    }
1174e98e3e1Schristos
1184e98e3e1Schristos  return vpc;
1194e98e3e1Schristos}
1204e98e3e1Schristos
1214e98e3e1SchristosEOF
1224e98e3e1Schristos
1234e98e3e1Schristos;;
1244e98e3e1Schristos
1254e98e3e1Schristosxinit)
1264e98e3e1Schristos
1274e98e3e1Schristos# Nothing needed.
1284e98e3e1Schristos
1294e98e3e1Schristos;;
1304e98e3e1Schristos
1314e98e3e1Schristosxextract-simple | xextract-scache)
1324e98e3e1Schristos
1334e98e3e1Schristoscat <<EOF
134*71f62182Schristos#line $LINENO "$0"
1354e98e3e1Schristos{
1364e98e3e1Schristos  CGEN_INSN_INT insn = GETIMEMUSI (current_cpu, vpc);
1374e98e3e1Schristos  extract (current_cpu, vpc, insn, SEM_ARGBUF (sc), FAST_P);
1384e98e3e1Schristos}
1394e98e3e1SchristosEOF
1404e98e3e1Schristos
1414e98e3e1Schristos;;
1424e98e3e1Schristos
1434e98e3e1Schristosxextract-pbb)
1444e98e3e1Schristos
1454e98e3e1Schristos# Inputs:  current_cpu, pc, sc, max_insns, FAST_P
1464e98e3e1Schristos# Outputs: sc, pc
1474e98e3e1Schristos# sc must be left pointing past the last created entry.
1484e98e3e1Schristos# pc must be left pointing past the last created entry.
1494e98e3e1Schristos# If the pbb is terminated by a cti insn, SET_CTI_VPC(sc) must be called
1504e98e3e1Schristos# to record the vpc of the cti insn.
1514e98e3e1Schristos# SET_INSN_COUNT(n) must be called to record number of real insns.
1524e98e3e1Schristos
1534e98e3e1Schristoscat <<EOF
154*71f62182Schristos#line $LINENO "$0"
1554e98e3e1Schristos{
1564e98e3e1Schristos  const IDESC *idesc;
1574e98e3e1Schristos  int icount = 0;
1584e98e3e1Schristos
1594e98e3e1Schristos  while (max_insns > 0)
1604e98e3e1Schristos    {
1614e98e3e1Schristos      USI insn = GETIMEMUSI (current_cpu, pc);
1624e98e3e1Schristos
1634e98e3e1Schristos      idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);
1644e98e3e1Schristos      ++sc;
1654e98e3e1Schristos      --max_insns;
1664e98e3e1Schristos      ++icount;
1674e98e3e1Schristos      pc += idesc->length;
1684e98e3e1Schristos
1694e98e3e1Schristos      if (IDESC_CTI_P (idesc))
1704e98e3e1Schristos        {
1714e98e3e1Schristos          SET_CTI_VPC (sc - 1);
1724e98e3e1Schristos          break;
1734e98e3e1Schristos        }
1744e98e3e1Schristos    }
1754e98e3e1Schristos
1764e98e3e1Schristos Finish:
1774e98e3e1Schristos  SET_INSN_COUNT (icount);
1784e98e3e1Schristos}
1794e98e3e1SchristosEOF
1804e98e3e1Schristos
1814e98e3e1Schristos;;
1824e98e3e1Schristos
1834e98e3e1Schristosxfull-exec-* | xfast-exec-*)
1844e98e3e1Schristos
1854e98e3e1Schristos# Inputs: current_cpu, vpc, FAST_P
1864e98e3e1Schristos# Outputs: vpc
1874e98e3e1Schristos
1884e98e3e1Schristoscat <<EOF
189*71f62182Schristos#line $LINENO "$0"
1904e98e3e1Schristos  /* Update cycle counter */
1914e98e3e1Schristos  SET_H_CSR (LM32_CSR_CC, GET_H_CSR (LM32_CSR_CC) + 1);
1924e98e3e1Schristos#if (! FAST_P && WITH_SEM_SWITCH_FULL) || (FAST_P && WITH_SEM_SWITCH_FAST)
1934e98e3e1Schristos#define DEFINE_SWITCH
1944e98e3e1Schristos#include "sem-switch.c"
1954e98e3e1Schristos#else
1964e98e3e1Schristos  vpc = execute (current_cpu, vpc, FAST_P);
1974e98e3e1Schristos#endif
1984e98e3e1SchristosEOF
1994e98e3e1Schristos
2004e98e3e1Schristos;;
2014e98e3e1Schristos
2024e98e3e1Schristos*)
2034e98e3e1Schristos  echo "Invalid argument to mainloop.in: $1" >&2
2044e98e3e1Schristos  exit 1
2054e98e3e1Schristos  ;;
2064e98e3e1Schristos
2074e98e3e1Schristosesac
208