* cgen-defs.h: New file, old cgen-sim.h.

* cgen-sim.h: Simple header that includes others.
	* sim-arange.c: New file.
	* sim-arange.h: New file.
	* sim-basics.h: Include it.
	* Make-common.in (SIM_NEW_COMMON_OBJS): Add sim-arange.o.
	(sim-arange.o): Add rule for.
	* sim-cpu.h (sim_cpu_msg_prefix): Add prototype.
	(sim_io_eprintf_cpu): Add prototype.
	* sim-inline.h (HAVE_INLINE): Define if GNUC.
	(INLINE2): New macro.
	(EXTERN_INLINE): New macro.
	* sim-module.c (sim_post_argv_init): Initialize cpu backlink
	before calling module init fns.
	* sim-profile.h (OPTION_PROFILE_*): Move into enum.
	(profile_init): New function.
	(profile_options): New option --profile-range.
	(profile_option_handler): Handle --profile-range.
	(profile_print_insn): Qualify address range specific section titles.
	(profile_print_addr_ranges): New function.
	(profile_info): Print address ranges if specified.
	(profile_install): Set profile_init init fn.
	* sim-profile.h (PROFILE_DATA): New member `range'.
	* sim-trace.c (trace_init): New function.
	(trace_options): New option --trace-range.
	(trace_option_handler): Handle --trace-range.
	(trace_install): Set trace_init init fn.
	* sim-trace.h (TRACE_DATA): New member `range'.
	* sim-utils.c (sim_cpu_msg_prefix): New function.
	(sim_io_eprintf_cpu): New function.
	* cgen-engine.h (PC_IN_TRACE_RANGE_P): New macro.
	(PC_IN_PROFILE_RANGE_P): New macro.
	* cgen-trace.c (trace_insn_init): Set current_insn to NULL.
	(trace_insn_fini): New arg abuf.  All callers updated.
	Exit early if trace_insn not called.  Check ARGBUF_PROFILE_P before
	printing cycle counts.
	* cgen-trace.h (trace_insn_fini): Update prototype.
	(TRACE_RESULT_P): New macro.
	(TRACE_INSN_INIT,TRACE_INSN_FINI): New arg abuf.  All callers updated.
	(TRACE_INSN): Check ARGBUF_TRACE_P.
	(TRACE_EXTRACT,TRACE_RESULT): New arg abuf.  All callers updated.
	* cgen-types.h (SIM_INLINE): Delete.
	(SIM_HAVE_MODEL,SIM_HAVE_ADDR_RANGE): Define.
	* cgen-utils.c: Don't include cgen-engine.h
	* genmloop.sh (@cpu@_fill_argbuf): New function.
	(@cpu@_fill_argbuf_tp): New function.
	(@cpu@_emit_before,@cpu@_emit_after): New functions.
	(@cpu@_pbb_begin): Prefix cti_sc,insn_count with '_'.
	(SET_CTI_VPC,SET_INSN_COUNT): Update.
	(@cpu@_pbb_before): Check ARGBUF_PROFILE_P before calling
	doing profiling.  Update call to TRACE_INSN_INIT,TRACE_INSN_FINI.
	(@cpu@_pbb_after): Check ARGBUF_PROFILE_P before calling
	doing profiling. Update call to TRACE_INSN_FINI.
This commit is contained in:
Doug Evans 1998-12-05 07:56:13 +00:00
parent e8116eca81
commit b61e2e146a
6 changed files with 554 additions and 132 deletions

View File

@ -44,6 +44,7 @@ acconfig.h
aclocal.m4
callback.c
cgen-cpu.h
cgen-defs.h
cgen-engine.h
cgen-mem.h
cgen-ops.h

View File

@ -1,9 +1,60 @@
1998-12-04 Doug Evans <devans@casey.cygnus.com>
* sim-memopt.c (sim_memory_uninstall): Result type is `void'.
* cgen-defs.h: New file, old cgen-sim.h.
* cgen-sim.h: Simple header that includes others.
* sim-arange.c: New file.
* sim-arange.h: New file.
* sim-basics.h: Include it.
* Make-common.in (SIM_NEW_COMMON_OBJS): Add sim-arange.o.
(sim-arange.o): Add rule for.
* sim-cpu.h (sim_cpu_msg_prefix): Add prototype.
(sim_io_eprintf_cpu): Add prototype.
* sim-inline.h (HAVE_INLINE): Define if GNUC.
(INLINE2): New macro.
(EXTERN_INLINE): New macro.
* sim-module.c (sim_post_argv_init): Initialize cpu backlink
before calling module init fns.
* sim-profile.h (OPTION_PROFILE_*): Move into enum.
(profile_init): New function.
(profile_options): New option --profile-range.
(profile_option_handler): Handle --profile-range.
(profile_print_insn): Qualify address range specific section titles.
(profile_print_addr_ranges): New function.
(profile_info): Print address ranges if specified.
(profile_install): Set profile_init init fn.
* sim-profile.h (PROFILE_DATA): New member `range'.
* sim-trace.c (trace_init): New function.
(trace_options): New option --trace-range.
(trace_option_handler): Handle --trace-range.
(trace_install): Set trace_init init fn.
* sim-trace.h (TRACE_DATA): New member `range'.
* sim-utils.c (sim_cpu_msg_prefix): New function.
(sim_io_eprintf_cpu): New function.
* cgen-engine.h (PC_IN_TRACE_RANGE_P): New macro.
(PC_IN_PROFILE_RANGE_P): New macro.
* cgen-trace.c (trace_insn_init): Set current_insn to NULL.
(trace_insn_fini): New arg abuf. All callers updated.
Exit early if trace_insn not called. Check ARGBUF_PROFILE_P before
printing cycle counts.
* cgen-trace.h (trace_insn_fini): Update prototype.
(TRACE_RESULT_P): New macro.
(TRACE_INSN_INIT,TRACE_INSN_FINI): New arg abuf. All callers updated.
(TRACE_INSN): Check ARGBUF_TRACE_P.
(TRACE_EXTRACT,TRACE_RESULT): New arg abuf. All callers updated.
* cgen-types.h (SIM_INLINE): Delete.
(SIM_HAVE_MODEL,SIM_HAVE_ADDR_RANGE): Define.
* cgen-utils.c: Don't include cgen-engine.h
* genmloop.sh (@cpu@_fill_argbuf): New function.
(@cpu@_fill_argbuf_tp): New function.
(@cpu@_emit_before,@cpu@_emit_after): New functions.
(@cpu@_pbb_begin): Prefix cti_sc,insn_count with '_'.
(SET_CTI_VPC,SET_INSN_COUNT): Update.
(@cpu@_pbb_before): Check ARGBUF_PROFILE_P before calling
doing profiling. Update call to TRACE_INSN_INIT,TRACE_INSN_FINI.
(@cpu@_pbb_after): Check ARGBUF_PROFILE_P before calling
doing profiling. Update call to TRACE_INSN_FINI.
* sim-memopt.c (sim_memory_uninstall): Result type is `void'.
1998-12-03 Frank Ch. Eigler <fche@cygnus.com>

