OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [iq2000/] [mloop.in] - Diff between revs 227 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 227 Rev 816
# Simulator main loop for IQ2000. -*- C -*-
# Simulator main loop for IQ2000. -*- C -*-
# Copyright (C) 1998, 1999, 2007, 2008, 2009, 2010
# Copyright (C) 1998, 1999, 2007, 2008, 2009, 2010
# Free Software Foundation, Inc.
# Free Software Foundation, Inc.
# Contributed by Cygnus Solutions.
# Contributed by Cygnus Solutions.
#
#
# This file is part of the GNU Simulators.
# This file is part of the GNU Simulators.
#
#
# This program is free software; you can redistribute it and/or modify
# 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
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see .
# along with this program.  If not, see .
# Syntax:
# Syntax:
# /bin/sh mainloop.in command
# /bin/sh mainloop.in command
#
#
# Command is one of:
# Command is one of:
#
#
# init
# init
# support
# support
# extract-{simple,scache,pbb}
# extract-{simple,scache,pbb}
# {full,fast}-exec-{simple,scache,pbb}
# {full,fast}-exec-{simple,scache,pbb}
#
#
# A target need only provide a "full" version of one of 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.
# If the target wants it can also provide a fast version of same.
# It can't provide more than this, however for illustration's sake the IQ2000
# It can't provide more than this, however for illustration's sake the IQ2000
# port provides examples of all.
# port provides examples of all.
# ??? After a few more ports are done, revisit.
# ??? After a few more ports are done, revisit.
# Will eventually need to machine generate a lot of this.
# Will eventually need to machine generate a lot of this.
case "x$1" in
case "x$1" in
xsupport)
xsupport)
cat <
cat <
static INLINE const IDESC *
static INLINE const IDESC *
extract (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn, ARGBUF *abuf,
extract (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn, ARGBUF *abuf,
         int fast_p)
         int fast_p)
{
{
  const IDESC *id = @cpu@_decode (current_cpu, pc, insn, insn, abuf);
  const IDESC *id = @cpu@_decode (current_cpu, pc, insn, insn, abuf);
  @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
  @cpu@_fill_argbuf (current_cpu, abuf, id, pc, fast_p);
  if (! fast_p)
  if (! fast_p)
    {
    {
      int trace_p = PC_IN_TRACE_RANGE_P (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);
      int profile_p = PC_IN_PROFILE_RANGE_P (current_cpu, pc);
      @cpu@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);
      @cpu@_fill_argbuf_tp (current_cpu, abuf, trace_p, profile_p);
    }
    }
  return id;
  return id;
}
}
static INLINE SEM_PC
static INLINE SEM_PC
execute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p)
execute (SIM_CPU *current_cpu, SCACHE *sc, int fast_p)
{
{
  SEM_PC vpc;
  SEM_PC vpc;
  /* Force R0 to zero before every insn.  */
  /* Force R0 to zero before every insn.  */
  @cpu@_h_gr_set (current_cpu, 0, 0);
  @cpu@_h_gr_set (current_cpu, 0, 0);
  if (fast_p)
  if (fast_p)
    {
    {
#if ! WITH_SEM_SWITCH_FAST
#if ! WITH_SEM_SWITCH_FAST
#if WITH_SCACHE
#if WITH_SCACHE
      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);
      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, sc);
#else
#else
      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, &sc->argbuf);
      vpc = (*sc->argbuf.semantic.sem_fast) (current_cpu, &sc->argbuf);
#endif
#endif
#else
#else
      abort ();
      abort ();
#endif /* WITH_SEM_SWITCH_FAST */
#endif /* WITH_SEM_SWITCH_FAST */
    }
    }
  else
  else
    {
    {
#if ! WITH_SEM_SWITCH_FULL
#if ! WITH_SEM_SWITCH_FULL
      ARGBUF *abuf = &sc->argbuf;
      ARGBUF *abuf = &sc->argbuf;
      const IDESC *idesc = abuf->idesc;
      const IDESC *idesc = abuf->idesc;
#if WITH_SCACHE_PBB
#if WITH_SCACHE_PBB
      int virtual_p = CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_VIRTUAL);
      int virtual_p = CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_VIRTUAL);
#else
#else
      int virtual_p = 0;
      int virtual_p = 0;
