diff options
author | Andrew Cagney <cagney@redhat.com> | 1998-02-18 04:11:09 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 1998-02-18 04:11:09 +0000 |
commit | 8dcc896d0e023cc7837370e4c186a7170400cff0 (patch) | |
tree | 695953f317cfa5a70f09d2bc76e3ef0c7ed66894 /sim/common/sim-trace.c | |
parent | 587137649429ea2e65ca518d9578e1607728ecdc (diff) | |
download | gdb-8dcc896d0e023cc7837370e4c186a7170400cff0.zip gdb-8dcc896d0e023cc7837370e4c186a7170400cff0.tar.gz gdb-8dcc896d0e023cc7837370e4c186a7170400cff0.tar.bz2 |
Extend sim-trace.[hc] to include a generic set of macro's for tracing
ALU/... inputs/outputs.
Base implementation on original v850 code.
Update igen to generate code interfacing with newer sim-trace.[hc].
Diffstat (limited to 'sim/common/sim-trace.c')
-rw-r--r-- | sim/common/sim-trace.c | 565 |
1 files changed, 530 insertions, 35 deletions
diff --git a/sim/common/sim-trace.c b/sim/common/sim-trace.c index 5f3dd13..d53afda 100644 --- a/sim/common/sim-trace.c +++ b/sim/common/sim-trace.c @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "sim-main.h" #include "sim-io.h" #include "sim-options.h" +#include "sim-fpu.h" #include "bfd.h" #include "sim-assert.h" @@ -72,45 +73,46 @@ enum { static const OPTION trace_options[] = { + /* This table is organized to group related instructions together. */ { {"trace", optional_argument, NULL, 't'}, - 't', "on|off", "Perform tracing", + 't', "on|off", "Trace everything", trace_option_handler }, { {"trace-insn", optional_argument, NULL, OPTION_TRACE_INSN}, '\0', "on|off", "Perform instruction tracing", trace_option_handler }, { {"trace-decode", optional_argument, NULL, OPTION_TRACE_DECODE}, - '\0', "on|off", "Perform instruction decoding tracing", + '\0', "on|off", "Trace instruction decoding", trace_option_handler }, { {"trace-extract", optional_argument, NULL, OPTION_TRACE_EXTRACT}, - '\0', "on|off", "Perform instruction extraction tracing", + '\0', "on|off", "Trace instruction extraction", trace_option_handler }, { {"trace-linenum", optional_argument, NULL, OPTION_TRACE_LINENUM}, '\0', "on|off", "Perform line number tracing (implies --trace-insn)", trace_option_handler }, { {"trace-memory", optional_argument, NULL, OPTION_TRACE_MEMORY}, - '\0', "on|off", "Perform memory tracing", - trace_option_handler }, - { {"trace-model", optional_argument, NULL, OPTION_TRACE_MODEL}, - '\0', "on|off", "Perform model tracing", + '\0', "on|off", "Trace memory operations", trace_option_handler }, { {"trace-alu", optional_argument, NULL, OPTION_TRACE_ALU}, - '\0', "on|off", "Perform ALU tracing", - trace_option_handler }, - { {"trace-core", optional_argument, NULL, OPTION_TRACE_CORE}, - '\0', "on|off", "Perform CORE tracing", - trace_option_handler }, - { {"trace-events", optional_argument, NULL, OPTION_TRACE_EVENTS}, - '\0', "on|off", "Perform EVENTS tracing", + '\0', "on|off", "Trace ALU operations", trace_option_handler }, { {"trace-fpu", optional_argument, NULL, OPTION_TRACE_FPU}, - '\0', "on|off", "Perform FPU tracing", + '\0', "on|off", "Trace FPU operations", trace_option_handler }, { {"trace-branch", optional_argument, NULL, OPTION_TRACE_BRANCH}, - '\0', "on|off", "Perform branch tracing", + '\0', "on|off", "Trace branching", trace_option_handler }, { {"trace-semantics", optional_argument, NULL, OPTION_TRACE_SEMANTICS}, '\0', "on|off", "Perform ALU, FPU, MEMORY, and BRANCH tracing", trace_option_handler }, + { {"trace-model", optional_argument, NULL, OPTION_TRACE_MODEL}, + '\0', "on|off", "Include model performance data", + trace_option_handler }, + { {"trace-core", optional_argument, NULL, OPTION_TRACE_CORE}, + '\0', "on|off", "Trace core operations", + trace_option_handler }, + { {"trace-events", optional_argument, NULL, OPTION_TRACE_EVENTS}, + '\0', "on|off", "Trace events", + trace_option_handler }, { {"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 }, @@ -366,6 +368,518 @@ trace_uninstall (SIM_DESC sd) } } +typedef enum { + trace_fmt_invalid, + trace_fmt_word, + trace_fmt_fp, + trace_fmt_fpu, + trace_fmt_string, + trace_fmt_instruction_incomplete, +} data_fmt; + +/* compute the nr of trace data units consumed by data */ +static int +save_data_size (TRACE_DATA *data, + long size) +{ + return ((size + sizeof (TRACE_INPUT_DATA (data) [0]) - 1) + / sizeof (TRACE_INPUT_DATA (data) [0])); +} + + +/* Archive DATA into the trace buffer */ +static void +save_data (SIM_DESC sd, + TRACE_DATA *data, + data_fmt fmt, + long size, + void *buf) +{ + int i = TRACE_INPUT_IDX (data); + if (i == sizeof (TRACE_INPUT_FMT (data))) + sim_io_error (sd, "trace buffer overflow"); + TRACE_INPUT_FMT (data) [i] = fmt; + TRACE_INPUT_SIZE (data) [i] = size; + memcpy (&TRACE_INPUT_DATA (data) [i], buf, size); + i += save_data_size (data, size); + TRACE_INPUT_IDX (data) = i; +} + +static void +print_data (SIM_DESC sd, + sim_cpu *cpu, + data_fmt fmt, + long size, + void *data) +{ + switch (fmt) + { + case trace_fmt_instruction_incomplete: + trace_printf (sd, cpu, " (instruction incomplete)"); + break; + case trace_fmt_word: + switch (size) + { + case sizeof (unsigned_word): + trace_printf (sd, cpu, " 0x%08lx", (long) * (unsigned_word*) data); + break; + default: + abort (); + } + break; + case trace_fmt_fp: + switch (size) + { + /* FIXME: Assumes sizeof float == 4; sizeof double == 8 */ + case 4: + trace_printf (sd, cpu, " %8g", * (float*) data); + break; + case 8: + trace_printf (sd, cpu, " %8g", * (double*) data); + break; + default: + abort (); + } + case trace_fmt_fpu: + /* FIXME: At present sim_fpu data is stored as a double */ + trace_printf (sd, cpu, " %8g", * (double*) data); + break; + case trace_fmt_string: + trace_printf (sd, cpu, " %-8s", (char*) data); + break; + default: + abort (); + } +} + +static const char * +trace_idx_to_str (int trace_idx) +{ + static char num[8]; + switch (trace_idx) + { + case TRACE_ALU_IDX: return "alu: "; + case TRACE_INSN_IDX: return "insn: "; + case TRACE_DECODE_IDX: return "decode: "; + case TRACE_EXTRACT_IDX: return "extract: "; + case TRACE_MEMORY_IDX: return "memory: "; + case TRACE_CORE_IDX: return "core: "; + case TRACE_EVENTS_IDX: return "events: "; + case TRACE_FPU_IDX: return "fpu: "; + case TRACE_BRANCH_IDX: return "branch: "; + default: + sprintf (num, "?%d?", trace_idx); + return num; + } +} + +static void +trace_results (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + int last_input) +{ + TRACE_DATA *data = CPU_TRACE_DATA (cpu); + int nr_out; + int i; + + /* cross check trace_idx against TRACE_IDX (data)? */ + + /* prefix */ + trace_printf (sd, cpu, "%s %s", + trace_idx_to_str (TRACE_IDX (data)), + TRACE_PREFIX (data)); + TRACE_IDX (data) = 0; + + for (i = 0, nr_out = 0; + i < TRACE_INPUT_IDX (data); + i += save_data_size (data, TRACE_INPUT_SIZE (data) [i]), nr_out++) + { + if (i == last_input) + { + int pad = (strlen (" 0x") + sizeof (unsigned_word) * 2); + int padding = pad * (3 - nr_out); + if (padding < 0) + padding = 0; + padding += strlen (" ::"); + trace_printf (sd, cpu, "%*s", padding, " ::"); + } + print_data (sd, cpu, + TRACE_INPUT_FMT (data) [i], + TRACE_INPUT_SIZE (data) [i], + &TRACE_INPUT_DATA (data) [i]); + } + trace_printf (sd, cpu, "\n"); +} + +void +trace_prefix (SIM_DESC sd, + sim_cpu *cpu, + address_word pc, + int line_p, + const char *filename, + int linenum, + const char *fmt, + ...) +{ + TRACE_DATA *data = CPU_TRACE_DATA (cpu); + va_list ap; + char *prefix = TRACE_PREFIX (data); + char *chp; + + /* if the previous trace data wasn't flused, flush it now with a + note indicating that this occured. */ + if (TRACE_IDX (data) != 0) + { + int last_input = TRACE_INPUT_IDX (data); + save_data (sd, data, trace_fmt_instruction_incomplete, 1, ""); + trace_results (sd, cpu, TRACE_IDX (data), last_input); + } + TRACE_IDX (data) = 0; + TRACE_INPUT_IDX (data) = 0; + + if (!line_p) + { + sprintf (prefix, "%s:%-*d 0x%.*lx ", + filename, + SIZE_LINE_NUMBER, linenum, + SIZE_PC, (long)pc); + chp = strchr (prefix, '\0'); + va_start (ap, fmt); + vsprintf (chp, fmt, ap); + va_end (ap); + } + else + { + char buf[256]; + buf[0] = 0; + if (STATE_TEXT_SECTION (CPU_STATE (cpu)) + && pc >= STATE_TEXT_START (CPU_STATE (cpu)) + && pc < STATE_TEXT_END (CPU_STATE (cpu))) + { + const char *pc_filename = (const char *)0; + const char *pc_function = (const char *)0; + unsigned int pc_linenum = 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)), + &pc_filename, &pc_function, &pc_linenum)) + { + char *p = buf; + if (pc_linenum) + { + sprintf (p, "#%-*d ", SIZE_LINE_NUMBER, pc_linenum); + p += strlen (p); + } + else + { + sprintf (p, "%-*s ", SIZE_LINE_NUMBER+1, "---"); + p += SIZE_LINE_NUMBER+2; + } + + if (pc_function) + { + sprintf (p, "%s ", pc_function); + p += strlen (p); + } + else if (pc_filename) + { + char *q = (char *) strrchr (pc_filename, '/'); + sprintf (p, "%s ", (q) ? q+1 : pc_filename); + p += strlen (p); + } + + if (*p == ' ') + *p = '\0'; + } + } + + sprintf (prefix, "0x%.*x %-*.*s ", + SIZE_PC, (unsigned) pc, + SIZE_LOCATION, SIZE_LOCATION, buf); + chp = strchr (prefix, '\0'); + va_start (ap, fmt); + vsprintf (chp, fmt, ap); + 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 + chp = strchr (prefix, '\0'); + if (chp - prefix < TRACE_PREFIX_WIDTH) + { + memset (chp, ' ', TRACE_PREFIX_WIDTH - (chp - prefix)); + chp = &prefix [TRACE_PREFIX_WIDTH]; + *chp = '\0'; + } + strcpy (chp, " -"); + + /* check that we've not over flowed the prefix buffer */ + if (strlen (prefix) >= sizeof (TRACE_PREFIX (data))) + abort (); +} + +void +trace_generic (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + char *fmt, + ...) +{ + va_list ap; + trace_printf (sd, cpu, "%s %s", + trace_idx_to_str (trace_idx), + TRACE_PREFIX (CPU_TRACE_DATA (cpu))); + va_start (ap, fmt); + trace_vprintf (sd, cpu, fmt, ap); + va_end (ap); + trace_printf (sd, cpu, "\n"); +} + +void +trace_input0 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx) +{ + TRACE_DATA *data = CPU_TRACE_DATA (cpu); + TRACE_IDX (data) = trace_idx; +} + +void +trace_input_word1 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + unsigned_word d0) +{ + TRACE_DATA *data = CPU_TRACE_DATA (cpu); + TRACE_IDX (data) = trace_idx; + save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0); +} + +void +trace_input_word2 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + unsigned_word d0, + unsigned_word d1) +{ + TRACE_DATA *data = CPU_TRACE_DATA (cpu); + TRACE_IDX (data) = trace_idx; + save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0); + save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d1); +} + +void +trace_input_word3 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + unsigned_word d0, + unsigned_word d1, + unsigned_word d2) +{ + TRACE_DATA *data = CPU_TRACE_DATA (cpu); + TRACE_IDX (data) = trace_idx; + save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0); + save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d1); + save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d2); +} + +void +trace_input_fp1 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + fp_word f0) +{ + TRACE_DATA *data = CPU_TRACE_DATA (cpu); + TRACE_IDX (data) = trace_idx; + save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0); +} + +void +trace_input_fp2 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + fp_word f0, + fp_word f1) +{ + TRACE_DATA *data = CPU_TRACE_DATA (cpu); + TRACE_IDX (data) = trace_idx; + save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0); + save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f1); +} + +void +trace_input_fp3 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + fp_word f0, + fp_word f1, + fp_word f2) +{ + TRACE_DATA *data = CPU_TRACE_DATA (cpu); + TRACE_IDX (data) = trace_idx; + save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0); + save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f1); + save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f2); +} + +void +trace_input_fpu1 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + sim_fpu *f0) +{ + double d; + TRACE_DATA *data = CPU_TRACE_DATA (cpu); + TRACE_IDX (data) = trace_idx; + d = sim_fpu_2d (f0); + save_data (sd, data, trace_fmt_fp, sizeof (double), &d); +} + +void +trace_input_fpu2 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + sim_fpu *f0, + sim_fpu *f1) +{ + double d; + TRACE_DATA *data = CPU_TRACE_DATA (cpu); + TRACE_IDX (data) = trace_idx; + d = sim_fpu_2d (f0); + save_data (sd, data, trace_fmt_fp, sizeof (double), &d); + d = sim_fpu_2d (f1); + save_data (sd, data, trace_fmt_fp, sizeof (double), &d); +} + +void +trace_input_fpu3 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + sim_fpu *f0, + sim_fpu *f1, + sim_fpu *f2) +{ + double d; + TRACE_DATA *data = CPU_TRACE_DATA (cpu); + TRACE_IDX (data) = trace_idx; + d = sim_fpu_2d (f0); + save_data (sd, data, trace_fmt_fp, sizeof (double), &d); + d = sim_fpu_2d (f1); + save_data (sd, data, trace_fmt_fp, sizeof (double), &d); + d = sim_fpu_2d (f2); + save_data (sd, data, trace_fmt_fp, sizeof (double), &d); +} + +void +trace_result_word1 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + unsigned_word r0) +{ + 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_word, sizeof (unsigned_word), &r0); + + trace_results (sd, cpu, trace_idx, last_input); +} + +void +trace_result_fp1 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + fp_word f0) +{ + 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 (fp_word), &f0); + + trace_results (sd, cpu, trace_idx, last_input); +} + +void +trace_result_fpu1 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + sim_fpu *f0) +{ + double d; + 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); + d = sim_fpu_2d (f0); + save_data (sd, data, trace_fmt_fp, sizeof (double), &d); + + trace_results (sd, cpu, trace_idx, last_input); +} + +void +trace_result_string1 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + char *s0) +{ + 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_string, strlen (s0) + 1, s0); + + trace_results (sd, cpu, trace_idx, last_input); +} + +void +trace_result_word1_string1 (SIM_DESC sd, + sim_cpu *cpu, + int trace_idx, + unsigned_word r0, + char *s0) +{ + 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_word, sizeof (unsigned_word), &r0); + save_data (sd, data, trace_fmt_string, strlen (s0) + 1, s0); + + trace_results (sd, cpu, trace_idx, last_input); +} + +void +trace_vprintf (SIM_DESC sd, sim_cpu *cpu, const char *fmt, va_list ap) +{ + if (cpu != NULL) + { + if (TRACE_FILE (CPU_TRACE_DATA (cpu)) != NULL) + vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu)), fmt, ap); + else + sim_io_evprintf (sd, fmt, ap); + } + else + { + if (TRACE_FILE (STATE_TRACE_DATA (sd)) != NULL) + vfprintf (TRACE_FILE (STATE_TRACE_DATA (sd)), fmt, ap); + else + sim_io_evprintf (sd, fmt, ap); + } +} + void trace_one_insn (SIM_DESC sd, sim_cpu *cpu, address_word pc, int line_p, const char *filename, int linenum, @@ -448,25 +962,6 @@ trace_one_insn (SIM_DESC sd, sim_cpu *cpu, address_word pc, trace_printf (sd, cpu, "\n"); } } - -void -trace_vprintf (SIM_DESC sd, sim_cpu *cpu, const char *fmt, va_list ap) -{ - if (cpu != NULL) - { - if (TRACE_FILE (CPU_TRACE_DATA (cpu)) != NULL) - vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu)), fmt, ap); - else - sim_io_evprintf (sd, fmt, ap); - } - else - { - if (TRACE_FILE (STATE_TRACE_DATA (sd)) != NULL) - vfprintf (TRACE_FILE (STATE_TRACE_DATA (sd)), fmt, ap); - else - sim_io_evprintf (sd, fmt, ap); - } -} void trace_printf VPARAMS ((SIM_DESC sd, sim_cpu *cpu, const char *fmt, ...)) |