* Make-common.in (sim-options.o, sim-load.o): Add rules for.
authorDavid Edelsohn <dje.gcc@gmail.com>
Thu, 17 Apr 1997 09:37:02 +0000 (09:37 +0000)
committerDavid Edelsohn <dje.gcc@gmail.com>
Thu, 17 Apr 1997 09:37:02 +0000 (09:37 +0000)
(sim_main_headers): Add sim-trace.h.
* run.c (exec_bfd, target_byte_order): Delete.
(main): Pass -E <endian> to sim_open.  Delete code to load sections,
call sim_load instead.  Check return code of sim_create_inferior.
* sim-base.h (CURRENT_STATE): Define.
(sim_state_base): Make typedef.  New members options, prog_argv,
prog_bfd, text_{section,start,end}, start_addr, simcache_size,
mem_size, memory [+ corresponding access macros].
(sim_cpu_base): New typedef.
* sim-trace.h: New file.
* sim-basics.h: #include it.
* sim-load.c: New file.

sim/common/ChangeLog
sim/common/Make-common.in
sim/common/run.c
sim/common/sim-base.h
sim/common/sim-basics.h
sim/common/sim-load.c [new file with mode: 0644]
sim/common/sim-trace.h [new file with mode: 0644]

index 7e0c76ab3a56f7672076155fc841e80ec7ceb70a..00aec4669c95a4aa1c6411888e6f3ed6481f01be 100644 (file)
@@ -1,3 +1,18 @@
+Thu Apr 17 02:25:11 1997  Doug Evans  <dje@canuck.cygnus.com>
+
+       * Make-common.in (sim-options.o, sim-load.o): Add rules for.
+       (sim_main_headers): Add sim-trace.h.
+       * run.c (exec_bfd, target_byte_order): Delete.
+       (main): Pass -E <endian> to sim_open.  Delete code to load sections,
+       call sim_load instead.  Check return code of sim_create_inferior.
+       * sim-base.h (CURRENT_STATE): Define.
+       (sim_state_base): Make typedef.  New members options, prog_argv,
+       prog_bfd, text_{section,start,end}, start_addr, simcache_size,
+       mem_size, memory [+ corresponding access macros].
+       (sim_cpu_base): New typedef.
+       * sim-trace.h: New file.
+       * sim-basics.h: #include it.
+
 Tue Apr 15 15:10:13 1997  Ian Lance Taylor  <ian@cygnus.com>
 
        * Make-common.in (INSTALL): Set to @INSTALL@.
index ad6b081ee208bb1eeba2c6dbad5c7b073987986e..6c7ef6dbc2f9c9bf8ee6fa704ef10fa189da7034 100644 (file)
@@ -80,7 +80,9 @@ RANLIB = @RANLIB@
 MAKEINFO = makeinfo
 
 # Each simulator's Makefile.in defines one or more of these variables
-# to override our settings as necessary.
+# to override our settings as necessary.  There is no need to define these
+# in the simulator's Makefile.in if one is using the default value.  In fact
+# it's preferable not to.
 
 # List of object files, less common parts.
 SIM_OBJS =
@@ -174,6 +176,7 @@ sim_main_headers = \
        $(srcdir)/../common/sim-config.h \
        $(srcdir)/../common/sim-base.h \
        $(srcdir)/../common/sim-basics.h \
+       $(srcdir)/../common/sim-trace.h \
        tconfig.h
 
 sim-assert_h = $(srcdir)/../common/sim-assert.h
@@ -254,10 +257,17 @@ sim-io.c: $(srcdir)/../common/sim-io.c
        cat $(srcdir)/../common/$@ >> tmp-$@
        $(srcdir)/../../move-if-change tmp-$@ $@
 
+sim-options.o: $(srcdir)/../common/sim-options.c $(sim_headers) \
+         $(srcdir)/../common/sim-options.h
+       $(CC) -c $(srcdir)/../common/sim-options.c $(ALL_CFLAGS)
+
 sim-utils.o: $(srcdir)/../common/sim-utils.c $(sim_main_headers) \
        $(SIM_EXTRA_DEPS)
        $(CC) -c $(srcdir)/../common/sim-utils.c $(ALL_CFLAGS)
 
