* A few more improvements to gx jit prototype.
[deliverable/binutils-gdb.git] / sim / common / cgen-trace.c
CommitLineData
b9c8cd10
DE
1/* Tracing support for CGEN-based simulators.
2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License along
18with this program; if not, write to the Free Software Foundation, Inc.,
1959 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#include "sim-main.h"
22#include "bfd.h"
23#include "cpu-opc.h"
24
25#ifndef SIZE_INSTRUCTION
26#define SIZE_INSTRUCTION 16
27#endif
28
29#ifndef SIZE_LOCATION
30#define SIZE_LOCATION 20
31#endif
32
33#ifndef SIZE_PC
34#define SIZE_PC 6
35#endif
36
37#ifndef SIZE_LINE_NUMBER
38#define SIZE_LINE_NUMBER 4
39#endif
40
41#ifndef SIZE_CYCLE_COUNT
42#define SIZE_CYCLE_COUNT 2
43#endif
44
45#ifndef SIZE_TOTAL_CYCLE_COUNT
46#define SIZE_TOTAL_CYCLE_COUNT 9
47#endif
48
49/* Text is queued in TRACE_BUF because we want to output the insn's cycle
c967f187 50 count first but that isn't known until after the insn has executed. */
b9c8cd10
DE
51static char trace_buf[1024];
52/* If NULL, output to stdout directly. */
53static char *bufptr;
54
55/* For computing an instruction's cycle count.
56 FIXME: Need to move into cpu struct for smp case. */
57static unsigned long last_cycle_count;
58
59void
bcb829fd 60trace_insn_init (SIM_CPU *cpu, int first_p)
b9c8cd10
DE
61{
62 bufptr = trace_buf;
63 *bufptr = 0;
64}
65
66void
bcb829fd 67trace_insn_fini (SIM_CPU *cpu, int last_p)
b9c8cd10
DE
68{
69 if (CPU_PROFILE_FLAGS (cpu) [PROFILE_MODEL_IDX])
70 {
71 unsigned long total = PROFILE_TOTAL_CYCLE_COUNT (CPU_PROFILE_DATA (cpu));
ef13d3e3 72 trace_printf (CPU_STATE (cpu), cpu, "%-*ld %-*ld ",
c967f187
DE
73 SIZE_CYCLE_COUNT, total - last_cycle_count,
74 SIZE_TOTAL_CYCLE_COUNT, total);
b9c8cd10
DE
75 last_cycle_count = total;
76 }
77
ef13d3e3 78 trace_printf (CPU_STATE (cpu), cpu, "%s\n", trace_buf);
b9c8cd10
DE
79}
80
81/* For communication between trace_insn and trace_result. */
82static int printed_result_p;
83
84void
85trace_insn (SIM_CPU *cpu, const struct cgen_insn *opcode,
86 const struct argbuf *abuf, PCADDR pc)
87{
88 const char *filename;
89 const char *functionname;
90 unsigned int linenumber;
91 char *p, buf[256], disasm_buf[50];
92
93 if (! TRACE_P (cpu, TRACE_LINENUM_IDX))
94 {
95 cgen_trace_printf (cpu, "0x%.*x %-*s ",
96 SIZE_PC, (unsigned) pc,
97 SIZE_INSTRUCTION,
ef13d3e3 98 CGEN_INSN_MNEMONIC (opcode));
bcb829fd 99 printed_result_p = 0;
b9c8cd10
DE
100 return;
101 }
102
103 buf[0] = 0;
104
105 if (STATE_TEXT_SECTION (CPU_STATE (cpu))
106 && pc >= STATE_TEXT_START (CPU_STATE (cpu))
107 && pc < STATE_TEXT_END (CPU_STATE (cpu)))
108 {
109 filename = (const char *) 0;
110 functionname = (const char *) 0;
111 linenumber = 0;
112 if (bfd_find_nearest_line (STATE_PROG_BFD (CPU_STATE (cpu)),
113 STATE_TEXT_SECTION (CPU_STATE (cpu)),
114 (struct symbol_cache_entry **) 0,
115 pc - STATE_TEXT_START (CPU_STATE (cpu)),
116 &filename, &functionname, &linenumber))
117 {
118 p = buf;
119 if (linenumber)
120 {
121 sprintf (p, "#%-*d ", SIZE_LINE_NUMBER, linenumber);
122 p += strlen (p);
123 }
124 else
125 {
126 sprintf (p, "%-*s ", SIZE_LINE_NUMBER+1, "---");
127 p += SIZE_LINE_NUMBER+2;
128 }
129
130 if (functionname)
131 {
132 sprintf (p, "%s ", functionname);
133 p += strlen (p);
134 }
135 else if (filename)
136 {
137 char *q = (char *) strrchr (filename, '/');
138 sprintf (p, "%s ", (q) ? q+1 : filename);
139 p += strlen (p);
140 }
141
142 if (*p == ' ')
143 *p = '\0';
144 }
145 }
146
ef13d3e3 147 sim_disassemble_insn (cpu, opcode, abuf, pc, disasm_buf);
b9c8cd10
DE
148
149 cgen_trace_printf (cpu, "0x%.*x %-*.*s %-*s ",
150 SIZE_PC, (unsigned) pc,
151 SIZE_LOCATION, SIZE_LOCATION, buf,
152 SIZE_INSTRUCTION,
153#if 0
bcb829fd 154 CGEN_INSN_NAME (opcode)
b9c8cd10
DE
155#else
156 disasm_buf
157#endif
158 );
159
160 printed_result_p = 0;
161}
162
163void
164trace_extract (SIM_CPU *cpu, PCADDR pc, char *name, ...)
165{
166 va_list args;
167 int printed_one_p = 0;
168 char *fmt;
169
170 va_start (args, name);
171
ef13d3e3 172 trace_printf (CPU_STATE (cpu), cpu, "Extract: 0x%.*x: %s ", SIZE_PC, pc, name);
b9c8cd10
DE
173
174 do {
175 int type,ival;
176
177 fmt = va_arg (args, char *);
178
179 if (fmt)
180 {
181 if (printed_one_p)
ef13d3e3 182 trace_printf (CPU_STATE (cpu), cpu, ", ");
b9c8cd10
DE
183 printed_one_p = 1;
184 type = va_arg (args, int);
185 switch (type)
186 {
187 case 'x' :
188 ival = va_arg (args, int);
ef13d3e3 189 trace_printf (CPU_STATE (cpu), cpu, fmt, ival);
b9c8cd10
DE
190 break;
191 default :
192 abort ();
193 }
194 }
195 } while (fmt);
196
197 va_end (args);
ef13d3e3 198 trace_printf (CPU_STATE (cpu), cpu, "\n");
b9c8cd10
DE
199}
200
201void
202trace_result (SIM_CPU *cpu, char *name, int type, ...)
203{
204 va_list args;
205
206 va_start (args, type);
207 if (printed_result_p)
208 cgen_trace_printf (cpu, ", ");
209 switch (type)
210 {
211 case 'x' :
212 default :
213 cgen_trace_printf (cpu, "%s <- 0x%x", name, va_arg (args, int));
214 break;
215 case 'D' :
216 {
217 DI di;
218 /* this is separated from previous line for sunos cc */
219 di = va_arg (args, DI);
220 cgen_trace_printf (cpu, "%s <- 0x%x%08x", name,
221 GETHIDI(di), GETLODI (di));
222 break;
223 }
224 }
225 printed_result_p = 1;
226 va_end (args);
227}
228
c967f187
DE
229/* Print trace output to BUFPTR if active, otherwise print normally.
230 This is only for tracing semantic code. */
231
b9c8cd10
DE
232void
233cgen_trace_printf (SIM_CPU *cpu, char *fmt, ...)
234{
235 va_list args;
236
237 va_start (args, fmt);
238
239 if (bufptr == NULL)
240 {
241 if (TRACE_FILE (CPU_TRACE_DATA (cpu)) == NULL)
242 (* STATE_CALLBACK (CPU_STATE (cpu))->evprintf_filtered)
243 (STATE_CALLBACK (CPU_STATE (cpu)), fmt, args);
244 else
245 vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu)), fmt, args);
246 }
247 else
248 {
249 vsprintf (bufptr, fmt, args);
250 bufptr += strlen (bufptr);
251 }
252
253 va_end (args);
254}
This page took 0.077825 seconds and 4 git commands to generate.