#endif
#endif
      if (! virtual_p)
      if (! virtual_p)
        {
        {
          /* FIXME: call x-before */
          /* FIXME: call x-before */
          if (ARGBUF_PROFILE_P (abuf))
          if (ARGBUF_PROFILE_P (abuf))
            PROFILE_COUNT_INSN (current_cpu, abuf->addr, idesc->num);
            PROFILE_COUNT_INSN (current_cpu, abuf->addr, idesc->num);
          /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}.  */
          /* FIXME: Later make cover macros: PROFILE_INSN_{INIT,FINI}.  */
          if (PROFILE_MODEL_P (current_cpu)
          if (PROFILE_MODEL_P (current_cpu)
              && ARGBUF_PROFILE_P (abuf))
              && ARGBUF_PROFILE_P (abuf))
            @cpu@_model_insn_before (current_cpu, 1 /*first_p*/);
            @cpu@_model_insn_before (current_cpu, 1 /*first_p*/);
          TRACE_INSN_INIT (current_cpu, abuf, 1);
          TRACE_INSN_INIT (current_cpu, abuf, 1);
          TRACE_INSN (current_cpu, idesc->idata,
          TRACE_INSN (current_cpu, idesc->idata,
                      (const struct argbuf *) abuf, abuf->addr);
                      (const struct argbuf *) abuf, abuf->addr);
        }
        }
#if WITH_SCACHE
#if WITH_SCACHE
      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc);
      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, sc);
#else
#else
      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, abuf);
      vpc = (*sc->argbuf.semantic.sem_full) (current_cpu, abuf);
#endif
#endif
      if (! virtual_p)
      if (! virtual_p)
        {
        {
          /* FIXME: call x-after */
          /* FIXME: call x-after */
          if (PROFILE_MODEL_P (current_cpu)
          if (PROFILE_MODEL_P (current_cpu)
              && ARGBUF_PROFILE_P (abuf))
              && ARGBUF_PROFILE_P (abuf))
            {
            {
              int cycles;
              int cycles;
              cycles = (*idesc->timing->model_fn) (current_cpu, sc);
              cycles = (*idesc->timing->model_fn) (current_cpu, sc);
              @cpu@_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
              @cpu@_model_insn_after (current_cpu, 1 /*last_p*/, cycles);
            }
            }
          TRACE_INSN_FINI (current_cpu, abuf, 1);
          TRACE_INSN_FINI (current_cpu, abuf, 1);
        }
        }
#else
#else
      abort ();
      abort ();
