1 /* Tracing support for CGEN-based simulators.
2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
5 This file is part of GDB, the GNU debugger.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25 #ifndef SIZE_INSTRUCTION
26 #define SIZE_INSTRUCTION 16
30 #define SIZE_LOCATION 20
37 #ifndef SIZE_LINE_NUMBER
38 #define SIZE_LINE_NUMBER 4
41 #ifndef SIZE_CYCLE_COUNT
42 #define SIZE_CYCLE_COUNT 2
45 #ifndef SIZE_TOTAL_CYCLE_COUNT
46 #define SIZE_TOTAL_CYCLE_COUNT 9
49 /* Text is queued in TRACE_BUF because we want to output the insn's cycle
50 count first but that isn't known until after the insn has executed. */
51 static char trace_buf[1024];
52 /* If NULL, output to stdout directly. */
55 /* For computing an instruction's cycle count.
56 FIXME: Need to move into cpu struct for smp case. */
57 static unsigned long last_cycle_count;
60 trace_insn_init (SIM_CPU *cpu)
67 trace_insn_fini (SIM_CPU *cpu)
69 if (CPU_PROFILE_FLAGS (cpu) [PROFILE_MODEL_IDX])
71 unsigned long total = PROFILE_TOTAL_CYCLE_COUNT (CPU_PROFILE_DATA (cpu));
72 trace_printf (cpu, "%-*ld %-*ld ",
73 SIZE_CYCLE_COUNT, total - last_cycle_count,
74 SIZE_TOTAL_CYCLE_COUNT, total);
75 last_cycle_count = total;
78 trace_printf (cpu, "%s\n", trace_buf);
81 /* For communication between trace_insn and trace_result. */
82 static int printed_result_p;
85 trace_insn (SIM_CPU *cpu, const struct cgen_insn *opcode,
86 const struct argbuf *abuf, PCADDR pc)
89 const char *functionname;
90 unsigned int linenumber;
91 char *p, buf[256], disasm_buf[50];
93 if (! TRACE_P (cpu, TRACE_LINENUM_IDX))
95 cgen_trace_printf (cpu, "0x%.*x %-*s ",
96 SIZE_PC, (unsigned) pc,
98 CGEN_INSN_SYNTAX (opcode)->mnemonic);
104 if (STATE_TEXT_SECTION (CPU_STATE (cpu))
105 && pc >= STATE_TEXT_START (CPU_STATE (cpu))
106 && pc < STATE_TEXT_END (CPU_STATE (cpu)))
108 filename = (const char *) 0;
109 functionname = (const char *) 0;
111 if (bfd_find_nearest_line (STATE_PROG_BFD (CPU_STATE (cpu)),
112 STATE_TEXT_SECTION (CPU_STATE (cpu)),
113 (struct symbol_cache_entry **) 0,
114 pc - STATE_TEXT_START (CPU_STATE (cpu)),
115 &filename, &functionname, &linenumber))
120 sprintf (p, "#%-*d ", SIZE_LINE_NUMBER, linenumber);
125 sprintf (p, "%-*s ", SIZE_LINE_NUMBER+1, "---");
126 p += SIZE_LINE_NUMBER+2;
131 sprintf (p, "%s ", functionname);
136 char *q = (char *) strrchr (filename, '/');
137 sprintf (p, "%s ", (q) ? q+1 : filename);
146 sim_disassemble_insn (opcode, abuf, pc, disasm_buf);
148 cgen_trace_printf (cpu, "0x%.*x %-*.*s %-*s ",
149 SIZE_PC, (unsigned) pc,
150 SIZE_LOCATION, SIZE_LOCATION, buf,
153 CGEN_INSN_SYNTAX (opcode)->mnemonic
159 printed_result_p = 0;
163 trace_extract (SIM_CPU *cpu, PCADDR pc, char *name, ...)
166 int printed_one_p = 0;
169 va_start (args, name);
171 trace_printf (cpu, "Extract: 0x%.*x: %s ", SIZE_PC, pc, name);
176 fmt = va_arg (args, char *);
181 trace_printf (cpu, ", ");
183 type = va_arg (args, int);
187 ival = va_arg (args, int);
188 trace_printf (cpu, fmt, ival);
197 trace_printf (cpu, "\n");
201 trace_result (SIM_CPU *cpu, char *name, int type, ...)
205 va_start (args, type);
206 if (printed_result_p)
207 cgen_trace_printf (cpu, ", ");
212 cgen_trace_printf (cpu, "%s <- 0x%x", name, va_arg (args, int));
217 /* this is separated from previous line for sunos cc */
218 di = va_arg (args, DI);
219 cgen_trace_printf (cpu, "%s <- 0x%x%08x", name,
220 GETHIDI(di), GETLODI (di));
224 printed_result_p = 1;
228 /* Print trace output to BUFPTR if active, otherwise print normally.
229 This is only for tracing semantic code. */
232 cgen_trace_printf (SIM_CPU *cpu, char *fmt, ...)
236 va_start (args, fmt);
240 if (TRACE_FILE (CPU_TRACE_DATA (cpu)) == NULL)
241 (* STATE_CALLBACK (CPU_STATE (cpu))->evprintf_filtered)
242 (STATE_CALLBACK (CPU_STATE (cpu)), fmt, args);
244 vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu)), fmt, args);
248 vsprintf (bufptr, fmt, args);
249 bufptr += strlen (bufptr);