From 0f2811d1c539d123b69ffa0da3cd13febd10ef43 Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Thu, 17 Apr 1997 09:37:02 +0000 Subject: [PATCH] * 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 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 | 15 +++ sim/common/Make-common.in | 12 ++- sim/common/run.c | 74 ++++++-------- sim/common/sim-base.h | 171 +++++++++++++++++++++++++++++-- sim/common/sim-basics.h | 1 + sim/common/sim-load.c | 209 ++++++++++++++++++++++++++++++++++++++ sim/common/sim-trace.h | 112 ++++++++++++++++++++ 7 files changed, 542 insertions(+), 52 deletions(-) create mode 100644 sim/common/sim-load.c create mode 100644 sim/common/sim-trace.h diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index 7e0c76ab3a5..00aec4669c9 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,3 +1,18 @@ +Thu Apr 17 02:25:11 1997 Doug Evans + + * 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 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 * Make-common.in (INSTALL): Set to @INSTALL@. diff --git a/sim/common/Make-common.in b/sim/common/Make-common.in index ad6b081ee20..6c7ef6dbc2f 100644 --- a/sim/common/Make-common.in +++ b/sim/common/Make-common.in @@ -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) diff --git a/sim/common/run.c b/sim/common/run.c index 1240445c7a7..6740f69ce4a 100644 --- a/sim/common/run.c +++ b/sim/common/run.c @@ -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); diff --git a/sim/common/sim-base.h b/sim/common/sim-base.h index 150b0835df4..d221e04074e 100644 --- a/sim/common/sim-base.h +++ b/sim/common/sim-base.h @@ -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)); diff --git a/sim/common/sim-basics.h b/sim/common/sim-basics.h index f31305f5707..f3db0e0b88f 100644 --- a/sim/common/sim-basics.h +++ b/sim/common/sim-basics.h @@ -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 index 00000000000..0fc1b4c6cdf --- /dev/null +++ b/sim/common/sim-load.c @@ -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 +#else +#include +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#include +#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 index 00000000000..29d85bd0e14 --- /dev/null +++ b/sim/common/sim-trace.h @@ -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 */ -- 2.30.2