+sim-load.o: $(srcdir)/../common/sim-load.c
+       $(CC) -c $(srcdir)/../common/sim-load.c $(ALL_CFLAGS)
+
 
 install: install-common $(SIM_EXTRA_INSTALL)
 
index 1240445c7a7574ed7d87e7f88c16a279964f3df5..6740f69ce4a2340bbcb0f90cdec2f328a8146b69 100644 (file)
@@ -1,5 +1,5 @@
 /* run front end support for all the simulators.
-   Copyright (C) 1992, 1993 1994, 1995, 1996 Free Software Foundation, Inc.
+   Copyright (C) 1992, 93-96, 1997 Free Software Foundation, Inc.
 
 GNU CC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -52,10 +52,6 @@ static void usage PARAMS ((void));
 extern int optind;
 extern char *optarg;
 
-bfd *exec_bfd;
-
-int target_byte_order;
-
 extern host_callback default_callback;
 
 static char *myname;
@@ -74,13 +70,12 @@ main (ac, av)
      char **av;
 {
   bfd *abfd;
-  bfd_vma start_address;
   asection *s;
   int i;
   int verbose = 0;
   int trace = 0;
   char *name;
-  static char *no_args[2];
+  static char *no_args[4];
   char **sim_argv = &no_args[0];
   char **prog_args;
   enum sim_stop reason;
@@ -93,6 +88,8 @@ main (ac, av)
 
   /* The first element of sim_open's argv is the program name.  */
   no_args[0] = av[0];
+  no_args[1] = "-E";
+  no_args[2] = "set-later";
 
   /* FIXME: This is currently being rewritten to have each simulator
      do all argv processing.  */
@@ -108,8 +105,11 @@ main (ac, av)
        /* FIXME: Temporary hack.  */
        {
          int len = strlen (av[0]) + strlen (optarg);
-         char *argbuf = (char *) alloca (len + 2);
-         sprintf (argbuf, "%s %s", av[0], optarg);
+         char *argbuf = (char *) alloca (len + 2 + 50);
+         /* The desired endianness must be passed to sim_open.
+            The value for "set-later" is set when we know what it is.
+            -e support isn't yet part of the published interface.  */
+         sprintf (argbuf, "%s %s -E set-later", av[0], optarg);
          sim_argv = buildargv (argbuf);
        }
        break;
@@ -154,16 +154,21 @@ main (ac, av)
 
   ac -= optind;
   av += optind;
+  if (ac <= 0)
+    usage ();
 
   name = *av;
-  prog_args = av + 1;
+  prog_args = av;
 
   if (verbose)
     {
       printf ("%s %s\n", myname, name);
     }
 