View File

@ -154,6 +154,7 @@ SIM_COMMON_HW_OBJS = \
sim-hw.o \
SIM_NEW_COMMON_OBJS = \
sim-arange.o \
sim-bits.o \
sim-break.o \
sim-config.o \
@ -176,11 +177,11 @@ SIM_NEW_COMMON_OBJS = \
$(SIM_HW_OBJS) \
CGEN_INCLUDE_DEPS = \
$(srccom)/cgen-types.h \
$(srccom)/cgen-sim.h \
$(srccom)/cgen-scache.h \
$(srccom)/cgen-cpu.h \
$(srccom)/cgen-scache.h \
$(srccom)/cgen-sim.h \
$(srccom)/cgen-trace.h \
$(srccom)/cgen-types.h \
$(srcdir)/../../include/opcode/cgen.h
## End COMMON_PRE_CONFIG_FRAG
@ -310,6 +311,7 @@ sim_main_headers = \
sim-assert_h = $(srccom)/sim-assert.h
sim-endian_h = $(srccom)/sim-endian.h
sim-n-endian_h = $(srccom)/sim-n-endian.h
sim-arange_h = $(srccom)/sim-arange.h
sim-bits_h = $(srccom)/sim-bits.h
sim-config_h = $(srccom)/sim-config.h
sim-n-bits_h = $(srccom)/sim-n-bits.h
@ -357,6 +359,9 @@ sim-abort.o: $(srccom)/sim-abort.c \
$(SIM_EXTRA_DEPS)
$(CC) -c $(srccom)/sim-abort.c $(ALL_CFLAGS)
sim-arange.o: $(srccom)/sim-arange.c $(sim-arange_h) $(SIM_EXTRA_DEPS)
$(CC) -c $(srccom)/sim-arange.c $(ALL_CFLAGS)
sim-bits.o: $(srccom)/sim-bits.c $(sim-bits_h) $(sim-n-bits_h) \
$(SIM_EXTRA_DEPS)
$(CC) -c $(srccom)/sim-bits.c $(ALL_CFLAGS)
@ -563,7 +568,7 @@ cgen-trace.o: $(srccom)/cgen-trace.c $(sim_main_headers)
$(CC) -c $(srccom)/cgen-trace.c $(ALL_CFLAGS)
cgen-utils.o: $(srccom)/cgen-utils.c $(sim_main_headers) \
$(srccom)/cgen-mem.h $(srccom)/cgen-ops.h
$(srccom)/cgen-mem.h $(srccom)/cgen-ops.h $(srccom)/cgen-engine.h
$(CC) -c $(srccom)/cgen-utils.c $(ALL_CFLAGS)
# Support targets.
@ -650,6 +655,7 @@ CGEN_MAIN_SCM = $(srccgen)/cos.scm $(srccgen)/utils.scm \
$(srccgen)/ifield.scm $(srccgen)/iformat.scm \
$(srccgen)/operand.scm $(srccgen)/insn.scm \
$(srccgen)/rtl.scm $(srccgen)/sim.scm
CGEN_ARCH_SCM = $(srccgen)/sim-arch.scm
CGEN_CPU_SCM = $(srccgen)/sim-cpu.scm $(srccgen)/sim-model.scm
CGEN_DECODE_SCM = $(srccgen)/sim-decode.scm

66
sim/common/cgen-trace.h Normal file
View File

@ -0,0 +1,66 @@
/* Simulator tracing support for Cpu tools GENerated simulators.
Copyright (C) 1996, 1997, 1998 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. */
#ifndef CGEN_TRACE_H
#define CGEN_TRACE_H
void trace_insn_init (SIM_CPU *, int);
void trace_insn_fini (SIM_CPU *, const struct argbuf *, int);
void trace_insn (SIM_CPU *, const struct cgen_insn *,
const struct argbuf *, PCADDR);
void trace_extract (SIM_CPU *, PCADDR, char *, ...);
void trace_result (SIM_CPU *, char *, int, ...);
void cgen_trace_printf (SIM_CPU *, char *fmt, ...);
/* Trace instruction results. */
#define TRACE_RESULT_P(cpu, abuf) (TRACE_INSN_P (cpu) && ARGBUF_TRACE_P (abuf))
#define TRACE_INSN_INIT(cpu, abuf, first_p) \
do { \
if (TRACE_INSN_P (cpu)) \
trace_insn_init ((cpu), (first_p)); \
} while (0)
#define TRACE_INSN_FINI(cpu, abuf, last_p) \
do { \
if (TRACE_INSN_P (cpu)) \
trace_insn_fini ((cpu), (abuf), (last_p)); \
} while (0)
#define TRACE_PRINTF(cpu, what, args) \
do { \
if (TRACE_P ((cpu), (what))) \
cgen_trace_printf args ; \
} while (0)
#define TRACE_INSN(cpu, opcode, abuf, pc) \
do { \
if (TRACE_INSN_P (cpu) && ARGBUF_TRACE_P (abuf)) \
trace_insn ((cpu), (opcode), (abuf), (pc)) ; \
} while (0)
#define TRACE_EXTRACT(cpu, abuf, args) \
do { \
if (TRACE_EXTRACT_P (cpu)) \
trace_extract args ; \
} while (0)
#define TRACE_RESULT(cpu, abuf, name, type, val) \
do { \
if (TRACE_RESULT_P ((cpu), (abuf))) \
trace_result ((cpu), (name), (type), (val)) ; \
} while (0)
#endif /* CGEN_TRACE_H */

View File

