diff options
author | Doug Evans <dje@google.com> | 1999-01-06 00:42:34 +0000 |
---|---|---|
committer | Doug Evans <dje@google.com> | 1999-01-06 00:42:34 +0000 |
commit | f5cd4d758c52b6746046da1fafd0e70b41022178 (patch) | |
tree | 3eb8c2ebe80f7fb26095862240191e4ae138adc6 /sim/common/cgen-trace.c | |
parent | 5730d39d2cd1974c77899555dac466babc316589 (diff) | |
download | gdb-f5cd4d758c52b6746046da1fafd0e70b41022178.zip gdb-f5cd4d758c52b6746046da1fafd0e70b41022178.tar.gz gdb-f5cd4d758c52b6746046da1fafd0e70b41022178.tar.bz2 |
* Make-common.in (CGEN_INCLUDE_DEPS): Add cgen-defs.h, cgen-engine.h.
(CGEN_MAIN_SCM): Add rtx-funcs.scm.
(cgen-arch): Pass $(mach) to cgen.sh.
* cgen-engine.h (SEM_BRANCH_FINI): New arg pcvar, all uses updated.
(SEM_BRANCH_INIT_EXTRACT): New macro.
(SEM_BRANCH_INIT): Add taken_p.
(TARGET_SEM_BRANCH_FINI): Provide default definition.
(SEM_BRANCH_FINI): Use it.
(SEM_INSN): Update.
* cgen-run.c (sim_resume): Handle tracing of last insn.
* cgen-scache.h (WITH_SCACHE): Define as 0 if not defined.
* cgen-trace.c (current_abuf): New static global.
(trace_insn_init): Initialize it.
(trace_insn_fini): Use it.
(trace_insn): Set it.
* cgen.sh (arch case): Pass -m ${mach} to cgen.
* genmloop.sh (@cpu@_emit_before): Only define if WITH_SCACHE_PBB.
(@cpu@_emit_after): Ditto.
(simple @cpu@_engine_run_full): New local `pc'. Initialize semantic
labels if WITH_SEM_SWITCH_FULL.
* sim-model.c: Include bfd.h.
(sim_model_init): New function.
(sim_model_install): Record init fn.
* sim-model.h (MACH): New member bfd_name.
* sim-module.c (modules): Initialize model before scache.
Diffstat (limited to 'sim/common/cgen-trace.c')
-rw-r--r-- | sim/common/cgen-trace.c | 196 |
1 files changed, 110 insertions, 86 deletions
diff --git a/sim/common/cgen-trace.c b/sim/common/cgen-trace.c index c389014..f95f837 100644 --- a/sim/common/cgen-trace.c +++ b/sim/common/cgen-trace.c @@ -1,5 +1,5 @@ /* Tracing support for CGEN-based simulators. - Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. Contributed by Cygnus Support. This file is part of GDB, the GNU debugger. @@ -46,118 +46,136 @@ with this program; if not, write to the Free Software Foundation, Inc., #define SIZE_TOTAL_CYCLE_COUNT 9 #endif +#ifndef SIZE_TRACE_BUF +#define SIZE_TRACE_BUF 256 +#endif + /* Text is queued in TRACE_BUF because we want to output the insn's cycle - count first but that isn't known until after the insn has executed. */ -static char trace_buf[1024]; + count first but that isn't known until after the insn has executed. + This also handles the queueing of trace results, TRACE_RESULT may be + called multiple times for one insn. */ +static char trace_buf[SIZE_TRACE_BUF]; /* If NULL, output to stdout directly. */ static char *bufptr; -/* For computing an instruction's cycle count. - FIXME: Need to move into cpu struct for smp case. */ -static unsigned long last_cycle_count; +/* Non-zero if this is the first insn in a set of parallel insns. */ +static int first_insn_p; + +/* For communication between trace_insn and trace_result. */ +static int printed_result_p; + +/* Insn and its extracted fields. + Set by trace_insn, used by trace_insn_fini. + ??? Move to SIM_CPU to support heterogeneous multi-cpu case. */ +static const struct cgen_insn *current_insn; +static CGEN_FIELDS insn_fields; +static const struct argbuf *current_abuf; void trace_insn_init (SIM_CPU *cpu, int first_p) { bufptr = trace_buf; *bufptr = 0; + first_insn_p = first_p; + + /* Set to NULL so trace_insn_fini can know if trace_insn was called. */ + current_insn = NULL; + current_abuf = NULL; } void -trace_insn_fini (SIM_CPU *cpu, int last_p) +trace_insn_fini (SIM_CPU *cpu, const struct argbuf *abuf, int last_p) { - if (CPU_PROFILE_FLAGS (cpu) [PROFILE_MODEL_IDX]) - { - unsigned long total = PROFILE_TOTAL_CYCLE_COUNT (CPU_PROFILE_DATA (cpu)); - trace_printf (CPU_STATE (cpu), cpu, "%-*ld %-*ld ", - SIZE_CYCLE_COUNT, total - last_cycle_count, - SIZE_TOTAL_CYCLE_COUNT, total); - last_cycle_count = total; - } + SIM_DESC sd = CPU_STATE (cpu); - trace_printf (CPU_STATE (cpu), cpu, "%s\n", trace_buf); -} + /* Was insn traced? It might not be if trace ranges are in effect. */ + if (current_insn == NULL) + return; -/* For communication between trace_insn and trace_result. */ -static int printed_result_p; + /* The first thing printed is current and total cycle counts. */ -void -trace_insn (SIM_CPU *cpu, const struct cgen_insn *opcode, - const struct argbuf *abuf, PCADDR pc) -{ - const char *filename; - const char *functionname; - unsigned int linenumber; - char *p, buf[256], disasm_buf[50]; - - if (! TRACE_P (cpu, TRACE_LINENUM_IDX)) + if (PROFILE_MODEL_P (cpu) + && ARGBUF_PROFILE_P (current_abuf)) { - cgen_trace_printf (cpu, "0x%.*x %-*s ", - SIZE_PC, (unsigned) pc, - SIZE_INSTRUCTION, - CGEN_INSN_MNEMONIC (opcode)); - printed_result_p = 0; - return; - } + unsigned long total = PROFILE_MODEL_TOTAL_CYCLES (CPU_PROFILE_DATA (cpu)); + unsigned long this_insn = PROFILE_MODEL_CUR_INSN_CYCLES (CPU_PROFILE_DATA (cpu)); - buf[0] = 0; - - if (STATE_TEXT_SECTION (CPU_STATE (cpu)) - && pc >= STATE_TEXT_START (CPU_STATE (cpu)) - && pc < STATE_TEXT_END (CPU_STATE (cpu))) - { - filename = (const char *) 0; - functionname = (const char *) 0; - linenumber = 0; - if (bfd_find_nearest_line (STATE_PROG_BFD (CPU_STATE (cpu)), - STATE_TEXT_SECTION (CPU_STATE (cpu)), - (struct symbol_cache_entry **) 0, - pc - STATE_TEXT_START (CPU_STATE (cpu)), - &filename, &functionname, &linenumber)) + if (last_p) + { + trace_printf (sd, cpu, "%-*ld %-*ld ", + SIZE_CYCLE_COUNT, this_insn, + SIZE_TOTAL_CYCLE_COUNT, total); + } + else { - p = buf; - if (linenumber) - { - sprintf (p, "#%-*d ", SIZE_LINE_NUMBER, linenumber); - p += strlen (p); - } - else - { - sprintf (p, "%-*s ", SIZE_LINE_NUMBER+1, "---"); - p += SIZE_LINE_NUMBER+2; - } - - if (functionname) - { - sprintf (p, "%s ", functionname); - p += strlen (p); - } - else if (filename) - { - char *q = (char *) strrchr (filename, '/'); - sprintf (p, "%s ", (q) ? q+1 : filename); - p += strlen (p); - } - - if (*p == ' ') - *p = '\0'; + trace_printf (sd, cpu, "%-*ld %-*s ", + SIZE_CYCLE_COUNT, this_insn, + SIZE_TOTAL_CYCLE_COUNT, "---"); } } - sim_disassemble_insn (cpu, opcode, abuf, pc, disasm_buf); + /* Print the disassembled insn. */ + + trace_printf (sd, cpu, "%s", TRACE_PREFIX (CPU_TRACE_DATA (cpu))); - cgen_trace_printf (cpu, "0x%.*x %-*.*s %-*s ", - SIZE_PC, (unsigned) pc, - SIZE_LOCATION, SIZE_LOCATION, buf, - SIZE_INSTRUCTION, #if 0 - CGEN_INSN_NAME (opcode) -#else - disasm_buf + /* Print insn results. */ + { + const CGEN_OPERAND_INSTANCE *opinst = CGEN_INSN_OPERANDS (current_insn); + + if (opinst) + { + int i; + int indices[MAX_OPERAND_INSTANCES]; + + /* Fetch the operands used by the insn. */ + /* FIXME: Add fn ptr to CGEN_OPCODE_DESC. */ + CGEN_SYM (get_insn_operands) (STATE_OPCODE_TABLE (sd), current_insn, + 0, CGEN_FIELDS_BITSIZE (&insn_fields), + indices); + + for (i = 0; + CGEN_OPERAND_INSTANCE_TYPE (opinst) != CGEN_OPERAND_INSTANCE_END; + ++i, ++opinst) + { + if (CGEN_OPERAND_INSTANCE_TYPE (opinst) == CGEN_OPERAND_INSTANCE_OUTPUT) + trace_result (cpu, current_insn, opinst, indices[i]); + } + } + } #endif - ); + + /* Print anything else requested. */ + + if (*trace_buf) + trace_printf (sd, cpu, " %s\n", trace_buf); + else + trace_printf (sd, cpu, "\n"); +} + +void +trace_insn (SIM_CPU *cpu, const struct cgen_insn *opcode, + const struct argbuf *abuf, PCADDR pc) +{ + char disasm_buf[50]; printed_result_p = 0; + current_insn = opcode; + current_abuf = abuf; + + if (CGEN_INSN_VIRTUAL_P (opcode)) + { + trace_prefix (CPU_STATE (cpu), cpu, NULL_CIA, (address_word) 0, 0, + NULL, 0, CGEN_INSN_NAME (opcode)); + return; + } + + sim_disassemble_insn (cpu, opcode, abuf, pc, disasm_buf, &insn_fields); + trace_prefix (CPU_STATE (cpu), cpu, NULL_CIA, pc, TRACE_LINENUM_P (cpu), + NULL, 0, + "%s%-*s", + first_insn_p ? " " : "|", + SIZE_INSTRUCTION, disasm_buf); } void @@ -169,7 +187,8 @@ trace_extract (SIM_CPU *cpu, PCADDR pc, char *name, ...) va_start (args, name); - trace_printf (CPU_STATE (cpu), cpu, "Extract: 0x%.*x: %s ", SIZE_PC, pc, name); + trace_printf (CPU_STATE (cpu), cpu, "Extract: 0x%.*lx: %s ", + SIZE_PC, pc, name); do { int type,ival; @@ -206,6 +225,7 @@ trace_result (SIM_CPU *cpu, char *name, int type, ...) va_start (args, type); if (printed_result_p) cgen_trace_printf (cpu, ", "); + switch (type) { case 'x' : @@ -222,6 +242,7 @@ trace_result (SIM_CPU *cpu, char *name, int type, ...) break; } } + printed_result_p = 1; va_end (args); } @@ -248,6 +269,9 @@ cgen_trace_printf (SIM_CPU *cpu, char *fmt, ...) { vsprintf (bufptr, fmt, args); bufptr += strlen (bufptr); + /* ??? Need version of SIM_ASSERT that is always enabled. */ + if (bufptr - trace_buf > SIZE_TRACE_BUF) + abort (); } va_end (args); |