#endif /* WITH_SEM_SWITCH_FULL */
#endif /* WITH_SEM_SWITCH_FULL */
    }
    }
  return vpc;
  return vpc;
}
}
EOF
EOF
;;
;;
xinit)
xinit)
;;
;;
xextract-simple | xextract-scache)
xextract-simple | xextract-scache)
# Inputs:  current_cpu, vpc, sc, FAST_P
# Inputs:  current_cpu, vpc, sc, FAST_P
# Outputs: sc filled in
# Outputs: sc filled in
cat <
cat <
{
{
  CGEN_INSN_INT insn = GETIMEMUSI (current_cpu, CPU2INSN(vpc));
  CGEN_INSN_INT insn = GETIMEMUSI (current_cpu, CPU2INSN(vpc));
  extract (current_cpu, vpc, insn, SEM_ARGBUF (sc), FAST_P);
  extract (current_cpu, vpc, insn, SEM_ARGBUF (sc), FAST_P);
  SEM_SKIP_COMPILE (current_cpu, sc, 1);
  SEM_SKIP_COMPILE (current_cpu, sc, 1);
}
}
EOF
EOF
;;
;;
xextract-pbb)
xextract-pbb)
# Inputs:  current_cpu, pc, sc, max_insns, FAST_P
# Inputs:  current_cpu, pc, sc, max_insns, FAST_P
# Outputs: sc, pc
# Outputs: sc, pc
# sc must be left pointing past the last created entry.
# sc must be left pointing past the last created entry.
# pc 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
# If the pbb is terminated by a cti insn, SET_CTI_VPC(sc) must be called
# to record the vpc of the cti insn.
# to record the vpc of the cti insn.
# SET_INSN_COUNT(n) must be called to record number of real insns.
# SET_INSN_COUNT(n) must be called to record number of real insns.
cat <
cat <
{
{
  const IDESC *idesc;
  const IDESC *idesc;
  int icount = 0;
  int icount = 0;
  /* Is the CTI instruction at the end of the PBB a likely branch?  */
  /* Is the CTI instruction at the end of the PBB a likely branch?  */
  int likely_cti;
  int likely_cti;
  while (max_insns > 0)
  while (max_insns > 0)
    {
    {
      USI insn = GETIMEMUSI (current_cpu, CPU2INSN(pc));
      USI insn = GETIMEMUSI (current_cpu, CPU2INSN(pc));
      idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);
      idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);
      SEM_SKIP_COMPILE (current_cpu, sc, 1);
      SEM_SKIP_COMPILE (current_cpu, sc, 1);
      ++sc;
      ++sc;
      --max_insns;
      --max_insns;
      ++icount;
      ++icount;
      pc += idesc->length;
      pc += idesc->length;
      if (IDESC_CTI_P (idesc))
      if (IDESC_CTI_P (idesc))
        {
        {
          /* Likely branches annul their delay slot if the branch is
          /* Likely branches annul their delay slot if the branch is
             not taken by using the (skip ..) rtx.  We'll rely on
             not taken by using the (skip ..) rtx.  We'll rely on
             that.  */
             that.  */
          likely_cti = (IDESC_SKIP_P (idesc));
          likely_cti = (IDESC_SKIP_P (idesc));
          SET_CTI_VPC (sc - 1);
          SET_CTI_VPC (sc - 1);
          if (CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_DELAY_SLOT))
          if (CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_DELAY_SLOT))
            {
            {
              USI insn = GETIMEMUSI (current_cpu, CPU2INSN(pc));
              USI insn = GETIMEMUSI (current_cpu, CPU2INSN(pc));
              idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);
              idesc = extract (current_cpu, pc, insn, &sc->argbuf, FAST_P);
              if (likely_cti && IDESC_CTI_P (idesc))
              if (likely_cti && IDESC_CTI_P (idesc))
                {
                {
                  /* malformed program */
                  /* malformed program */
                  sim_io_eprintf (CPU_STATE (current_cpu),
                  sim_io_eprintf (CPU_STATE (current_cpu),
                    "malformed program, \`%s' insn in branch likely delay slot\n",
                    "malformed program, \`%s' insn in branch likely delay slot\n",
                    CGEN_INSN_NAME (idesc->idata));
                    CGEN_INSN_NAME (idesc->idata));
                }
                }
              else
              else
                {
                {
                  ++sc;
                  ++sc;
                  --max_insns;
                  --max_insns;
                  ++icount;
                  ++icount;
                  pc += idesc->length;
                  pc += idesc->length;
                }
                }
            }
            }
          break;
          break;
        }
        }
    }
    }
 Finish:
 Finish:
  SET_INSN_COUNT (icount);
  SET_INSN_COUNT (icount);
}
}
EOF
EOF
;;
;;
xfull-exec-* | xfast-exec-*)
xfull-exec-* | xfast-exec-*)
# Inputs: current_cpu, sc, FAST_P
# Inputs: current_cpu, sc, FAST_P
# Outputs: vpc
# Outputs: vpc
# vpc contains the address of the next insn to execute
# vpc contains the address of the next insn to execute
cat <
cat <
{
{
#if (! FAST_P && WITH_SEM_SWITCH_FULL) || (FAST_P && WITH_SEM_SWITCH_FAST)
#if (! FAST_P && WITH_SEM_SWITCH_FULL) || (FAST_P && WITH_SEM_SWITCH_FAST)
#define DEFINE_SWITCH
#define DEFINE_SWITCH
#include "sem-switch.c"
#include "sem-switch.c"
#else
#else
  vpc = execute (current_cpu, vpc, FAST_P);
  vpc = execute (current_cpu, vpc, FAST_P);
#endif
#endif
}
}
EOF
EOF
;;
;;
*)
*)
  echo "Invalid argument to mainloop.in: $1" >&2
  echo "Invalid argument to mainloop.in: $1" >&2
  exit 1
  exit 1
  ;;
  ;;
esac
esac
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.