@ -37,23 +37,23 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define COMMAS(n) sim_add_commas (comma_buf, sizeof (comma_buf), (n))
static MODULE_INIT_FN profile_init;
static MODULE_UNINSTALL_FN profile_uninstall;
#if WITH_PROFILE_INSN_P || WITH_PROFILE_MEMORY_P || WITH_PROFILE_CORE_P || WITH_PROFILE_PC_P
static void print_bar (SIM_DESC, unsigned int, unsigned int, unsigned int);
#endif
static DECLARE_OPTION_HANDLER (profile_option_handler);
#define OPTION_PROFILE_INSN (OPTION_START + 0)
#define OPTION_PROFILE_MEMORY (OPTION_START + 1)
#define OPTION_PROFILE_MODEL (OPTION_START + 2)
#define OPTION_PROFILE_FILE (OPTION_START + 3)
#define OPTION_PROFILE_RANGE (OPTION_START + 4)
#define OPTION_PROFILE_CORE (OPTION_START + 5)
#define OPTION_PROFILE_PC (OPTION_START + 6)
#define OPTION_PROFILE_PC_RANGE (OPTION_START + 7)
#define OPTION_PROFILE_PC_GRANULARITY (OPTION_START + 8)
enum {
OPTION_PROFILE_INSN = OPTION_START,
OPTION_PROFILE_MEMORY,
OPTION_PROFILE_MODEL,
OPTION_PROFILE_FILE,
OPTION_PROFILE_CORE,
OPTION_PROFILE_PC,
OPTION_PROFILE_PC_RANGE,
OPTION_PROFILE_PC_GRANULARITY,
OPTION_PROFILE_RANGE,
OPTION_PROFILE_FUNCTION
};
static const OPTION profile_options[] = {
{ {"profile", no_argument, NULL, 'p'},
@ -92,10 +92,15 @@ static const OPTION profile_options[] = {
'\0', "BASE,BOUND", "Specify PC profiling address range",
profile_option_handler },
#if 0 /*FIXME:wip*/
#ifdef SIM_HAVE_ADDR_RANGE
{ {"profile-range", required_argument, NULL, OPTION_PROFILE_RANGE},
0, NULL, "Specify range of addresses to profile",
'\0', "START,END", "Specify range of addresses for instruction and model profiling",
profile_option_handler },
#if 0 /*wip*/
{ {"profile-function", required_argument, NULL, OPTION_PROFILE_FUNCTION},
'\0', "FUNCTION", "Specify function to profile",
profile_option_handler },
#endif
#endif
{ {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
@ -108,7 +113,9 @@ profile_option_handler (SIM_DESC sd,
char *arg,
int is_command)
{
int i,n;
int cpu_nr,prof_nr;
/* FIXME: Need to handle `cpu' arg. */
switch (opt)
{
@ -117,16 +124,16 @@ profile_option_handler (SIM_DESC sd,
sim_io_eprintf (sd, "Profiling not compiled in, -p option ignored\n");
else
{
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
for (i = 0; i < MAX_PROFILE_VALUES; ++i)
CPU_PROFILE_FLAGS (STATE_CPU (sd, n))[i] = 1;
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
for (prof_nr = 0; prof_nr < MAX_PROFILE_VALUES; ++prof_nr)
CPU_PROFILE_FLAGS (STATE_CPU (sd, cpu_nr))[prof_nr] = 1;
}
break;
case OPTION_PROFILE_INSN :
#if WITH_PROFILE_INSN_P
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
CPU_PROFILE_FLAGS (STATE_CPU (sd, n))[PROFILE_INSN_IDX] = 1;
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
CPU_PROFILE_FLAGS (STATE_CPU (sd, cpu_nr))[PROFILE_INSN_IDX] = 1;
#else
sim_io_eprintf (sd, "Instruction profiling not compiled in, `--profile-insn' ignored\n");
#endif
@ -134,8 +141,8 @@ profile_option_handler (SIM_DESC sd,
case OPTION_PROFILE_MEMORY :
#if WITH_PROFILE_MEMORY_P
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
CPU_PROFILE_FLAGS (STATE_CPU (sd, n))[PROFILE_MEMORY_IDX] = 1;
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
CPU_PROFILE_FLAGS (STATE_CPU (sd, cpu_nr))[PROFILE_MEMORY_IDX] = 1;
#else
sim_io_eprintf (sd, "Memory profiling not compiled in, `--profile-memory' ignored\n");
#endif
@ -143,8 +150,8 @@ profile_option_handler (SIM_DESC sd,
case OPTION_PROFILE_CORE :
#if WITH_PROFILE_CORE_P
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
CPU_PROFILE_FLAGS (STATE_CPU (sd, n))[PROFILE_CORE_IDX] = 1;
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
CPU_PROFILE_FLAGS (STATE_CPU (sd, cpu_nr))[PROFILE_CORE_IDX] = 1;
#else
sim_io_eprintf (sd, "CORE profiling not compiled in, `--profile-core' ignored\n");
#endif
@ -152,8 +159,8 @@ profile_option_handler (SIM_DESC sd,
case OPTION_PROFILE_MODEL :
#if WITH_PROFILE_MODEL_P
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
CPU_PROFILE_FLAGS (STATE_CPU (sd, n))[PROFILE_MODEL_IDX] = 1;
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
CPU_PROFILE_FLAGS (STATE_CPU (sd, cpu_nr))[PROFILE_MODEL_IDX] = 1;
#else
sim_io_eprintf (sd, "Model profiling not compiled in, `--profile-model' ignored\n");
#endif
@ -173,16 +180,16 @@ profile_option_handler (SIM_DESC sd,
sim_io_eprintf (sd, "Unable to open profile output file `%s'\n", arg);
return SIM_RC_FAIL;
}
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
PROFILE_FILE (CPU_PROFILE_DATA (STATE_CPU (sd, n))) = f;
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
PROFILE_FILE (CPU_PROFILE_DATA (STATE_CPU (sd, cpu_nr))) = f;
}
break;
case OPTION_PROFILE_PC:
if (WITH_PROFILE_PC_P)
{
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
CPU_PROFILE_FLAGS (STATE_CPU (sd, n))[PROFILE_PC_IDX] = 1;
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
CPU_PROFILE_FLAGS (STATE_CPU (sd, cpu_nr))[PROFILE_PC_IDX] = 1;
}
else
sim_io_eprintf (sd, "PC profiling not compiled in, `--profile-pc' ignored\n");
@ -192,11 +199,11 @@ profile_option_handler (SIM_DESC sd,
if (WITH_PROFILE_PC_P)
{
/* FIXME: Validate arg. */
i = atoi (arg);
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
PROFILE_PC_FREQ (CPU_PROFILE_DATA (STATE_CPU (sd, n))) = i;
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
CPU_PROFILE_FLAGS (STATE_CPU (sd, n))[PROFILE_PC_IDX] = 1;
int val = atoi (arg);
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
PROFILE_PC_FREQ (CPU_PROFILE_DATA (STATE_CPU (sd, cpu_nr))) = val;
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
CPU_PROFILE_FLAGS (STATE_CPU (sd, cpu_nr))[PROFILE_PC_IDX] = 1;
}
else
sim_io_eprintf (sd, "PC profiling not compiled in, `--profile-pc-frequency' ignored\n");
@ -206,11 +213,11 @@ profile_option_handler (SIM_DESC sd,
if (WITH_PROFILE_PC_P)
{
/* FIXME: Validate arg. */
i = atoi (arg);
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
PROFILE_PC_NR_BUCKETS (CPU_PROFILE_DATA (STATE_CPU (sd, n))) = i;
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
CPU_PROFILE_FLAGS (STATE_CPU (sd, n))[PROFILE_PC_IDX] = 1;
int val = atoi (arg);
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
PROFILE_PC_NR_BUCKETS (CPU_PROFILE_DATA (STATE_CPU (sd, cpu_nr))) = val;
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
CPU_PROFILE_FLAGS (STATE_CPU (sd, cpu_nr))[PROFILE_PC_IDX] = 1;
}
else
sim_io_eprintf (sd, "PC profiling not compiled in, `--profile-pc-size' ignored\n");
@ -220,14 +227,14 @@ profile_option_handler (SIM_DESC sd,
if (WITH_PROFILE_PC_P)
{
int shift;
i = atoi (arg);
int val = atoi (arg);
/* check that the granularity is a power of two */
shift = 0;
while (i > (1 << shift))
while (val > (1 << shift))
{
shift += 1;
}
if (i != (1 << shift))
if (val != (1 << shift))
{
sim_io_eprintf (sd, "PC profiling granularity not a power of two\n");
return SIM_RC_FAIL;
@ -237,10 +244,10 @@ profile_option_handler (SIM_DESC sd,
sim_io_eprintf (sd, "PC profiling granularity too small");
return SIM_RC_FAIL;
}
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
PROFILE_PC_SHIFT (CPU_PROFILE_DATA (STATE_CPU (sd, n))) = shift;
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
CPU_PROFILE_FLAGS (STATE_CPU (sd, n))[PROFILE_PC_IDX] = 1;
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
PROFILE_PC_SHIFT (CPU_PROFILE_DATA (STATE_CPU (sd, cpu_nr))) = shift;
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
CPU_PROFILE_FLAGS (STATE_CPU (sd, cpu_nr))[PROFILE_PC_IDX] = 1;
}
else
sim_io_eprintf (sd, "PC profiling not compiled in, `--profile-pc-granularity' ignored\n");
@ -260,22 +267,66 @@ profile_option_handler (SIM_DESC sd,
return SIM_RC_FAIL;
}
bound = strtoul (chp + 1, NULL, 0);
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
{
PROFILE_PC_START (CPU_PROFILE_DATA (STATE_CPU (sd, n))) = base;
PROFILE_PC_END (CPU_PROFILE_DATA (STATE_CPU (sd, n))) = bound;
PROFILE_PC_START (CPU_PROFILE_DATA (STATE_CPU (sd, cpu_nr))) = base;
PROFILE_PC_END (CPU_PROFILE_DATA (STATE_CPU (sd, cpu_nr))) = bound;
}
for (n = 0; n < MAX_NR_PROCESSORS; ++n)
CPU_PROFILE_FLAGS (STATE_CPU (sd, n))[PROFILE_PC_IDX] = 1;
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
CPU_PROFILE_FLAGS (STATE_CPU (sd, cpu_nr))[PROFILE_PC_IDX] = 1;
}
else
sim_io_eprintf (sd, "PC profiling not compiled in, `--profile-pc-range' ignored\n");
#if 0 /* FIXME:wip */
#ifdef SIM_HAVE_ADDR_RANGE
case OPTION_PROFILE_RANGE :
if (WITH_PROFILE)
{
char *chp = arg;
unsigned long start,end;
start = strtoul (chp, &chp, 0);
if (*chp != ',')
{
sim_io_eprintf (sd, "--profile-range missing END argument\n");
return SIM_RC_FAIL;
}
end = strtoul (chp + 1, NULL, 0);
/* FIXME: Argument validation. */
if (cpu != NULL)
sim_addr_range_add (PROFILE_RANGE (CPU_PROFILE_DATA (cpu)),
start, end);
else
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
sim_addr_range_add (PROFILE_RANGE (CPU_PROFILE_DATA (STATE_CPU (sd, cpu_nr))),
start, end);
}
else
sim_io_eprintf (sd, "Profiling not compiled in, `--profile-range' ignored\n");
break;
#endif
case OPTION_PROFILE_FUNCTION :
if (WITH_PROFILE)
{
/*wip: need to compute function range given name*/
}
else
sim_io_eprintf (sd, "Profiling not compiled in, `--profile-function' ignored\n");
break;
#endif /* SIM_HAVE_ADDR_RANGE */
}
/* Re-compute the cpu profile summary. */
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
{
CPU_PROFILE_DATA (STATE_CPU (sd, cpu_nr))->profile_any_p = 0;
for (prof_nr = 0; prof_nr < MAX_PROFILE_VALUES; ++prof_nr)
{
if (CPU_PROFILE_FLAGS (STATE_CPU (sd, cpu_nr))[prof_nr])
{
CPU_PROFILE_DATA (STATE_CPU (sd, cpu_nr))->profile_any_p = 1;
break;
}
}
}
return SIM_RC_OK;
@ -476,9 +527,9 @@ profile_print_pc (sim_cpu *cpu, int verbose)
sim_io_printf (sd, " %4.1f",
(PROFILE_PC_COUNT (profile) [i] * 100.0) / total);
sim_io_printf (sd, ": ");
print_bar (sd, PROFILE_HISTOGRAM_WIDTH,
PROFILE_PC_COUNT (profile) [i],
max_val);
sim_profile_print_bar (sd, PROFILE_HISTOGRAM_WIDTH,
PROFILE_PC_COUNT (profile) [i],
max_val);
sim_io_printf (sd, "\n");
}
}
@ -540,6 +591,22 @@ profile_print_pc (sim_cpu *cpu, int verbose)
#if WITH_PROFILE_INSN_P
static SIM_RC
profile_insn_init (SIM_DESC sd)
{
int c;
for (c = 0; c < MAX_NR_PROCESSORS; ++c)
{
sim_cpu *cpu = STATE_CPU (sd, c);
if (CPU_MAX_INSNS (cpu) > 0)
PROFILE_INSN_COUNT (CPU_PROFILE_DATA (cpu)) = NZALLOC (unsigned int, CPU_MAX_INSNS (cpu));
}
return SIM_RC_OK;
}
static void
profile_print_insn (sim_cpu *cpu, int verbose)
{
@ -548,25 +615,36 @@ profile_print_insn (sim_cpu *cpu, int verbose)
PROFILE_DATA *data = CPU_PROFILE_DATA (cpu);
char comma_buf[20];
sim_io_printf (sd, "Instruction Statistics:\n\n");
/* If MAX_INSNS not set, insn profiling isn't supported. */
if (CPU_MAX_INSNS (cpu) == 0)
return;
sim_io_printf (sd, "Instruction Statistics");
#ifdef SIM_HAVE_ADDR_RANGE
if (PROFILE_RANGE (data)->ranges)
sim_io_printf (sd, " (for selected address range(s))");
#endif
sim_io_printf (sd, "\n\n");
/* First pass over data computes various things. */
max_val = 0;
total = 0;
max_name_len = 0;
for (i = 0; i < MAX_INSNS; ++i)
for (i = 0; i < CPU_MAX_INSNS (cpu); ++i)
{
if (INSN_NAME (i) == NULL)
const char *name = (*CPU_INSN_NAME (cpu)) (cpu, i);
if (name == NULL)
continue;
total += PROFILE_INSN_COUNT (data) [i];
if (PROFILE_INSN_COUNT (data) [i] > max_val)
max_val = PROFILE_INSN_COUNT (data) [i];
n = strlen (INSN_NAME (i));
n = strlen (name);
if (n > max_name_len)
max_name_len = n;
}
/* set the total insn count, in case client is being lazy */
if (PROFILE_TOTAL_INSN_COUNT (data))
if (! PROFILE_TOTAL_INSN_COUNT (data))
PROFILE_TOTAL_INSN_COUNT (data) = total;
sim_io_printf (sd, " Total: %s insns\n", COMMAS (total));
@ -575,19 +653,21 @@ profile_print_insn (sim_cpu *cpu, int verbose)
{
/* Now we can print the histogram. */
sim_io_printf (sd, "\n");
for (i = 0; i < MAX_INSNS; ++i)
for (i = 0; i < CPU_MAX_INSNS (cpu); ++i)
{
if (INSN_NAME (i) == NULL)
const char *name = (*CPU_INSN_NAME (cpu)) (cpu, i);
if (name == NULL)
continue;
if (PROFILE_INSN_COUNT (data) [i] != 0)
{
sim_io_printf (sd, " %*s: %*s: ",
max_name_len, INSN_NAME (i),
max_name_len, name,
max_val < 10000 ? 5 : 10,
COMMAS (PROFILE_INSN_COUNT (data) [i]));
print_bar (sd, PROFILE_HISTOGRAM_WIDTH,
PROFILE_INSN_COUNT (data) [i],
max_val);
sim_profile_print_bar (sd, PROFILE_HISTOGRAM_WIDTH,
PROFILE_INSN_COUNT (data) [i],
max_val);
sim_io_printf (sd, "\n");
}
}
@ -611,11 +691,11 @@ profile_print_memory (sim_cpu *cpu, int verbose)
PROFILE_DATA *data = CPU_PROFILE_DATA (cpu);
char comma_buf[20];
sim_io_printf (sd, "Memory Access Statistics:\n\n");
sim_io_printf (sd, "Memory Access Statistics\n\n");
/* First pass over data computes various things. */
max_val = total_read = total_write = max_name_len = 0;
for (i = 0; i < MAX_MODES; ++i)
for (i = 0; i < MODE_TARGET_MAX; ++i)
{
total_read += PROFILE_READ_COUNT (data) [i];
total_write += PROFILE_WRITE_COUNT (data) [i];
@ -640,7 +720,7 @@ profile_print_memory (sim_cpu *cpu, int verbose)
as the former swamps the latter. */
/* Now we can print the histogram. */
sim_io_printf (sd, "\n");
for (i = 0; i < MAX_MODES; ++i)
for (i = 0; i < MODE_TARGET_MAX; ++i)
{
if (PROFILE_READ_COUNT (data) [i] != 0)
{
@ -648,9 +728,9 @@ profile_print_memory (sim_cpu *cpu, int verbose)
max_name_len, MODE_NAME (i),
max_val < 10000 ? 5 : 10,
COMMAS (PROFILE_READ_COUNT (data) [i]));
print_bar (sd, PROFILE_HISTOGRAM_WIDTH,
PROFILE_READ_COUNT (data) [i],
max_val);
sim_profile_print_bar (sd, PROFILE_HISTOGRAM_WIDTH,
PROFILE_READ_COUNT (data) [i],
max_val);
sim_io_printf (sd, "\n");
}
if (PROFILE_WRITE_COUNT (data) [i] != 0)
@ -659,9 +739,9 @@ profile_print_memory (sim_cpu *cpu, int verbose)
max_name_len, MODE_NAME (i),
max_val < 10000 ? 5 : 10,
COMMAS (PROFILE_WRITE_COUNT (data) [i]));
print_bar (sd, PROFILE_HISTOGRAM_WIDTH,
PROFILE_WRITE_COUNT (data) [i],
max_val);
sim_profile_print_bar (sd, PROFILE_HISTOGRAM_WIDTH,
PROFILE_WRITE_COUNT (data) [i],
max_val);
sim_io_printf (sd, "\n");
}
}
@ -684,14 +764,14 @@ profile_print_core (sim_cpu *cpu, int verbose)
PROFILE_DATA *data = CPU_PROFILE_DATA (cpu);
char comma_buf[20];
sim_io_printf (sd, "CORE Statistics:\n\n");
sim_io_printf (sd, "CORE Statistics\n\n");
/* First pass over data computes various things. */
{
sim_core_maps map;
unsigned map;
total = 0;
max_val = 0;
for (map = 0; map < nr_sim_core_maps; map++)
for (map = 0; map < nr_maps; map++)
{
total += PROFILE_CORE_COUNT (data) [map];
if (PROFILE_CORE_COUNT (data) [map] > max_val)
@ -705,20 +785,20 @@ profile_print_core (sim_cpu *cpu, int verbose)
if (verbose && max_val != 0)
{
sim_core_maps map;
unsigned map;
/* Now we can print the histogram. */
sim_io_printf (sd, "\n");
for (map = 0; map < nr_sim_core_maps; map++)
for (map = 0; map < nr_maps; map++)
{
if (PROFILE_CORE_COUNT (data) [map] != 0)
{
sim_io_printf (sd, "%10s:", sim_core_map_to_str (map));
sim_io_printf (sd, "%10s:", map_to_str (map));
sim_io_printf (sd, "%*s: ",
max_val < 10000 ? 5 : 10,
COMMAS (PROFILE_CORE_COUNT (data) [map]));
print_bar (sd, PROFILE_HISTOGRAM_WIDTH,
PROFILE_CORE_COUNT (data) [map],
max_val);
sim_profile_print_bar (sd, PROFILE_HISTOGRAM_WIDTH,
PROFILE_CORE_COUNT (data) [map],
max_val);
sim_io_printf (sd, "\n");
}
}
@ -736,14 +816,18 @@ profile_print_model (sim_cpu *cpu, int verbose)
{
SIM_DESC sd = CPU_STATE (cpu);
PROFILE_DATA *data = CPU_PROFILE_DATA (cpu);
unsigned long cti_stalls = PROFILE_MODEL_CTI_STALL_COUNT (data);
unsigned long load_stalls = PROFILE_MODEL_LOAD_STALL_COUNT (data);
unsigned long total = PROFILE_MODEL_CYCLE_COUNT (data)
+ cti_stalls + load_stalls;
unsigned long cti_stall_cycles = PROFILE_MODEL_CTI_STALL_CYCLES (data);
unsigned long load_stall_cycles = PROFILE_MODEL_LOAD_STALL_CYCLES (data);
unsigned long total_cycles = PROFILE_MODEL_TOTAL_CYCLES (data);
char comma_buf[20];
sim_io_printf (sd, "Model %s Timing Information\n\n",
sim_io_printf (sd, "Model %s Timing Information",
MODEL_NAME (CPU_MODEL (cpu)));
#ifdef SIM_HAVE_ADDR_RANGE
if (PROFILE_RANGE (data)->ranges)
sim_io_printf (sd, " (for selected address range(s))");
#endif
sim_io_printf (sd, "\n\n");
sim_io_printf (sd, " %-*s %s\n",
PROFILE_LABEL_WIDTH, "Taken branches:",
COMMAS (PROFILE_MODEL_TAKEN_COUNT (data)));
@ -752,24 +836,21 @@ profile_print_model (sim_cpu *cpu, int verbose)
COMMAS (PROFILE_MODEL_UNTAKEN_COUNT (data)));
sim_io_printf (sd, " %-*s %s\n",
PROFILE_LABEL_WIDTH, "Cycles stalled due to branches:",
COMMAS (cti_stalls));
COMMAS (cti_stall_cycles));
sim_io_printf (sd, " %-*s %s\n",
PROFILE_LABEL_WIDTH, "Cycles stalled due to loads:",
COMMAS (load_stalls));
COMMAS (load_stall_cycles));
sim_io_printf (sd, " %-*s %s\n",
PROFILE_LABEL_WIDTH, "Total cycles (*approximate*):",
COMMAS (total));
COMMAS (total_cycles));
sim_io_printf (sd, "\n");
}
#endif
#if WITH_PROFILE_INSN_P || WITH_PROFILE_MEMORY_P || WITH_PROFILE_CORE_P || WITH_PROFILE_PC_P
static void
print_bar (SIM_DESC sd, unsigned int width,
unsigned int val, unsigned int max_val)
void
sim_profile_print_bar (SIM_DESC sd, unsigned int width,
unsigned int val, unsigned int max_val)
{
unsigned int i, count;
@ -779,8 +860,6 @@ print_bar (SIM_DESC sd, unsigned int width,
sim_io_printf (sd, "*");
}
#endif
/* Print the simulator's execution speed for CPU. */
static void
@ -798,7 +877,7 @@ profile_print_speed (sim_cpu *cpu)
sim_io_printf (sd, " Total instructions: %s\n", COMMAS (total));
if (milliseconds < 1000)
sim_io_printf (sd, " Total Execution Time: < 1 second\n\n");
sim_io_printf (sd, " Total execution time: < 1 second\n\n");
else
{
/* The printing of the time rounded to 2 decimal places makes the speed
@ -807,16 +886,37 @@ profile_print_speed (sim_cpu *cpu)
better that the user not perceive there's a math error. */
double secs = (double) milliseconds / 1000;
secs = ((double) (unsigned long) (secs * 100 + .5)) / 100;
sim_io_printf (sd, " Total Execution Time: %.2f seconds\n", secs);
sim_io_printf (sd, " Total execution time: %.2f seconds\n", secs);
/* Don't confuse things with data that isn't useful.
If we ran for less than 2 seconds, only use the data if we
executed more than 100,000 insns. */
if (secs >= 2 || total >= 100000)
sim_io_printf (sd, " Simulator Speed: %s insns/second\n\n",
sim_io_printf (sd, " Simulator speed: %s insns/second\n\n",
COMMAS ((unsigned long) ((double) total / secs)));
}
}
/* Print selected address ranges. */
static void
profile_print_addr_ranges (sim_cpu *cpu)
{
ADDR_SUBRANGE *asr = PROFILE_RANGE (CPU_PROFILE_DATA (cpu))->ranges;
SIM_DESC sd = CPU_STATE (cpu);
if (asr)
{
sim_io_printf (sd, "Selected address ranges:\n");
while (asr != NULL)
{
sim_io_printf (sd, "0x%lx - 0x%lx\n",
(long) asr->start, (long) asr->end);
asr = asr->next;
}
sim_io_printf (sd, "\n");
}
}
/* Top level function to print all summary profile information.
It is [currently] intended that all such data is printed by this function.
I'd rather keep it all in one place for now. To that end, MISC_CPU and
@ -836,6 +936,7 @@ profile_info (SIM_DESC sd, int verbose)
int print_title_p = 0;
/* Only print the title if some data has been collected. */
/* ??? Why don't we just exit if no data collected? */
/* FIXME: If the number of processors can be selected on the command line,
then MAX_NR_PROCESSORS will need to take an argument of `sd'. */
@ -884,6 +985,13 @@ profile_info (SIM_DESC sd, int verbose)
sim_io_printf (sd, "CPU %d\n\n", c);
}
#ifdef SIM_HAVE_ADDR_RANGE
if (print_title_p
&& (PROFILE_INSN_P (cpu)
|| PROFILE_MODEL_P (cpu)))
profile_print_addr_ranges (cpu);
#endif
#if WITH_PROFILE_INSN_P
if (PROFILE_FLAGS (data) [PROFILE_INSN_IDX])
profile_print_insn (cpu, verbose);
@ -942,15 +1050,48 @@ profile_install (SIM_DESC sd)
for (i = 0; i < MAX_NR_PROCESSORS; ++i)
memset (CPU_PROFILE_DATA (STATE_CPU (sd, i)), 0,
sizeof (* CPU_PROFILE_DATA (STATE_CPU (sd, i))));
#if WITH_PROFILE_INSN_P
sim_module_add_init_fn (sd, profile_insn_init);
#endif
#if WITH_PROFILE_PC_P
sim_module_add_uninstall_fn (sd, profile_pc_uninstall);
sim_module_add_init_fn (sd, profile_pc_init);
#endif
sim_module_add_init_fn (sd, profile_init);
sim_module_add_uninstall_fn (sd, profile_uninstall);
sim_module_add_info_fn (sd, profile_info);
return SIM_RC_OK;
}
static SIM_RC
profile_init (SIM_DESC sd)
{
#ifdef SIM_HAVE_ADDR_RANGE
/* Check if a range has been specified without specifying what to
collect. */
{
int i;
for (i = 0; i < MAX_NR_PROCESSORS; ++i)
{
sim_cpu *cpu = STATE_CPU (sd, i);
if (ADDR_RANGE_RANGES (PROFILE_RANGE (CPU_PROFILE_DATA (cpu)))
&& ! (PROFILE_INSN_P (cpu)
|| PROFILE_MODEL_P (cpu)))
{
sim_io_eprintf_cpu (cpu, "Profiling address range specified without --profile-insn or --profile-model.\n");
sim_io_eprintf_cpu (cpu, "Address range ignored.\n");
sim_addr_range_delete (PROFILE_RANGE (CPU_PROFILE_DATA (cpu)),
0, ~ (address_word) 0);
}
}
}
#endif
return SIM_RC_OK;
}
static void
profile_uninstall (SIM_DESC sd)
{
@ -958,7 +1099,9 @@ profile_uninstall (SIM_DESC sd)
for (i = 0; i < MAX_NR_PROCESSORS; ++i)
{
PROFILE_DATA *data = CPU_PROFILE_DATA (STATE_CPU (sd, i));
sim_cpu *cpu = STATE_CPU (sd, i);
PROFILE_DATA *data = CPU_PROFILE_DATA (cpu);
if (PROFILE_FILE (data) != NULL)
{
/* If output from different cpus is going to the same file,
@ -970,5 +1113,8 @@ profile_uninstall (SIM_DESC sd)
if (i == j)
fclose (PROFILE_FILE (data));
}
if (PROFILE_INSN_COUNT (data) != NULL)
zfree (PROFILE_INSN_COUNT (data));
}
}

View File

@ -22,7 +22,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "sim-io.h"
#include "sim-options.h"
#include "sim-fpu.h"
#include "bfd.h"
#include "libiberty.h"
#include "sim-assert.h"
@ -50,6 +52,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define SIZE_LINE_NUMBER 4
#endif
static MODULE_INIT_FN trace_init;
static MODULE_UNINSTALL_FN trace_uninstall;
static DECLARE_OPTION_HANDLER (trace_option_handler);
@ -67,6 +70,8 @@ enum {
OPTION_TRACE_FPU,
OPTION_TRACE_BRANCH,
OPTION_TRACE_SEMANTICS,
OPTION_TRACE_RANGE,
OPTION_TRACE_FUNCTION,
OPTION_TRACE_DEBUG,
OPTION_TRACE_FILE
};
@ -113,6 +118,16 @@ static const OPTION trace_options[] =
{ {"trace-events", optional_argument, NULL, OPTION_TRACE_EVENTS},
'\0', "on|off", "Trace events",
trace_option_handler },
#ifdef SIM_HAVE_ADDR_RANGE
{ {"trace-range", required_argument, NULL, OPTION_TRACE_RANGE},
'\0', "START,END", "Specify range of addresses for instruction tracing",
trace_option_handler },
#if 0 /*wip*/
{ {"trace-function", required_argument, NULL, OPTION_TRACE_FUNCTION},
'\0', "FUNCTION", "Specify function to trace",
trace_option_handler },
#endif
#endif
{ {"trace-debug", optional_argument, NULL, OPTION_TRACE_DEBUG},
'\0', "on|off", "Add information useful for debugging the simulator to the tracing output",
trace_option_handler },
@ -152,6 +167,7 @@ set_trace_option_mask (sd, name, mask, arg)
}
}
/* update applicable trace bits */
for (trace_nr = 0; trace_nr < MAX_TRACE_VALUES; ++trace_nr)
{
if ((mask & (1 << trace_nr)) == 0)
@ -175,6 +191,28 @@ set_trace_option_mask (sd, name, mask, arg)
}
}
/* Re-compute the cpu trace summary. */
if (trace_val)
{
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
CPU_TRACE_DATA (STATE_CPU (sd, cpu_nr))->trace_any_p = 1;
}
else
{
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
{
CPU_TRACE_DATA (STATE_CPU (sd, cpu_nr))->trace_any_p = 0;
for (trace_nr = 0; trace_nr < MAX_TRACE_VALUES; ++trace_nr)
{
if (CPU_TRACE_FLAGS (STATE_CPU (sd, cpu_nr))[trace_nr])
{
CPU_TRACE_DATA (STATE_CPU (sd, cpu_nr))->trace_any_p = 1;
break;
}
}
}
}
return SIM_RC_OK;
}
@ -196,6 +234,7 @@ trace_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
char *arg, int is_command)
{
int n;
int cpu_nr;
switch (opt)
{
@ -303,6 +342,42 @@ trace_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
sim_io_eprintf (sd, "Alu, fpu, memory, and/or branch tracing not compiled in, `--trace-semantics' ignored\n");
break;
#ifdef SIM_HAVE_ADDR_RANGE
case OPTION_TRACE_RANGE :
if (WITH_TRACE)
{
char *chp = arg;
unsigned long start,end;
start = strtoul (chp, &chp, 0);
if (*chp != ',')
{
sim_io_eprintf (sd, "--trace-range missing END argument\n");
return SIM_RC_FAIL;
}
end = strtoul (chp + 1, NULL, 0);
/* FIXME: Argument validation. */
if (cpu != NULL)
sim_addr_range_add (TRACE_RANGE (CPU_PROFILE_DATA (cpu)),
start, end);
else
for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
sim_addr_range_add (TRACE_RANGE (CPU_TRACE_DATA (STATE_CPU (sd, cpu_nr))),
start, end);
}
else
sim_io_eprintf (sd, "Tracing not compiled in, `--trace-range' ignored\n");
break;
case OPTION_TRACE_FUNCTION :
if (WITH_TRACE)
{
/*wip: need to compute function range given name*/
}
else
sim_io_eprintf (sd, "Tracing not compiled in, `--trace-function' ignored\n");
break;
#endif /* SIM_HAVE_ADDR_RANGE */
case OPTION_TRACE_DEBUG :
if (WITH_TRACE_DEBUG_P)
return set_trace_option (sd, "-debug", TRACE_DEBUG_IDX, arg);
@ -346,10 +421,39 @@ trace_install (SIM_DESC sd)
for (i = 0; i < MAX_NR_PROCESSORS; ++i)
memset (CPU_TRACE_DATA (STATE_CPU (sd, i)), 0,
sizeof (* CPU_TRACE_DATA (STATE_CPU (sd, i))));
sim_module_add_init_fn (sd, trace_init);
sim_module_add_uninstall_fn (sd, trace_uninstall);
return SIM_RC_OK;
}
static SIM_RC
trace_init (SIM_DESC sd)
{
#ifdef SIM_HAVE_ADDR_RANGE
/* Check if a range has been specified without specifying what to
collect. */
{
int i;
for (i = 0; i < MAX_NR_PROCESSORS; ++i)
{
sim_cpu *cpu = STATE_CPU (sd, i);
if (ADDR_RANGE_RANGES (TRACE_RANGE (CPU_TRACE_DATA (cpu)))
&& ! TRACE_INSN_P (cpu))
{
sim_io_eprintf_cpu (cpu, "Tracing address range specified without --trace-insn.\n");
sim_io_eprintf_cpu (cpu, "Address range ignored.\n");
sim_addr_range_delete (TRACE_RANGE (CPU_TRACE_DATA (cpu)),
0, ~ (address_word) 0);
}
}
}
#endif
return SIM_RC_OK;
}
static void
trace_uninstall (SIM_DESC sd)
{
@ -458,15 +562,29 @@ print_data (SIM_DESC sd,
{
/* FIXME: Assumes sizeof float == 4; sizeof double == 8 */
case 4:
sim_fpu_32to (&fp, * (unsigned32*) data);
sim_fpu_32to (&fp, *(unsigned32*)data);
break;
case 8:
sim_fpu_64to (&fp, * (unsigned32*) data);
sim_fpu_64to (&fp, *(unsigned64*)data);
break;
default:
abort ();
}
trace_printf (sd, cpu, " %8g", sim_fpu_2d (&fp));
switch (size)
{
case 4:
trace_printf (sd, cpu, " (0x%08lx)",
(long) *(unsigned32*)data);
break;
case 8:
trace_printf (sd, cpu, " (0x%08lx%08lx)",
(long) (*(unsigned64*)data >> 32),
(long) (*(unsigned64*)data));
break;
default:
abort ();
}
break;
}
case trace_fmt_fpu:
@ -544,6 +662,7 @@ trace_results (SIM_DESC sd,
void
trace_prefix (SIM_DESC sd,
sim_cpu *cpu,
sim_cia cia,
address_word pc,
int line_p,
const char *filename,
@ -555,9 +674,15 @@ trace_prefix (SIM_DESC sd,
va_list ap;
char *prefix = TRACE_PREFIX (data);
char *chp;
/* FIXME: The TRACE_PREFIX_WIDTH should be determined at build time using
known information about the disassembled instructions. */
#ifndef TRACE_PREFIX_WIDTH
#define TRACE_PREFIX_WIDTH 48
#endif
int width = TRACE_PREFIX_WIDTH;
/* if the previous trace data wasn't flushed, flush it now with a
note indicating that this occured. */
note indicating that the trace was incomplete. */
if (TRACE_IDX (data) != 0)
{
int last_input = TRACE_INPUT_IDX (data);
@ -567,12 +692,23 @@ trace_prefix (SIM_DESC sd,
TRACE_IDX (data) = 0;
TRACE_INPUT_IDX (data) = 0;
/* Create the text prefix for this new instruction: */
if (!line_p)
{
sprintf (prefix, "%s:%-*d 0x%.*lx ",
filename,
SIZE_LINE_NUMBER, linenum,
SIZE_PC, (long)pc);
if (filename)
{
sprintf (prefix, "%s:%-*d 0x%.*lx ",
filename,
SIZE_LINE_NUMBER, linenum,
SIZE_PC, (long) pc);
}
else
{
sprintf (prefix, "0x%.*lx ",
SIZE_PC, (long) pc);
/* Shrink the width by the amount that we didn't print. */
width -= SIZE_LINE_NUMBER + SIZE_PC + 8;
}
chp = strchr (prefix, '\0');
va_start (ap, fmt);
vsprintf (chp, fmt, ap);
@ -602,16 +738,17 @@ trace_prefix (SIM_DESC sd,
symsize = bfd_get_symtab_upper_bound (abfd);
if (symsize < 0)
{
sim_engine_abort (sd, cpu, 0, "could not read symbols\n");
sim_engine_abort (sd, cpu, cia, "could not read symbols");
}
asymbols = (asymbol **) xmalloc (symsize);
symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
if (symbol_count < 0)
{
sim_engine_abort (sd, cpu, 0, "could not canonicalize symbols\n");
sim_engine_abort (sd, cpu, cia, "could not canonicalize symbols");
}
STATE_PROG_SYMS (CPU_STATE (cpu)) = asymbols;
}
if (bfd_find_nearest_line (abfd,
STATE_TEXT_SECTION (CPU_STATE (cpu)),
asymbols,
@ -656,17 +793,12 @@ trace_prefix (SIM_DESC sd,
va_end (ap);
}
/* pad it out to TRACE_PREFIX_WIDTH. FIXME: The TRACE_PREFIX_WIDTH
should be determined at build time using known information about
the disassembled instructions */
#ifndef TRACE_PREFIX_WIDTH
#define TRACE_PREFIX_WIDTH 48
#endif
/* Pad it out to TRACE_PREFIX_WIDTH. */
chp = strchr (prefix, '\0');
if (chp - prefix < TRACE_PREFIX_WIDTH)
if (chp - prefix < width)
{
memset (chp, ' ', TRACE_PREFIX_WIDTH - (chp - prefix));
chp = &prefix [TRACE_PREFIX_WIDTH];
memset (chp, ' ', width - (chp - prefix));
chp = &prefix [width];
*chp = '\0';
}
strcpy (chp, " -");
@ -985,6 +1117,24 @@ trace_result_fp1 (SIM_DESC sd,
trace_results (sd, cpu, trace_idx, last_input);
}
void
trace_result_fp2 (SIM_DESC sd,
sim_cpu *cpu,
int trace_idx,
fp_word f0,
fp_word f1)
{
TRACE_DATA *data = CPU_TRACE_DATA (cpu);
int last_input;
/* Append any results to the end of the inputs */
last_input = TRACE_INPUT_IDX (data);
save_data (sd, data, trace_fmt_fp, sizeof (f0), &f0);
save_data (sd, data, trace_fmt_fp, sizeof (f1), &f1);
trace_results (sd, cpu, trace_idx, last_input);
}
void
trace_result_fpu1 (SIM_DESC sd,
sim_cpu *cpu,
@ -1056,6 +1206,8 @@ trace_vprintf (SIM_DESC sd, sim_cpu *cpu, const char *fmt, va_list ap)
}
}
/* The function trace_one_insn has been replaced by the function pair
trace_prefix() + trace_generic(). It is still used. */
void
trace_one_insn (SIM_DESC sd, sim_cpu *cpu, address_word pc,
int line_p, const char *filename, int linenum,