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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [m32r/] [mloop.in] - Diff between revs 835 and 841

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

Rev 835 Rev 841
# Simulator main loop for m32r. -*- C -*-
# Simulator main loop for m32r. -*- C -*-
#
#
# Copyright (C) 1996, 1997, 1998, 2007, 2008, 2009, 2010
# Copyright (C) 1996, 1997, 1998, 2007, 2008, 2009, 2010
# Free Software Foundation, Inc.
# Free Software Foundation, Inc.
#
#
# 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, or if
# 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
# the slow (full featured) version is `simple', then the fast version can be
# one of scache/pbb.
# one of scache/pbb.
# A target can't provide more than this.
# A target can't provide more than this.
# However for illustration's sake this file provides examples of all.
# However for illustration's sake this file 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 *
extract16 (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
extract16 (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
           ARGBUF *abuf, int fast_p)
           ARGBUF *abuf, 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 const IDESC *
static INLINE const IDESC *
extract32 (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
extract32 (SIM_CPU *current_cpu, PCADDR pc, CGEN_INSN_INT insn,
           ARGBUF *abuf, int fast_p)
           ARGBUF *abuf, int fast_p)
{
{
  const IDESC *id = @cpu@_decode (current_cpu, pc, (USI) insn >> 16, insn, abuf);
  const IDESC *id = @cpu@_decode (current_cpu, pc, (USI) insn >> 16, 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;
  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;
      const CGEN_INSN *idata = idesc->idata;
      const CGEN_INSN *idata = idesc->idata;
#if WITH_SCACHE_PBB
#if WITH_SCACHE_PBB
      int virtual_p = CGEN_INSN_ATTR_VALUE (idata, CGEN_INSN_VIRTUAL);
      int virtual_p = CGEN_INSN_ATTR_VALUE (idata, 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, idata,
          TRACE_INSN (current_cpu, 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)
# Nothing needed.
# Nothing needed.
;;
;;
xextract-simple | xextract-scache)
xextract-simple | xextract-scache)
cat <
cat <
{
{
  if ((pc & 3) != 0)
  if ((pc & 3) != 0)
    {
    {
      /* This only occurs when single stepping.
      /* This only occurs when single stepping.
         The test is unnecessary otherwise, but the cost is teensy,
         The test is unnecessary otherwise, but the cost is teensy,
         compared with decoding/extraction.  */
         compared with decoding/extraction.  */
      UHI insn = GETIMEMUHI (current_cpu, pc);
      UHI insn = GETIMEMUHI (current_cpu, pc);
      extract16 (current_cpu, pc, insn & 0x7fff, sc, FAST_P);
      extract16 (current_cpu, pc, insn & 0x7fff, sc, FAST_P);
    }
    }
  else
  else
    {
    {
      USI insn = GETIMEMUSI (current_cpu, pc);
      USI insn = GETIMEMUSI (current_cpu, pc);
      if ((SI) insn < 0)
      if ((SI) insn < 0)
        {
        {
          extract32 (current_cpu, pc, insn, sc, FAST_P);
          extract32 (current_cpu, pc, insn, sc, FAST_P);
        }
        }
      else
      else
        {
        {
          extract16 (current_cpu, pc, insn >> 16, sc, FAST_P);
          extract16 (current_cpu, pc, insn >> 16, sc, FAST_P);
          extract16 (current_cpu, pc + 2, insn & 0x7fff, sc + 1, FAST_P);
          extract16 (current_cpu, pc + 2, insn & 0x7fff, sc + 1, FAST_P);
          /* The m32r doesn't support parallel execution.  */
          /* The m32r doesn't support parallel execution.  */
          if ((insn & 0x8000) != 0
          if ((insn & 0x8000) != 0
              && (insn & 0x7fff) != 0x7000) /* parallel nops are ok */
              && (insn & 0x7fff) != 0x7000) /* parallel nops are ok */
            sim_engine_illegal_insn (current_cpu, pc);
            sim_engine_illegal_insn (current_cpu, pc);
        }
        }
    }
    }
}
}
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;
  if ((pc & 3) != 0)
  if ((pc & 3) != 0)
    {
    {
      /* This only occurs when single stepping.
      /* This only occurs when single stepping.
         The test is unnecessary otherwise, but the cost is teensy,
         The test is unnecessary otherwise, but the cost is teensy,
         compared with decoding/extraction.  */
         compared with decoding/extraction.  */
      UHI insn = GETIMEMUHI (current_cpu, pc);
      UHI insn = GETIMEMUHI (current_cpu, pc);
      idesc = extract16 (current_cpu, pc, insn & 0x7fff, &sc->argbuf, FAST_P);
      idesc = extract16 (current_cpu, pc, insn & 0x7fff, &sc->argbuf, FAST_P);
      ++sc;
      ++sc;
      --max_insns;
      --max_insns;
      ++icount;
      ++icount;
      pc += 2;
      pc += 2;
      if (IDESC_CTI_P (idesc))
      if (IDESC_CTI_P (idesc))
        {
        {
          SET_CTI_VPC (sc - 1);
          SET_CTI_VPC (sc - 1);
          goto Finish;
          goto Finish;
        }
        }
    }
    }
  while (max_insns > 0)
  while (max_insns > 0)
    {
    {
      USI insn = GETIMEMUSI (current_cpu, pc);
      USI insn = GETIMEMUSI (current_cpu, pc);
      if ((SI) insn < 0)
      if ((SI) insn < 0)
        {
        {
          idesc = extract32 (current_cpu, pc, insn, &sc->argbuf, FAST_P);
          idesc = extract32 (current_cpu, pc, insn, &sc->argbuf, FAST_P);
          ++sc;
          ++sc;
          --max_insns;
          --max_insns;
          ++icount;
          ++icount;
          pc += 4;
          pc += 4;
          if (IDESC_CTI_P (idesc))
          if (IDESC_CTI_P (idesc))
            {
            {
              SET_CTI_VPC (sc - 1);
              SET_CTI_VPC (sc - 1);
              break;
              break;
            }
            }
        }
        }
      else
      else
        {
        {
          idesc = extract16 (current_cpu, pc, insn >> 16, &sc->argbuf, FAST_P);
          idesc = extract16 (current_cpu, pc, insn >> 16, &sc->argbuf, FAST_P);
          ++sc;
          ++sc;
          --max_insns;
          --max_insns;
          ++icount;
          ++icount;
          pc += 2;
          pc += 2;
          if (IDESC_CTI_P (idesc))
          if (IDESC_CTI_P (idesc))
            {
            {
              SET_CTI_VPC (sc - 1);
              SET_CTI_VPC (sc - 1);
              break;
              break;
            }
            }
          /* The m32r doesn't support parallel execution.  */
          /* The m32r doesn't support parallel execution.  */
          if ((insn & 0x8000) != 0)
          if ((insn & 0x8000) != 0)
            {
            {
              /* ??? Defer signalling to execution.  */
              /* ??? Defer signalling to execution.  */
              if ((insn & 0x7fff) != 0x7000) /* parallel nops are ok */
              if ((insn & 0x7fff) != 0x7000) /* parallel nops are ok */
                sim_engine_invalid_insn (current_cpu, pc - 2, 0);
                sim_engine_invalid_insn (current_cpu, pc - 2, 0);
              /* There's no point in processing parallel nops in fast mode.
              /* There's no point in processing parallel nops in fast mode.
                 We might as well do this test since we've already tested
                 We might as well do this test since we've already tested
                 that we have a parallel nop.  */
                 that we have a parallel nop.  */
              if (0 && FAST_P)
              if (0 && FAST_P)
                {
                {
                  pc += 2;
                  pc += 2;
                  continue;
                  continue;
                }
                }
            }
            }
          else
          else
            {
            {
              /* Non-parallel case.
              /* Non-parallel case.
                 While we're guaranteed that there's room to extract the
                 While we're guaranteed that there's room to extract the
                 insn, when single stepping we can't; the pbb must stop
                 insn, when single stepping we can't; the pbb must stop
                 after the first insn.  */
                 after the first insn.  */
              if (max_insns == 0)
              if (max_insns == 0)
                break;
                break;
            }
            }
          /* We're guaranteed that we can always process 16 bit insns in
          /* We're guaranteed that we can always process 16 bit insns in
             pairs.  */
             pairs.  */
          idesc = extract16 (current_cpu, pc, insn & 0x7fff, &sc->argbuf, FAST_P);
          idesc = extract16 (current_cpu, pc, insn & 0x7fff, &sc->argbuf, FAST_P);
          ++sc;
          ++sc;
          --max_insns;
          --max_insns;
          ++icount;
          ++icount;
          pc += 2;
          pc += 2;
          if (IDESC_CTI_P (idesc))
          if (IDESC_CTI_P (idesc))
            {
            {
              SET_CTI_VPC (sc - 1);
              SET_CTI_VPC (sc - 1);
              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, vpc, FAST_P
# Inputs: current_cpu, vpc, FAST_P
# Outputs: vpc
# Outputs: vpc
# vpc is the virtual program counter.
# vpc is the virtual program counter.
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.