-  exec_bfd = abfd = bfd_openr (name, 0);
+  sim_set_callbacks (NULL, &default_callback);
+  default_callback.init (&default_callback);
+
+  abfd = bfd_openr (name, 0);
   if (!abfd) 
     {
       fprintf (stderr, "%s: can't open %s: %s\n", 
@@ -178,43 +183,27 @@ main (ac, av)
       exit (1);
     }
 
-  /* This must be set before sim_open is called, because gdb assumes that
-     the simulator endianness is known immediately after the sim_open call.  */
-  target_byte_order = bfd_big_endian (abfd) ? 4321 : 1234;
-
-  sim_set_callbacks (NULL, &default_callback);
-  default_callback.init (&default_callback);
+  /* The endianness must be passed to sim_open because one may wish to
+     examine/set registers before calling sim_load [which is the other
+     place where one can determine endianness].  We previously passed the
+     endianness via global `target_byte_order' but that's not a clean
+     interface.  */
+  for (i = 1; sim_argv[i + 1] != NULL; ++i)
+    continue;
+  if (bfd_big_endian (abfd))
+    sim_argv[i] = "big";
+  else
+    sim_argv[i] = "little";
 
   /* Ensure that any run-time initialisation that needs to be
      performed by the simulator can occur. */
   sd = sim_open (SIM_OPEN_STANDALONE, sim_argv);
 
-  for (s = abfd->sections; s; s = s->next)
-    {
-      if (s->flags & SEC_LOAD)
-       {
-         unsigned char *buffer = (unsigned char *)malloc ((size_t)(bfd_section_size (abfd, s)));
-         if (buffer != NULL)
-           {
-             bfd_get_section_contents (abfd,
-                                       s,
-                                       buffer,
-                                       0,
-                                       bfd_section_size (abfd, s));
-             sim_write (sd, s->vma, buffer, bfd_section_size (abfd, s));
-             /* FIXME: How come we don't free buffer?  */
-           }
-         else
-           {
-             fprintf (stderr, "%s: failed to allocate section buffer: %s\n", 
-                      myname, bfd_errmsg (bfd_get_error ()));
-             exit (1);
-           }
-       }
-    }
+  if (sim_load (sd, name, abfd, 0) == SIM_RC_FAIL)
+    exit (1);
 
-  start_address = bfd_get_start_address (abfd);
-  sim_create_inferior (sd, start_address, prog_args, NULL);
+  if (sim_create_inferior (sd, prog_args, NULL) == SIM_RC_FAIL)
+    exit (1);
 
   if (trace)
     {
@@ -228,6 +217,7 @@ main (ac, av)
     {
       sim_resume (sd, 0, 0);
     }
+
   if (verbose)
     sim_info (sd, 0);
 
index 150b0835df46586e0385988941a1f7b019854528..d221e04074efcebef05f01a81e6c5cd96c438d1d 100644 (file)
@@ -38,22 +38,44 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 extern struct sim_state *current_state;
 #endif
 
-/* Simulator state pseudo base-class.
+/* The simulator may provide different (and faster) definition.  */
+#ifndef CURRENT_STATE
+#define CURRENT_STATE current_state
+#endif
+
+/* Simulator state pseudo baseclass.
    Each simulator is required to have a sim-main.h file that includes
    sim-basics.h and defines struct sim_state to be:
 
    struct sim_state {
-     struct sim_state_base base;
+     sim_cpu cpu;
+   #define STATE_CPU(sd,n) (&(sd)->cpu)
      ... simulator specific members ...
+     sim_state_base base;
    };
-   */
 
-struct sim_state_base {
-  /* Marker for those wanting to do sanity checks.  */
-  int magic;
-#define SIM_MAGIC_NUMBER 0x4242
-#define STATE_MAGIC(sd) ((sd)->base.magic)
+   for a single processor or
+
+   struct sim_state {
+     sim_cpu cpu[MAX_CPUS]; -- could be also be array of pointers
+   #define STATE_CPU(sd,n) (&(sd)->cpu[n])
+     ... simulator specific members ...
+     sim_state_base base;
+   };
+
+   for multiprocessors.
+   Note that `base' appears last.  This makes `base.magic' appear last
+   in the entire struct and helps catch miscompilation errors.
+
+   sim_cpu is defined to be:
 
+   typedef struct {
+      ... simulator specific members ...
+      sim_cpu_base base;
+   } sim_cpu;
+   */
+
+typedef struct {
   /* Simulator's argv[0].  */
   const char *my_name;
 #define STATE_MY_NAME(sd) ((sd)->base.my_name)
@@ -71,7 +93,138 @@ struct sim_state_base {
   struct sim_config config;
 #define STATE_CONFIG(sd) ((sd)->base.config)
 #endif
-};
+
+  /* Supported options.  */
+  struct option_list *options;
+#define STATE_OPTIONS(sd) ((sd)->base.options)
+
+  /* Non-zero if -v specified.  */
+  int verbose_p;
+#define STATE_VERBOSE_P(sd) ((sd)->base.verbose_p)
+
+  /* In standalone simulator, this is the program's arguments passed
+     on the command line.  */
+  char **prog_argv;
+#define STATE_PROG_ARGV(sd) ((sd)->base.prog_argv)
+
+  /* The program's bfd.  */
+  struct _bfd *prog_bfd;
+#define STATE_PROG_BFD(sd) ((sd)->base.prog_bfd)
+
+  /* The program's text section.  */
+  struct sec *text_section;
+  /* Starting and ending text section addresses from the bfd.  */
+  SIM_ADDR text_start, text_end;
+#define STATE_TEXT_SECTION(sd) ((sd)->base.text_section)
+#define STATE_TEXT_START(sd) ((sd)->base.text_start)
+#define STATE_TEXT_END(sd) ((sd)->base.text_end)
+
+  /* Start address, set when the program is loaded from the bfd.  */
+  SIM_ADDR start_addr;
+#define STATE_START_ADDR(sd) ((sd)->base.start_addr)
+
+  /* Size of the simulator's cache, if any.
+     This is not the target's cache.  It is the cache the simulator uses
+     to process instructions.  */
+  unsigned int simcache_size;
+#define STATE_SIMCACHE_SIZE(sd) ((sd)->base.simcache_size)
+
+  /* FIXME: Move to top level sim_state struct (as some struct)?  */
+#ifdef SIM_HAVE_FLATMEM
+  unsigned int mem_size;
+#define STATE_MEM_SIZE(sd) ((sd)->base.mem_size)
+  unsigned char *memory;
+#define STATE_MEMORY(sd) ((sd)->base.memory)
+#endif
+
+  /* Marker for those wanting to do sanity checks.
+     This should remain the last member of this struct to help catch
+     miscompilation errors.  */
+  int magic;
+#define SIM_MAGIC_NUMBER 0x4242
+#define STATE_MAGIC(sd) ((sd)->base.magic)
+} sim_state_base;
+
+/* Pseudo baseclass for each cpu.  */
+
+typedef struct {
+  /* Backlink to main state struct.  */
+  SIM_DESC sd;
+
+  /* Maximum number of traceable entities.  */
+#ifndef MAX_TRACE_VALUES
+#define MAX_TRACE_VALUES 12
+#endif
+
+  /* Boolean array of specified tracing flags.  */
+  /* ??? It's not clear that using an array vs a bit mask is faster.
+     Consider the case where one wants to test whether any of several bits
+     are set.  */
+  char trace_flags[MAX_TRACE_VALUES];
+#define CPU_TRACE_FLAGS(cpu) ((cpu)->base.trace_flags)
+  /* Standard values.  */
+#define TRACE_INSN_IDX 0
+#define TRACE_DECODE_IDX 1
+#define TRACE_EXTRACT_IDX 2
+#define TRACE_LINENUM_IDX 3
+#define TRACE_MEMORY_IDX 4
+#define TRACE_MODEL_IDX 5
+#define TRACE_ALU_IDX 6
+#define TRACE_NEXT_IDX 8 /* simulator specific trace bits begin here */
+
+  /* Tracing output goes to this or stdout if NULL.
+     We can't store `stdout' here as stdout goes through a callback.  */
+  FILE *trace_file;
+
+  /* Maximum number of debuggable entities.
+     This debugging is not intended for normal use.
+     It is only enabled when the simulator is configured with --with-debug
+     which shouldn't normally be specified.  */
+#ifndef MAX_DEBUG_VALUES
+#define MAX_DEBUG_VALUES 4
+#endif
+
+  /* Boolean array of specified debugging flags.  */
+  char debug_flags[MAX_DEBUG_VALUES];
+#define CPU_DEBUG_FLAGS(cpu) ((cpu)->base.debug_flags)
+  /* Standard values.  */
+#define DEBUG_INSN_IDX 0
+#define DEBUG_NEXT_IDX 2 /* simulator specific debug bits begin here */
+
+  /* Debugging output goes to this or stderr if NULL.
+     We can't store `stderr' here as stderr goes through a callback.  */
+  FILE *debug_file;
+
+#ifdef SIM_HAVE_PROFILE
+  /* Maximum number of profilable entities.  */
+#ifndef MAX_PROFILE_VALUES
+#define MAX_PROFILE_VALUES 8
+#endif
+
+  /* Boolean array of specified profiling flags.  */
+  char profile_flags[MAX_PROFILE_VALUES];
+#define CPU_PROFILE_FLAGS(cpu) ((cpu)->base.profile_flags)
+  /* Standard masks.  */
+#define PROFILE_INSN_MASK 0
+#define PROFILE_MEMORY_MASK 1
+#define PROFILE_MODEL_MASK 2
+#define PROFILE_SIMCACHE_MASK 3
+#define PROFILE_NEXT_MASK 6 /* simulator specific profile bits begin here */
+
+  /* PC profiling attempts to determine function usage by sampling the PC
+     every so many instructions.  */
+#ifdef SIM_HAVE_PROFILE_PC
+  unsigned int profile_pc_freq;
+#define STATE_PROFILE_PC_FREQ(sd) ((sd)->base.profile_pc_freq)
+  unsigned int profile_pc_size;
+#define STATE_PROFILE_PC_SIZE(sd) ((sd)->base.profile_pc_size)
+#endif
+
+  /* Profile output goes to this or stdout if NULL.
+     We can't store `stderr' here as stdout goes through a callback.  */
+  FILE *profile_file;
+#endif /* SIM_HAVE_PROFILE */
+} sim_cpu_base;
 
 /* Functions for allocating/freeing a sim_state.  */
 SIM_DESC sim_state_alloc PARAMS ((void));
index f31305f5707c3f7d2897c8841d9404b84dc10128..f3db0e0b88f4eb268af048d4a4bf2093e331efb5 100644 (file)
@@ -107,6 +107,7 @@ typedef enum _attach_type {
 #include "sim-config.h"
 
 #include "sim-base.h"
+#include "sim-trace.h"
 
 #include "sim-inline.h"
 
diff --git a/sim/common/sim-load.c b/sim/common/sim-load.c
new file mode 100644 (file)
index 0000000..0fc1b4c
--- /dev/null
@@ -0,0 +1,209 @@
+/* Utility to load a file into the simulator.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+
+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 2, 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, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "config.h"
+#ifdef __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <time.h>
+#include "ansidecl.h"
+#include "bfd.h"
+#include "callback.h"
+#include "remote-sim.h"
+
+static void eprintf PARAMS ((host_callback *, const char *, ...));
+static void xprintf PARAMS ((host_callback *, const char *, ...));
+static void report_transfer_performance
+  PARAMS ((host_callback *, unsigned long, time_t, time_t));
+static void xprintf_bfd_vma PARAMS ((host_callback *, bfd_vma));
+
+/* Load program PROG into the simulator.
+   If PROG_BFD is non-NULL, the file has already been opened.
+   If VERBOSE_P is non-zero statistics are printed of each loaded section
+   and the transfer rate (for consistency with gdb).
+   If this fails an error message is printed and NULL is returned.
+   If it succeeds the bfd is returned.  */
+
+/* FIXME: Where can we put a prototype for this?  */
+
+bfd *
+sim_load_file (sd, myname, callback, prog, prog_bfd, verbose_p)
+     SIM_DESC sd;
+     char *myname;
+     host_callback *callback;
+     char *prog;
+     bfd *prog_bfd;
+{
+  asection *s;
+  /* Record separately as we don't want to close PROG_BFD if it was passed.  */
+  bfd *result_bfd;
+  time_t start_time, end_time; /* Start and end times of download */
+  unsigned long data_count = 0;        /* Number of bytes transferred to memory */
+
+  if (prog_bfd != NULL)
+    result_bfd = prog_bfd;
+  else
+    {
+      result_bfd = bfd_openr (prog, 0);
+      if (result_bfd == NULL)
+       {
+         eprintf (callback, "%s: can't open \"%s\": %s\n", 
+                  myname, prog, bfd_errmsg (bfd_get_error ()));
+         return NULL;
+       }
+    }
+
+  if (!bfd_check_format (result_bfd, bfd_object)) 
+    {
+      eprintf (callback, "%s: \"%s\" is not an object file: %s\n",
+              myname, prog, bfd_errmsg (bfd_get_error ()));
+      /* Only close if we opened it.  */
+      if (prog_bfd == NULL)
+       bfd_close (result_bfd);
+      return NULL;
+    }
+
+  if (verbose_p)
+    start_time = time (NULL);
+
+  for (s = result_bfd->sections; s; s = s->next) 
+    {
+      if (s->flags & SEC_LOAD) 
+       {
+         bfd_size_type size;
+
+         size = bfd_get_section_size_before_reloc (s);
+         if (size > 0)
+           {
+             char *buffer;
+             bfd_vma lma;
+
+             buffer = malloc (size);
+             if (buffer == NULL)
+               {
+                 eprintf (callback,
+                          "%s: insufficient memory to load \"%s\"\n",
+                          myname, prog);
+                 /* Only close if we opened it.  */
+                 if (prog_bfd == NULL)
+                   bfd_close (result_bfd);
+                 return NULL;
+               }
+             /* Before you change this to bfd_section_lma, make sure
+                the arm-pe simulator still works.  */
+             lma = bfd_section_vma (result_bfd, s);
+             if (verbose_p)
+               {
+                 xprintf (callback, "Loading section %s, size 0x%lx lma ",
+                          bfd_get_section_name (result_bfd, s),
+                          (unsigned long) size);
+                 xprintf_bfd_vma (callback, lma);
+                 xprintf (callback, "\n");
+               }
+             data_count += size;
+             bfd_get_section_contents (result_bfd, s, buffer, 0, size);
+             sim_write (sd, lma, buffer, size);
+             free (buffer);
+           }
+       }
+    }
+
+  if (verbose_p)
+    {
+      end_time = time (NULL);
+      xprintf (callback, "Start address ");
+      xprintf_bfd_vma (callback, bfd_get_start_address (result_bfd));
+      xprintf (callback, "\n");
+      report_transfer_performance (callback, data_count, start_time, end_time);
+    }
+
+  return result_bfd;
+}
+
+static void
+xprintf VPARAMS ((host_callback *callback, const char *fmt, ...))
+{
+#ifndef __STDC__
+  host_callback *callback;
+  char *fmt;
+#endif
+  va_list ap;
+
+  VA_START (ap, fmt);
+#ifndef __STDC__
+  callback = va_arg (ap, host_callback *);
+  fmt = va_arg (ap, char *);
+#endif
+
+  (*callback->vprintf_filtered) (callback, fmt, ap);
+
+  va_end (ap);
+}
+
+static void
+eprintf VPARAMS ((host_callback *callback, const char *fmt, ...))
+{
+#ifndef __STDC__
+  host_callback *callback;
+  char *fmt;
+#endif
+  va_list ap;
+
+  VA_START (ap, fmt);
+#ifndef __STDC__
+  callback = va_arg (ap, host_callback *);
+  fmt = va_arg (ap, char *);
+#endif
+
+  (*callback->evprintf_filtered) (callback, fmt, ap);
+
+  va_end (ap);
+}
+
+/* Report how fast the transfer went. */
+
+static void
+report_transfer_performance (callback, data_count, start_time, end_time)
+     host_callback *callback;
+     unsigned long data_count;
+     time_t start_time, end_time;
+{
+  xprintf (callback, "Transfer rate: ");
+  if (end_time != start_time)
+    xprintf (callback, "%ld bits/sec",
+            (data_count * 8) / (end_time - start_time));
+  else
+    xprintf (callback, "%ld bits in <1 sec", (data_count * 8));
+  xprintf (callback, ".\n");
+}
+
+/* Print a bfd_vma.
+   This is intended to handle the vagaries of 32 vs 64 bits, etc.  */
+
+static void
+xprintf_bfd_vma (callback, vma)
+     host_callback *callback;
+     bfd_vma vma;
+{
+  /* FIXME: for now */
+  xprintf (callback, "0x%lx", (unsigned long) vma);
+}
diff --git a/sim/common/sim-trace.h b/sim/common/sim-trace.h
new file mode 100644 (file)
index 0000000..29d85bd
--- /dev/null
@@ -0,0 +1,112 @@
+/* Simulator tracing/debugging support.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.
+
+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 2, 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, write to the Free Software Foundation, Inc.,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* This file is meant to be included by sim-basics.h.  */
+
+#ifndef SIM_TRACE_H
+#define SIM_TRACE_H
+
+/* Tracing support.  */
+
+#ifdef MAX_CPUS
+
+/* Return non-zero if tracing of IDX is enabled for CPU.  */
+#define TRACE_P(cpu,idx) \
+((WITH_TRACE & (1 << (idx))) != 0 \
+ && CPU_TRACE_FLAGS (cpu)[idx] != 0)
+
+/* Non-zero if "--trace-insn" specified for CPU.  */
+#define TRACE_INSN_P(cpu) TRACE_P (cpu, TRACE_INSN_IDX)
+
+#define TRACE_PRINTF(cpu, idx, args) \
+do { \
+  if ((WITH_TRACE & (1 << (idx))) != 0 \
+      && CPU_TRACE_FLAGS (cpu)[idx] != 0) \
+    trace_printf args; \
+} while (0)
+
+#else
+
+/* Fetch current tracing flags.  */
+#define CURRENT_TRACE_FLAGS CPU_TRACE_FLAGS (& CURRENT_STATE->cpu)
+
+/* Return non-zero if tracing of IDX is enabled.  */
+#define TRACE_P(idx) \
+((WITH_TRACE & (1 << (idx))) != 0 \
+ && CURRENT_TRACE_FLAGS[idx] != 0)
+
+/* Non-zero if "--trace-insn" specified.  */
+#define TRACE_INSN_P TRACE_P (TRACE_INSN_IDX)
+
+#define TRACE_PRINTF(idx, args) \
+do { \
+  if ((WITH_TRACE & (1 << (idx))) != 0 \
+      && CURRENT_TRACE_FLAGS[idx] != 0) \
+    trace_printf args; \
+} while (0)
+
+#endif /* MAX_CPUS */
+
+extern void trace_printf PARAMS ((char *, ...));
+
+/* Debug support.  */
+
+#ifdef MAX_CPUS
+
+/* Return non-zero if debugging of IDX for CPU is enabled.  */
+#define DEBUG_P(cpu, idx) \
+((WITH_DEBUG & (1 << (idx))) != 0 \
+ && CPU_DEBUG_FLAGS (cpu)[idx] != 0)
+
+/* Non-zero if "--debug-insn" specified.  */
+#define DEBUG_INSN_P(cpu) DEBUG_P (cpu, DEBUG_INSN_IDX)
+
+#define DEBUG_PRINTF(cpu, idx, args) \
+do { \
+  if ((WITH_DEBUG & (1 << (idx))) != 0 \
+      && CPU_DEBUG_FLAGS (cpu)[idx] != 0) \
+    debug_printf args; \
+} while (0)
+
+#else
+
+/* Fetch current debugging flags.  */
+#define CURRENT_DEBUG_FLAGS CPU_DEBUG_FLAGS (& CURRENT_STATE->cpu)
+
+/* Return non-zero if debugging of IDX is enabled.  */
+#define DEBUG_P(idx) \
+((WITH_DEBUG & (1 << (idx))) != 0 \
+ && CURRENT_DEBUG_FLAGS[idx] != 0)
+
+/* Non-zero if "--debug-insn" specified.  */
+#define DEBUG_INSN_P DEBUG_P (DEBUG_INSN_IDX)
+
+#define DEBUG_PRINTF(idx, args) \
+do { \
+  if ((WITH_DEBUG & (1 << (idx))) != 0 \
+      && CURRENT_DEBUG_FLAGS[idx] != 0) \
+    debug_printf args; \
+} while (0)
+
+#endif /* MAX_CPUS */
+
+extern void debug_printf PARAMS ((char *, ...));
+
+#endif /* SIM_TRACE_H */