sim-trace.c revision 1.1.1.6 1 1.1 christos /* Simulator tracing/debugging support.
2 1.1.1.6 christos Copyright (C) 1997-2016 Free Software Foundation, Inc.
3 1.1 christos Contributed by Cygnus Support.
4 1.1 christos
5 1.1 christos This file is part of GDB, the GNU debugger.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos #include "sim-main.h"
21 1.1 christos #include "sim-io.h"
22 1.1 christos #include "sim-options.h"
23 1.1 christos #include "sim-fpu.h"
24 1.1 christos
25 1.1 christos #include "bfd.h"
26 1.1 christos #include "libiberty.h"
27 1.1 christos
28 1.1.1.6 christos #include "dis-asm.h"
29 1.1.1.6 christos
30 1.1 christos #include "sim-assert.h"
31 1.1 christos
32 1.1 christos #ifdef HAVE_STRING_H
33 1.1 christos #include <string.h>
34 1.1 christos #else
35 1.1 christos #ifdef HAVE_STRINGS_H
36 1.1 christos #include <strings.h>
37 1.1 christos #endif
38 1.1 christos #endif
39 1.1 christos #ifdef HAVE_STDLIB_H
40 1.1 christos #include <stdlib.h>
41 1.1 christos #endif
42 1.1 christos
43 1.1 christos #ifndef SIZE_PHASE
44 1.1 christos #define SIZE_PHASE 8
45 1.1 christos #endif
46 1.1 christos
47 1.1 christos #ifndef SIZE_LOCATION
48 1.1 christos #define SIZE_LOCATION 20
49 1.1 christos #endif
50 1.1 christos
51 1.1 christos #ifndef SIZE_PC
52 1.1 christos #define SIZE_PC 6
53 1.1 christos #endif
54 1.1 christos
55 1.1 christos #ifndef SIZE_LINE_NUMBER
56 1.1 christos #define SIZE_LINE_NUMBER 4
57 1.1 christos #endif
58 1.1 christos
59 1.1 christos static MODULE_INIT_FN trace_init;
60 1.1 christos static MODULE_UNINSTALL_FN trace_uninstall;
61 1.1 christos
62 1.1 christos static DECLARE_OPTION_HANDLER (trace_option_handler);
63 1.1 christos
64 1.1 christos enum {
65 1.1 christos OPTION_TRACE_INSN = OPTION_START,
66 1.1.1.6 christos OPTION_TRACE_DISASM,
67 1.1 christos OPTION_TRACE_DECODE,
68 1.1 christos OPTION_TRACE_EXTRACT,
69 1.1 christos OPTION_TRACE_LINENUM,
70 1.1 christos OPTION_TRACE_MEMORY,
71 1.1 christos OPTION_TRACE_MODEL,
72 1.1 christos OPTION_TRACE_ALU,
73 1.1 christos OPTION_TRACE_CORE,
74 1.1 christos OPTION_TRACE_EVENTS,
75 1.1 christos OPTION_TRACE_FPU,
76 1.1 christos OPTION_TRACE_BRANCH,
77 1.1 christos OPTION_TRACE_SEMANTICS,
78 1.1 christos OPTION_TRACE_RANGE,
79 1.1 christos OPTION_TRACE_FUNCTION,
80 1.1 christos OPTION_TRACE_DEBUG,
81 1.1 christos OPTION_TRACE_FILE,
82 1.1.1.2 christos OPTION_TRACE_VPU,
83 1.1.1.5 christos OPTION_TRACE_SYSCALL,
84 1.1.1.5 christos OPTION_TRACE_REGISTER
85 1.1 christos };
86 1.1 christos
87 1.1 christos static const OPTION trace_options[] =
88 1.1 christos {
89 1.1 christos /* This table is organized to group related instructions together. */
90 1.1 christos { {"trace", optional_argument, NULL, 't'},
91 1.1 christos 't', "on|off", "Trace useful things",
92 1.1 christos trace_option_handler, NULL },
93 1.1 christos { {"trace-insn", optional_argument, NULL, OPTION_TRACE_INSN},
94 1.1 christos '\0', "on|off", "Perform instruction tracing",
95 1.1 christos trace_option_handler, NULL },
96 1.1.1.6 christos { {"trace-disasm", optional_argument, NULL, OPTION_TRACE_DISASM},
97 1.1.1.6 christos '\0', "on|off", "Disassemble instructions (slower, but more accurate)",
98 1.1.1.6 christos trace_option_handler, NULL },
99 1.1 christos { {"trace-decode", optional_argument, NULL, OPTION_TRACE_DECODE},
100 1.1 christos '\0', "on|off", "Trace instruction decoding",
101 1.1 christos trace_option_handler, NULL },
102 1.1 christos { {"trace-extract", optional_argument, NULL, OPTION_TRACE_EXTRACT},
103 1.1 christos '\0', "on|off", "Trace instruction extraction",
104 1.1 christos trace_option_handler, NULL },
105 1.1 christos { {"trace-linenum", optional_argument, NULL, OPTION_TRACE_LINENUM},
106 1.1 christos '\0', "on|off", "Perform line number tracing (implies --trace-insn)",
107 1.1 christos trace_option_handler, NULL },
108 1.1 christos { {"trace-memory", optional_argument, NULL, OPTION_TRACE_MEMORY},
109 1.1 christos '\0', "on|off", "Trace memory operations",
110 1.1 christos trace_option_handler, NULL },
111 1.1 christos { {"trace-alu", optional_argument, NULL, OPTION_TRACE_ALU},
112 1.1.1.5 christos '\0', "on|off", "Trace ALU (Arithmetic Logic Unit) operations",
113 1.1 christos trace_option_handler, NULL },
114 1.1 christos { {"trace-fpu", optional_argument, NULL, OPTION_TRACE_FPU},
115 1.1.1.5 christos '\0', "on|off", "Trace FPU (Floating Point Unit) operations",
116 1.1 christos trace_option_handler, NULL },
117 1.1 christos { {"trace-vpu", optional_argument, NULL, OPTION_TRACE_VPU},
118 1.1.1.5 christos '\0', "on|off", "Trace VPU (Vector Processing Unit) operations",
119 1.1 christos trace_option_handler, NULL },
120 1.1 christos { {"trace-branch", optional_argument, NULL, OPTION_TRACE_BRANCH},
121 1.1 christos '\0', "on|off", "Trace branching",
122 1.1 christos trace_option_handler, NULL },
123 1.1 christos { {"trace-semantics", optional_argument, NULL, OPTION_TRACE_SEMANTICS},
124 1.1.1.5 christos '\0', "on|off", "Perform ALU, FPU, VPU, MEMORY, and BRANCH tracing",
125 1.1 christos trace_option_handler, NULL },
126 1.1 christos { {"trace-model", optional_argument, NULL, OPTION_TRACE_MODEL},
127 1.1 christos '\0', "on|off", "Include model performance data",
128 1.1 christos trace_option_handler, NULL },
129 1.1 christos { {"trace-core", optional_argument, NULL, OPTION_TRACE_CORE},
130 1.1 christos '\0', "on|off", "Trace core operations",
131 1.1 christos trace_option_handler, NULL },
132 1.1 christos { {"trace-events", optional_argument, NULL, OPTION_TRACE_EVENTS},
133 1.1 christos '\0', "on|off", "Trace events",
134 1.1 christos trace_option_handler, NULL },
135 1.1.1.2 christos { {"trace-syscall", optional_argument, NULL, OPTION_TRACE_SYSCALL},
136 1.1.1.2 christos '\0', "on|off", "Trace system calls",
137 1.1.1.2 christos trace_option_handler, NULL },
138 1.1.1.5 christos { {"trace-register", optional_argument, NULL, OPTION_TRACE_REGISTER},
139 1.1.1.5 christos '\0', "on|off", "Trace cpu register accesses",
140 1.1.1.5 christos trace_option_handler, NULL },
141 1.1 christos #ifdef SIM_HAVE_ADDR_RANGE
142 1.1 christos { {"trace-range", required_argument, NULL, OPTION_TRACE_RANGE},
143 1.1 christos '\0', "START,END", "Specify range of addresses for instruction tracing",
144 1.1 christos trace_option_handler, NULL },
145 1.1 christos #if 0 /*wip*/
146 1.1 christos { {"trace-function", required_argument, NULL, OPTION_TRACE_FUNCTION},
147 1.1 christos '\0', "FUNCTION", "Specify function to trace",
148 1.1 christos trace_option_handler, NULL },
149 1.1 christos #endif
150 1.1 christos #endif
151 1.1 christos { {"trace-debug", optional_argument, NULL, OPTION_TRACE_DEBUG},
152 1.1 christos '\0', "on|off", "Add information useful for debugging the simulator to the tracing output",
153 1.1 christos trace_option_handler, NULL },
154 1.1 christos { {"trace-file", required_argument, NULL, OPTION_TRACE_FILE},
155 1.1 christos '\0', "FILE NAME", "Specify tracing output file",
156 1.1 christos trace_option_handler, NULL },
157 1.1 christos { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
158 1.1 christos };
159 1.1 christos
160 1.1 christos /* Set/reset the trace options indicated in MASK. */
161 1.1 christos
162 1.1 christos static SIM_RC
163 1.1 christos set_trace_option_mask (SIM_DESC sd, const char *name, int mask, const char *arg)
164 1.1 christos {
165 1.1 christos int trace_nr;
166 1.1 christos int cpu_nr;
167 1.1 christos int trace_val = 1;
168 1.1 christos
169 1.1 christos if (arg != NULL)
170 1.1 christos {
171 1.1 christos if (strcmp (arg, "yes") == 0
172 1.1 christos || strcmp (arg, "on") == 0
173 1.1 christos || strcmp (arg, "1") == 0)
174 1.1 christos trace_val = 1;
175 1.1 christos else if (strcmp (arg, "no") == 0
176 1.1 christos || strcmp (arg, "off") == 0
177 1.1 christos || strcmp (arg, "0") == 0)
178 1.1 christos trace_val = 0;
179 1.1 christos else
180 1.1 christos {
181 1.1 christos sim_io_eprintf (sd, "Argument `%s' for `--trace%s' invalid, one of `on', `off', `yes', `no' expected\n", arg, name);
182 1.1 christos return SIM_RC_FAIL;
183 1.1 christos }
184 1.1 christos }
185 1.1 christos
186 1.1.1.5 christos /* Update applicable trace bits. */
187 1.1 christos for (trace_nr = 0; trace_nr < MAX_TRACE_VALUES; ++trace_nr)
188 1.1 christos {
189 1.1 christos if ((mask & (1 << trace_nr)) == 0)
190 1.1 christos continue;
191 1.1 christos
192 1.1 christos /* Set non-cpu specific values. */
193 1.1.1.5 christos STATE_TRACE_FLAGS (sd)[trace_nr] = trace_val;
194 1.1 christos
195 1.1 christos /* Set cpu values. */
196 1.1 christos for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
197 1.1 christos {
198 1.1 christos CPU_TRACE_FLAGS (STATE_CPU (sd, cpu_nr))[trace_nr] = trace_val;
199 1.1 christos }
200 1.1 christos }
201 1.1 christos
202 1.1 christos /* Re-compute the cpu trace summary. */
203 1.1 christos if (trace_val)
204 1.1 christos {
205 1.1 christos for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
206 1.1 christos CPU_TRACE_DATA (STATE_CPU (sd, cpu_nr))->trace_any_p = 1;
207 1.1 christos }
208 1.1 christos else
209 1.1 christos {
210 1.1 christos for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
211 1.1 christos {
212 1.1 christos CPU_TRACE_DATA (STATE_CPU (sd, cpu_nr))->trace_any_p = 0;
213 1.1 christos for (trace_nr = 0; trace_nr < MAX_TRACE_VALUES; ++trace_nr)
214 1.1 christos {
215 1.1 christos if (CPU_TRACE_FLAGS (STATE_CPU (sd, cpu_nr))[trace_nr])
216 1.1 christos {
217 1.1 christos CPU_TRACE_DATA (STATE_CPU (sd, cpu_nr))->trace_any_p = 1;
218 1.1 christos break;
219 1.1 christos }
220 1.1 christos }
221 1.1 christos }
222 1.1 christos }
223 1.1 christos
224 1.1 christos return SIM_RC_OK;
225 1.1 christos }
226 1.1 christos
227 1.1 christos /* Set one trace option based on its IDX value. */
228 1.1 christos
229 1.1 christos static SIM_RC
230 1.1 christos set_trace_option (SIM_DESC sd, const char *name, int idx, const char *arg)
231 1.1 christos {
232 1.1 christos return set_trace_option_mask (sd, name, 1 << idx, arg);
233 1.1 christos }
234 1.1 christos
235 1.1 christos
236 1.1 christos static SIM_RC
237 1.1 christos trace_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
238 1.1 christos char *arg, int is_command)
239 1.1 christos {
240 1.1 christos int n;
241 1.1 christos
242 1.1 christos switch (opt)
243 1.1 christos {
244 1.1 christos case 't' :
245 1.1.1.5 christos if (!WITH_TRACE_ANY_P)
246 1.1 christos sim_io_eprintf (sd, "Tracing not compiled in, `-t' ignored\n");
247 1.1 christos else
248 1.1 christos return set_trace_option_mask (sd, "trace", TRACE_USEFUL_MASK, arg);
249 1.1 christos break;
250 1.1 christos
251 1.1 christos case OPTION_TRACE_INSN :
252 1.1 christos if (WITH_TRACE_INSN_P)
253 1.1 christos return set_trace_option (sd, "-insn", TRACE_INSN_IDX, arg);
254 1.1 christos else
255 1.1 christos sim_io_eprintf (sd, "Instruction tracing not compiled in, `--trace-insn' ignored\n");
256 1.1 christos break;
257 1.1 christos
258 1.1.1.6 christos case OPTION_TRACE_DISASM :
259 1.1.1.6 christos if (WITH_TRACE_DISASM_P)
260 1.1.1.6 christos return set_trace_option (sd, "-disasm", TRACE_DISASM_IDX, arg);
261 1.1.1.6 christos else
262 1.1.1.6 christos sim_io_eprintf (sd, "Instruction tracing not compiled in, `--trace-disasm' ignored\n");
263 1.1.1.6 christos break;
264 1.1.1.6 christos
265 1.1 christos case OPTION_TRACE_DECODE :
266 1.1 christos if (WITH_TRACE_DECODE_P)
267 1.1 christos return set_trace_option (sd, "-decode", TRACE_DECODE_IDX, arg);
268 1.1 christos else
269 1.1 christos sim_io_eprintf (sd, "Decode tracing not compiled in, `--trace-decode' ignored\n");
270 1.1 christos break;
271 1.1 christos
272 1.1 christos case OPTION_TRACE_EXTRACT :
273 1.1 christos if (WITH_TRACE_EXTRACT_P)
274 1.1 christos return set_trace_option (sd, "-extract", TRACE_EXTRACT_IDX, arg);
275 1.1 christos else
276 1.1 christos sim_io_eprintf (sd, "Extract tracing not compiled in, `--trace-extract' ignored\n");
277 1.1 christos break;
278 1.1 christos
279 1.1 christos case OPTION_TRACE_LINENUM :
280 1.1 christos if (WITH_TRACE_LINENUM_P && WITH_TRACE_INSN_P)
281 1.1 christos {
282 1.1 christos if (set_trace_option (sd, "-linenum", TRACE_LINENUM_IDX, arg) != SIM_RC_OK
283 1.1 christos || set_trace_option (sd, "-linenum", TRACE_INSN_IDX, arg) != SIM_RC_OK)
284 1.1 christos return SIM_RC_FAIL;
285 1.1 christos }
286 1.1 christos else
287 1.1 christos sim_io_eprintf (sd, "Line number or instruction tracing not compiled in, `--trace-linenum' ignored\n");
288 1.1 christos break;
289 1.1 christos
290 1.1 christos case OPTION_TRACE_MEMORY :
291 1.1 christos if (WITH_TRACE_MEMORY_P)
292 1.1 christos return set_trace_option (sd, "-memory", TRACE_MEMORY_IDX, arg);
293 1.1 christos else
294 1.1 christos sim_io_eprintf (sd, "Memory tracing not compiled in, `--trace-memory' ignored\n");
295 1.1 christos break;
296 1.1 christos
297 1.1 christos case OPTION_TRACE_MODEL :
298 1.1 christos if (WITH_TRACE_MODEL_P)
299 1.1 christos return set_trace_option (sd, "-model", TRACE_MODEL_IDX, arg);
300 1.1 christos else
301 1.1 christos sim_io_eprintf (sd, "Model tracing not compiled in, `--trace-model' ignored\n");
302 1.1 christos break;
303 1.1 christos
304 1.1 christos case OPTION_TRACE_ALU :
305 1.1 christos if (WITH_TRACE_ALU_P)
306 1.1 christos return set_trace_option (sd, "-alu", TRACE_ALU_IDX, arg);
307 1.1 christos else
308 1.1 christos sim_io_eprintf (sd, "ALU tracing not compiled in, `--trace-alu' ignored\n");
309 1.1 christos break;
310 1.1 christos
311 1.1 christos case OPTION_TRACE_CORE :
312 1.1 christos if (WITH_TRACE_CORE_P)
313 1.1 christos return set_trace_option (sd, "-core", TRACE_CORE_IDX, arg);
314 1.1 christos else
315 1.1 christos sim_io_eprintf (sd, "CORE tracing not compiled in, `--trace-core' ignored\n");
316 1.1 christos break;
317 1.1 christos
318 1.1 christos case OPTION_TRACE_EVENTS :
319 1.1 christos if (WITH_TRACE_EVENTS_P)
320 1.1 christos return set_trace_option (sd, "-events", TRACE_EVENTS_IDX, arg);
321 1.1 christos else
322 1.1 christos sim_io_eprintf (sd, "EVENTS tracing not compiled in, `--trace-events' ignored\n");
323 1.1 christos break;
324 1.1 christos
325 1.1 christos case OPTION_TRACE_FPU :
326 1.1 christos if (WITH_TRACE_FPU_P)
327 1.1 christos return set_trace_option (sd, "-fpu", TRACE_FPU_IDX, arg);
328 1.1 christos else
329 1.1 christos sim_io_eprintf (sd, "FPU tracing not compiled in, `--trace-fpu' ignored\n");
330 1.1 christos break;
331 1.1 christos
332 1.1 christos case OPTION_TRACE_VPU :
333 1.1 christos if (WITH_TRACE_VPU_P)
334 1.1 christos return set_trace_option (sd, "-vpu", TRACE_VPU_IDX, arg);
335 1.1 christos else
336 1.1 christos sim_io_eprintf (sd, "VPU tracing not compiled in, `--trace-vpu' ignored\n");
337 1.1 christos break;
338 1.1 christos
339 1.1 christos case OPTION_TRACE_BRANCH :
340 1.1 christos if (WITH_TRACE_BRANCH_P)
341 1.1 christos return set_trace_option (sd, "-branch", TRACE_BRANCH_IDX, arg);
342 1.1 christos else
343 1.1 christos sim_io_eprintf (sd, "Branch tracing not compiled in, `--trace-branch' ignored\n");
344 1.1 christos break;
345 1.1 christos
346 1.1.1.2 christos case OPTION_TRACE_SYSCALL :
347 1.1.1.2 christos if (WITH_TRACE_SYSCALL_P)
348 1.1.1.2 christos return set_trace_option (sd, "-syscall", TRACE_SYSCALL_IDX, arg);
349 1.1.1.2 christos else
350 1.1.1.2 christos sim_io_eprintf (sd, "System call tracing not compiled in, `--trace-syscall' ignored\n");
351 1.1.1.2 christos break;
352 1.1.1.2 christos
353 1.1.1.5 christos case OPTION_TRACE_REGISTER :
354 1.1.1.5 christos if (WITH_TRACE_REGISTER_P)
355 1.1.1.5 christos return set_trace_option (sd, "-register", TRACE_REGISTER_IDX, arg);
356 1.1.1.5 christos else
357 1.1.1.5 christos sim_io_eprintf (sd, "Register tracing not compiled in, `--trace-register' ignored\n");
358 1.1.1.5 christos break;
359 1.1.1.5 christos
360 1.1 christos case OPTION_TRACE_SEMANTICS :
361 1.1 christos if (WITH_TRACE_ALU_P
362 1.1 christos && WITH_TRACE_FPU_P
363 1.1 christos && WITH_TRACE_MEMORY_P
364 1.1 christos && WITH_TRACE_BRANCH_P)
365 1.1 christos {
366 1.1 christos if (set_trace_option (sd, "-semantics", TRACE_ALU_IDX, arg) != SIM_RC_OK
367 1.1 christos || set_trace_option (sd, "-semantics", TRACE_FPU_IDX, arg) != SIM_RC_OK
368 1.1 christos || set_trace_option (sd, "-semantics", TRACE_VPU_IDX, arg) != SIM_RC_OK
369 1.1 christos || set_trace_option (sd, "-semantics", TRACE_MEMORY_IDX, arg) != SIM_RC_OK
370 1.1 christos || set_trace_option (sd, "-semantics", TRACE_BRANCH_IDX, arg) != SIM_RC_OK)
371 1.1 christos return SIM_RC_FAIL;
372 1.1 christos }
373 1.1 christos else
374 1.1 christos sim_io_eprintf (sd, "Alu, fpu, memory, and/or branch tracing not compiled in, `--trace-semantics' ignored\n");
375 1.1 christos break;
376 1.1 christos
377 1.1 christos #ifdef SIM_HAVE_ADDR_RANGE
378 1.1 christos case OPTION_TRACE_RANGE :
379 1.1.1.5 christos if (WITH_TRACE_ANY_P)
380 1.1 christos {
381 1.1 christos int cpu_nr;
382 1.1 christos char *chp = arg;
383 1.1 christos unsigned long start,end;
384 1.1 christos start = strtoul (chp, &chp, 0);
385 1.1 christos if (*chp != ',')
386 1.1 christos {
387 1.1 christos sim_io_eprintf (sd, "--trace-range missing END argument\n");
388 1.1 christos return SIM_RC_FAIL;
389 1.1 christos }
390 1.1 christos end = strtoul (chp + 1, NULL, 0);
391 1.1 christos /* FIXME: Argument validation. */
392 1.1 christos if (cpu != NULL)
393 1.1 christos sim_addr_range_add (TRACE_RANGE (CPU_PROFILE_DATA (cpu)),
394 1.1 christos start, end);
395 1.1 christos else
396 1.1 christos for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; ++cpu_nr)
397 1.1 christos sim_addr_range_add (TRACE_RANGE (CPU_TRACE_DATA (STATE_CPU (sd, cpu_nr))),
398 1.1 christos start, end);
399 1.1 christos }
400 1.1 christos else
401 1.1 christos sim_io_eprintf (sd, "Tracing not compiled in, `--trace-range' ignored\n");
402 1.1 christos break;
403 1.1 christos
404 1.1 christos case OPTION_TRACE_FUNCTION :
405 1.1.1.5 christos if (WITH_TRACE_ANY_P)
406 1.1 christos {
407 1.1 christos /*wip: need to compute function range given name*/
408 1.1 christos }
409 1.1 christos else
410 1.1 christos sim_io_eprintf (sd, "Tracing not compiled in, `--trace-function' ignored\n");
411 1.1 christos break;
412 1.1 christos #endif /* SIM_HAVE_ADDR_RANGE */
413 1.1 christos
414 1.1 christos case OPTION_TRACE_DEBUG :
415 1.1 christos if (WITH_TRACE_DEBUG_P)
416 1.1 christos return set_trace_option (sd, "-debug", TRACE_DEBUG_IDX, arg);
417 1.1 christos else
418 1.1 christos sim_io_eprintf (sd, "Tracing debug support not compiled in, `--trace-debug' ignored\n");
419 1.1 christos break;
420 1.1 christos
421 1.1 christos case OPTION_TRACE_FILE :
422 1.1.1.5 christos if (!WITH_TRACE_ANY_P)
423 1.1 christos sim_io_eprintf (sd, "Tracing not compiled in, `--trace-file' ignored\n");
424 1.1 christos else
425 1.1 christos {
426 1.1 christos FILE *f = fopen (arg, "w");
427 1.1 christos
428 1.1 christos if (f == NULL)
429 1.1 christos {
430 1.1 christos sim_io_eprintf (sd, "Unable to open trace output file `%s'\n", arg);
431 1.1 christos return SIM_RC_FAIL;
432 1.1 christos }
433 1.1 christos for (n = 0; n < MAX_NR_PROCESSORS; ++n)
434 1.1 christos TRACE_FILE (CPU_TRACE_DATA (STATE_CPU (sd, n))) = f;
435 1.1 christos TRACE_FILE (STATE_TRACE_DATA (sd)) = f;
436 1.1 christos }
437 1.1 christos break;
438 1.1 christos }
439 1.1 christos
440 1.1 christos return SIM_RC_OK;
441 1.1 christos }
442 1.1 christos
443 1.1 christos /* Install tracing support. */
445 1.1 christos
446 1.1 christos SIM_RC
447 1.1 christos trace_install (SIM_DESC sd)
448 1.1 christos {
449 1.1 christos int i;
450 1.1 christos
451 1.1 christos SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
452 1.1 christos
453 1.1 christos sim_add_option_table (sd, NULL, trace_options);
454 1.1 christos memset (STATE_TRACE_DATA (sd), 0, sizeof (* STATE_TRACE_DATA (sd)));
455 1.1 christos for (i = 0; i < MAX_NR_PROCESSORS; ++i)
456 1.1 christos memset (CPU_TRACE_DATA (STATE_CPU (sd, i)), 0,
457 1.1 christos sizeof (* CPU_TRACE_DATA (STATE_CPU (sd, i))));
458 1.1 christos sim_module_add_init_fn (sd, trace_init);
459 1.1 christos sim_module_add_uninstall_fn (sd, trace_uninstall);
460 1.1 christos return SIM_RC_OK;
461 1.1 christos }
462 1.1 christos
463 1.1 christos static SIM_RC
464 1.1 christos trace_init (SIM_DESC sd)
465 1.1 christos {
466 1.1 christos #ifdef SIM_HAVE_ADDR_RANGE
467 1.1 christos /* Check if a range has been specified without specifying what to
468 1.1 christos collect. */
469 1.1 christos {
470 1.1 christos int i;
471 1.1 christos
472 1.1 christos for (i = 0; i < MAX_NR_PROCESSORS; ++i)
473 1.1 christos {
474 1.1 christos sim_cpu *cpu = STATE_CPU (sd, i);
475 1.1 christos
476 1.1 christos if (ADDR_RANGE_RANGES (TRACE_RANGE (CPU_TRACE_DATA (cpu)))
477 1.1 christos && ! TRACE_INSN_P (cpu))
478 1.1 christos {
479 1.1 christos sim_io_eprintf_cpu (cpu, "Tracing address range specified without --trace-insn.\n");
480 1.1 christos sim_io_eprintf_cpu (cpu, "Address range ignored.\n");
481 1.1 christos sim_addr_range_delete (TRACE_RANGE (CPU_TRACE_DATA (cpu)),
482 1.1 christos 0, ~ (address_word) 0);
483 1.1 christos }
484 1.1 christos }
485 1.1 christos }
486 1.1 christos #endif
487 1.1 christos
488 1.1 christos return SIM_RC_OK;
489 1.1 christos }
490 1.1 christos
491 1.1 christos static void
492 1.1 christos trace_uninstall (SIM_DESC sd)
493 1.1 christos {
494 1.1 christos int i,j;
495 1.1 christos FILE *sfile = TRACE_FILE (STATE_TRACE_DATA (sd));
496 1.1 christos
497 1.1 christos if (sfile != NULL)
498 1.1 christos fclose (sfile);
499 1.1 christos
500 1.1 christos for (i = 0; i < MAX_NR_PROCESSORS; ++i)
501 1.1 christos {
502 1.1 christos FILE *cfile = TRACE_FILE (CPU_TRACE_DATA (STATE_CPU (sd, i)));
503 1.1 christos if (cfile != NULL && cfile != sfile)
504 1.1 christos {
505 1.1 christos /* If output from different cpus is going to the same file,
506 1.1 christos avoid closing the file twice. */
507 1.1 christos for (j = 0; j < i; ++j)
508 1.1 christos if (TRACE_FILE (CPU_TRACE_DATA (STATE_CPU (sd, j))) == cfile)
509 1.1 christos break;
510 1.1 christos if (i == j)
511 1.1 christos fclose (cfile);
512 1.1 christos }
513 1.1 christos }
514 1.1 christos }
515 1.1 christos
516 1.1 christos /* compute the nr of trace data units consumed by data */
518 1.1 christos static int
519 1.1 christos save_data_size (TRACE_DATA *data,
520 1.1 christos long size)
521 1.1 christos {
522 1.1 christos return ((size + sizeof (TRACE_INPUT_DATA (data) [0]) - 1)
523 1.1 christos / sizeof (TRACE_INPUT_DATA (data) [0]));
524 1.1 christos }
525 1.1 christos
526 1.1.1.2 christos
527 1.1 christos /* Archive DATA into the trace buffer */
528 1.1 christos void
529 1.1 christos save_data (SIM_DESC sd,
530 1.1 christos TRACE_DATA *data,
531 1.1 christos data_fmt fmt,
532 1.1 christos long size,
533 1.1 christos const void *buf)
534 1.1 christos {
535 1.1 christos int i = TRACE_INPUT_IDX (data);
536 1.1 christos if (i == sizeof (TRACE_INPUT_FMT (data)))
537 1.1 christos sim_io_error (sd, "trace buffer overflow");
538 1.1 christos TRACE_INPUT_FMT (data) [i] = fmt;
539 1.1 christos TRACE_INPUT_SIZE (data) [i] = size;
540 1.1 christos memcpy (&TRACE_INPUT_DATA (data) [i], buf, size);
541 1.1 christos i += save_data_size (data, size);
542 1.1 christos TRACE_INPUT_IDX (data) = i;
543 1.1 christos }
544 1.1 christos
545 1.1 christos static void
546 1.1 christos print_data (SIM_DESC sd,
547 1.1 christos sim_cpu *cpu,
548 1.1 christos data_fmt fmt,
549 1.1 christos long size,
550 1.1 christos void *data)
551 1.1 christos {
552 1.1 christos switch (fmt)
553 1.1 christos {
554 1.1 christos case trace_fmt_instruction_incomplete:
555 1.1 christos trace_printf (sd, cpu, " (instruction incomplete)");
556 1.1 christos break;
557 1.1 christos case trace_fmt_word:
558 1.1 christos case trace_fmt_addr:
559 1.1 christos {
560 1.1 christos switch (size)
561 1.1 christos {
562 1.1 christos case sizeof (unsigned32):
563 1.1 christos trace_printf (sd, cpu, " 0x%08lx", (long) * (unsigned32*) data);
564 1.1 christos break;
565 1.1 christos case sizeof (unsigned64):
566 1.1 christos trace_printf (sd, cpu, " 0x%08lx%08lx",
567 1.1 christos (long) ((* (unsigned64*) data) >> 32),
568 1.1 christos (long) * (unsigned64*) data);
569 1.1 christos break;
570 1.1 christos default:
571 1.1 christos abort ();
572 1.1 christos }
573 1.1 christos break;
574 1.1 christos }
575 1.1 christos case trace_fmt_bool:
576 1.1 christos {
577 1.1 christos SIM_ASSERT (size == sizeof (int));
578 1.1 christos trace_printf (sd, cpu, " %-8s",
579 1.1 christos (* (int*) data) ? "true" : "false");
580 1.1 christos break;
581 1.1 christos }
582 1.1 christos case trace_fmt_fp:
583 1.1 christos {
584 1.1 christos sim_fpu fp;
585 1.1 christos switch (size)
586 1.1 christos {
587 1.1 christos /* FIXME: Assumes sizeof float == 4; sizeof double == 8 */
588 1.1 christos case 4:
589 1.1 christos sim_fpu_32to (&fp, *(unsigned32*)data);
590 1.1 christos break;
591 1.1 christos case 8:
592 1.1 christos sim_fpu_64to (&fp, *(unsigned64*)data);
593 1.1 christos break;
594 1.1 christos default:
595 1.1 christos abort ();
596 1.1 christos }
597 1.1 christos trace_printf (sd, cpu, " %8g", sim_fpu_2d (&fp));
598 1.1 christos switch (size)
599 1.1 christos {
600 1.1 christos case 4:
601 1.1 christos trace_printf (sd, cpu, " (0x%08lx)",
602 1.1 christos (long) *(unsigned32*)data);
603 1.1 christos break;
604 1.1 christos case 8:
605 1.1 christos trace_printf (sd, cpu, " (0x%08lx%08lx)",
606 1.1 christos (long) (*(unsigned64*)data >> 32),
607 1.1 christos (long) (*(unsigned64*)data));
608 1.1 christos break;
609 1.1 christos default:
610 1.1 christos abort ();
611 1.1 christos }
612 1.1 christos break;
613 1.1 christos }
614 1.1 christos case trace_fmt_fpu:
615 1.1 christos /* FIXME: At present sim_fpu data is stored as a double */
616 1.1 christos trace_printf (sd, cpu, " %8g", * (double*) data);
617 1.1 christos break;
618 1.1 christos case trace_fmt_string:
619 1.1 christos trace_printf (sd, cpu, " %-8s", (char*) data);
620 1.1 christos break;
621 1.1 christos default:
622 1.1 christos abort ();
623 1.1 christos }
624 1.1 christos }
625 1.1 christos
626 1.1 christos static const char *
627 1.1 christos trace_idx_to_str (int trace_idx)
628 1.1 christos {
629 1.1 christos static char num[8];
630 1.1.1.5 christos switch (trace_idx)
631 1.1.1.5 christos {
632 1.1.1.6 christos case TRACE_ALU_IDX: return "alu: ";
633 1.1.1.5 christos case TRACE_INSN_IDX: return "insn: ";
634 1.1.1.5 christos case TRACE_DISASM_IDX: return "disasm: ";
635 1.1.1.5 christos case TRACE_DECODE_IDX: return "decode: ";
636 1.1.1.5 christos case TRACE_EXTRACT_IDX: return "extract: ";
637 1.1.1.5 christos case TRACE_MEMORY_IDX: return "memory: ";
638 1.1.1.5 christos case TRACE_CORE_IDX: return "core: ";
639 1.1.1.5 christos case TRACE_EVENTS_IDX: return "events: ";
640 1.1.1.5 christos case TRACE_FPU_IDX: return "fpu: ";
641 1.1.1.5 christos case TRACE_BRANCH_IDX: return "branch: ";
642 1.1.1.5 christos case TRACE_SYSCALL_IDX: return "syscall: ";
643 1.1 christos case TRACE_REGISTER_IDX: return "reg: ";
644 1.1 christos case TRACE_VPU_IDX: return "vpu: ";
645 1.1 christos default:
646 1.1 christos sprintf (num, "?%d?", trace_idx);
647 1.1 christos return num;
648 1.1 christos }
649 1.1 christos }
650 1.1 christos
651 1.1 christos static void
652 1.1 christos trace_results (SIM_DESC sd,
653 1.1 christos sim_cpu *cpu,
654 1.1 christos int trace_idx,
655 1.1 christos int last_input)
656 1.1 christos {
657 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
658 1.1 christos int nr_out;
659 1.1 christos int i;
660 1.1 christos
661 1.1 christos /* cross check trace_idx against TRACE_IDX (data)? */
662 1.1 christos
663 1.1 christos /* prefix */
664 1.1 christos trace_printf (sd, cpu, "%s %s",
665 1.1 christos trace_idx_to_str (TRACE_IDX (data)),
666 1.1 christos TRACE_PREFIX (data));
667 1.1 christos TRACE_IDX (data) = 0;
668 1.1 christos
669 1.1 christos for (i = 0, nr_out = 0;
670 1.1 christos i < TRACE_INPUT_IDX (data);
671 1.1 christos i += save_data_size (data, TRACE_INPUT_SIZE (data) [i]), nr_out++)
672 1.1 christos {
673 1.1 christos if (i == last_input)
674 1.1 christos {
675 1.1 christos int pad = (strlen (" 0x") + sizeof (unsigned_word) * 2);
676 1.1 christos int padding = pad * (3 - nr_out);
677 1.1 christos if (padding < 0)
678 1.1 christos padding = 0;
679 1.1 christos padding += strlen (" ::");
680 1.1 christos trace_printf (sd, cpu, "%*s", padding, " ::");
681 1.1 christos }
682 1.1 christos print_data (sd, cpu,
683 1.1 christos TRACE_INPUT_FMT (data) [i],
684 1.1 christos TRACE_INPUT_SIZE (data) [i],
685 1.1 christos &TRACE_INPUT_DATA (data) [i]);
686 1.1 christos }
687 1.1 christos trace_printf (sd, cpu, "\n");
688 1.1 christos }
689 1.1 christos
690 1.1 christos void
691 1.1 christos trace_prefix (SIM_DESC sd,
692 1.1 christos sim_cpu *cpu,
693 1.1 christos sim_cia cia,
694 1.1 christos address_word pc,
695 1.1 christos int line_p,
696 1.1 christos const char *filename,
697 1.1 christos int linenum,
698 1.1 christos const char *fmt,
699 1.1 christos ...)
700 1.1 christos {
701 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
702 1.1 christos va_list ap;
703 1.1 christos char *prefix = TRACE_PREFIX (data);
704 1.1 christos char *chp;
705 1.1 christos /* FIXME: The TRACE_PREFIX_WIDTH should be determined at build time using
706 1.1 christos known information about the disassembled instructions. */
707 1.1 christos #ifndef TRACE_PREFIX_WIDTH
708 1.1 christos #define TRACE_PREFIX_WIDTH 48
709 1.1 christos #endif
710 1.1 christos int width = TRACE_PREFIX_WIDTH;
711 1.1 christos
712 1.1 christos /* if the previous trace data wasn't flushed, flush it now with a
713 1.1 christos note indicating that the trace was incomplete. */
714 1.1 christos if (TRACE_IDX (data) != 0)
715 1.1 christos {
716 1.1 christos int last_input = TRACE_INPUT_IDX (data);
717 1.1 christos save_data (sd, data, trace_fmt_instruction_incomplete, 1, "");
718 1.1 christos trace_results (sd, cpu, TRACE_IDX (data), last_input);
719 1.1 christos }
720 1.1 christos TRACE_IDX (data) = 0;
721 1.1 christos TRACE_INPUT_IDX (data) = 0;
722 1.1 christos
723 1.1 christos /* Create the text prefix for this new instruction: */
724 1.1 christos if (!line_p)
725 1.1 christos {
726 1.1 christos if (filename)
727 1.1 christos {
728 1.1 christos sprintf (prefix, "%s:%-*d 0x%.*lx ",
729 1.1 christos filename,
730 1.1 christos SIZE_LINE_NUMBER, linenum,
731 1.1 christos SIZE_PC, (long) pc);
732 1.1 christos }
733 1.1 christos else
734 1.1 christos {
735 1.1 christos sprintf (prefix, "0x%.*lx ",
736 1.1 christos SIZE_PC, (long) pc);
737 1.1 christos /* Shrink the width by the amount that we didn't print. */
738 1.1 christos width -= SIZE_LINE_NUMBER + SIZE_PC + 8;
739 1.1 christos }
740 1.1 christos chp = strchr (prefix, '\0');
741 1.1 christos va_start (ap, fmt);
742 1.1 christos vsprintf (chp, fmt, ap);
743 1.1 christos va_end (ap);
744 1.1 christos }
745 1.1 christos else
746 1.1 christos {
747 1.1 christos char buf[256];
748 1.1 christos buf[0] = 0;
749 1.1 christos if (STATE_TEXT_SECTION (CPU_STATE (cpu))
750 1.1 christos && pc >= STATE_TEXT_START (CPU_STATE (cpu))
751 1.1 christos && pc < STATE_TEXT_END (CPU_STATE (cpu)))
752 1.1 christos {
753 1.1 christos const char *pc_filename = (const char *)0;
754 1.1 christos const char *pc_function = (const char *)0;
755 1.1 christos unsigned int pc_linenum = 0;
756 1.1 christos bfd *abfd;
757 1.1 christos asymbol **asymbols;
758 1.1 christos
759 1.1 christos abfd = STATE_PROG_BFD (CPU_STATE (cpu));
760 1.1 christos asymbols = STATE_PROG_SYMS (CPU_STATE (cpu));
761 1.1 christos if (asymbols == NULL)
762 1.1 christos {
763 1.1 christos long symsize;
764 1.1 christos long symbol_count;
765 1.1 christos
766 1.1 christos symsize = bfd_get_symtab_upper_bound (abfd);
767 1.1 christos if (symsize < 0)
768 1.1 christos {
769 1.1 christos sim_engine_abort (sd, cpu, cia, "could not read symbols");
770 1.1 christos }
771 1.1 christos asymbols = (asymbol **) xmalloc (symsize);
772 1.1 christos symbol_count = bfd_canonicalize_symtab (abfd, asymbols);
773 1.1 christos if (symbol_count < 0)
774 1.1 christos {
775 1.1 christos sim_engine_abort (sd, cpu, cia, "could not canonicalize symbols");
776 1.1 christos }
777 1.1 christos STATE_PROG_SYMS (CPU_STATE (cpu)) = asymbols;
778 1.1 christos }
779 1.1 christos
780 1.1 christos if (bfd_find_nearest_line (abfd,
781 1.1 christos STATE_TEXT_SECTION (CPU_STATE (cpu)),
782 1.1 christos asymbols,
783 1.1 christos pc - STATE_TEXT_START (CPU_STATE (cpu)),
784 1.1 christos &pc_filename, &pc_function, &pc_linenum))
785 1.1 christos {
786 1.1 christos char *p = buf;
787 1.1 christos if (pc_linenum)
788 1.1 christos {
789 1.1 christos sprintf (p, "#%-*d ", SIZE_LINE_NUMBER, pc_linenum);
790 1.1 christos p += strlen (p);
791 1.1 christos }
792 1.1 christos else
793 1.1 christos {
794 1.1 christos sprintf (p, "%-*s ", SIZE_LINE_NUMBER+1, "---");
795 1.1 christos p += SIZE_LINE_NUMBER+2;
796 1.1 christos }
797 1.1 christos
798 1.1 christos if (pc_function)
799 1.1 christos {
800 1.1 christos sprintf (p, "%s ", pc_function);
801 1.1 christos p += strlen (p);
802 1.1 christos }
803 1.1 christos else if (pc_filename)
804 1.1 christos {
805 1.1 christos char *q = (char *) strrchr (pc_filename, '/');
806 1.1 christos sprintf (p, "%s ", (q) ? q+1 : pc_filename);
807 1.1 christos p += strlen (p);
808 1.1 christos }
809 1.1 christos
810 1.1 christos if (*p == ' ')
811 1.1 christos *p = '\0';
812 1.1 christos }
813 1.1 christos }
814 1.1 christos
815 1.1 christos sprintf (prefix, "0x%.*x %-*.*s ",
816 1.1 christos SIZE_PC, (unsigned) pc,
817 1.1 christos SIZE_LOCATION, SIZE_LOCATION, buf);
818 1.1 christos chp = strchr (prefix, '\0');
819 1.1 christos va_start (ap, fmt);
820 1.1 christos vsprintf (chp, fmt, ap);
821 1.1 christos va_end (ap);
822 1.1 christos }
823 1.1 christos
824 1.1 christos /* Pad it out to TRACE_PREFIX_WIDTH. */
825 1.1 christos chp = strchr (prefix, '\0');
826 1.1 christos if (chp - prefix < width)
827 1.1 christos {
828 1.1 christos memset (chp, ' ', width - (chp - prefix));
829 1.1 christos chp = &prefix [width];
830 1.1 christos *chp = '\0';
831 1.1 christos }
832 1.1 christos strcpy (chp, " -");
833 1.1 christos
834 1.1 christos /* check that we've not over flowed the prefix buffer */
835 1.1 christos if (strlen (prefix) >= sizeof (TRACE_PREFIX (data)))
836 1.1 christos abort ();
837 1.1 christos }
838 1.1 christos
839 1.1 christos void
840 1.1 christos trace_generic (SIM_DESC sd,
841 1.1 christos sim_cpu *cpu,
842 1.1 christos int trace_idx,
843 1.1 christos const char *fmt,
844 1.1 christos ...)
845 1.1 christos {
846 1.1 christos va_list ap;
847 1.1 christos trace_printf (sd, cpu, "%s %s",
848 1.1 christos trace_idx_to_str (trace_idx),
849 1.1 christos TRACE_PREFIX (CPU_TRACE_DATA (cpu)));
850 1.1 christos va_start (ap, fmt);
851 1.1 christos trace_vprintf (sd, cpu, fmt, ap);
852 1.1 christos va_end (ap);
853 1.1 christos trace_printf (sd, cpu, "\n");
854 1.1.1.6 christos }
855 1.1.1.6 christos
856 1.1.1.6 christos static int
857 1.1.1.6 christos dis_read (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length,
858 1.1.1.6 christos struct disassemble_info *dinfo)
859 1.1.1.6 christos {
860 1.1.1.6 christos SIM_CPU *cpu = dinfo->application_data;
861 1.1.1.6 christos sim_core_read_buffer (CPU_STATE (cpu), cpu, NULL_CIA, myaddr, memaddr, length);
862 1.1.1.6 christos return 0;
863 1.1.1.6 christos }
864 1.1.1.6 christos
865 1.1.1.6 christos static int
866 1.1.1.6 christos dis_printf (SIM_CPU *cpu, const char *fmt, ...)
867 1.1.1.6 christos {
868 1.1.1.6 christos SIM_DESC sd = CPU_STATE (cpu);
869 1.1.1.6 christos va_list ap;
870 1.1.1.6 christos va_start (ap, fmt);
871 1.1.1.6 christos trace_vprintf (sd, cpu, fmt, ap);
872 1.1.1.6 christos va_end (ap);
873 1.1.1.6 christos return 0;
874 1.1.1.6 christos }
875 1.1.1.6 christos
876 1.1.1.6 christos void
877 1.1.1.6 christos trace_disasm (SIM_DESC sd, sim_cpu *cpu, address_word addr)
878 1.1.1.6 christos {
879 1.1.1.6 christos struct bfd *bfd = STATE_PROG_BFD (sd);
880 1.1.1.6 christos TRACE_DATA *trace_data = CPU_TRACE_DATA (cpu);
881 1.1.1.6 christos disassemble_info *info = &trace_data->dis_info;
882 1.1.1.6 christos
883 1.1.1.6 christos /* See if we need to set up the disassembly func. */
884 1.1.1.6 christos if (trace_data->dis_bfd != bfd)
885 1.1.1.6 christos {
886 1.1.1.6 christos trace_data->dis_bfd = bfd;
887 1.1.1.6 christos trace_data->disassembler = disassembler (trace_data->dis_bfd);
888 1.1.1.6 christos INIT_DISASSEMBLE_INFO (*info, cpu, dis_printf);
889 1.1.1.6 christos info->read_memory_func = dis_read;
890 1.1.1.6 christos info->arch = bfd_get_arch (bfd);
891 1.1.1.6 christos info->mach = bfd_get_mach (bfd);
892 1.1.1.6 christos disassemble_init_for_target (info);
893 1.1.1.6 christos }
894 1.1.1.6 christos
895 1.1.1.6 christos info->application_data = cpu;
896 1.1.1.6 christos
897 1.1.1.6 christos trace_printf (sd, cpu, "%s %s",
898 1.1.1.6 christos trace_idx_to_str (TRACE_DISASM_IDX),
899 1.1.1.6 christos TRACE_PREFIX (trace_data));
900 1.1.1.6 christos trace_data->disassembler (addr, info);
901 1.1.1.6 christos trace_printf (sd, cpu, "\n");
902 1.1 christos }
903 1.1 christos
904 1.1 christos void
905 1.1 christos trace_input0 (SIM_DESC sd,
906 1.1 christos sim_cpu *cpu,
907 1.1 christos int trace_idx)
908 1.1 christos {
909 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
910 1.1 christos TRACE_IDX (data) = trace_idx;
911 1.1 christos }
912 1.1 christos
913 1.1 christos void
914 1.1 christos trace_input_word1 (SIM_DESC sd,
915 1.1 christos sim_cpu *cpu,
916 1.1 christos int trace_idx,
917 1.1 christos unsigned_word d0)
918 1.1 christos {
919 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
920 1.1 christos TRACE_IDX (data) = trace_idx;
921 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);
922 1.1 christos }
923 1.1 christos
924 1.1 christos void
925 1.1 christos trace_input_word2 (SIM_DESC sd,
926 1.1 christos sim_cpu *cpu,
927 1.1 christos int trace_idx,
928 1.1 christos unsigned_word d0,
929 1.1 christos unsigned_word d1)
930 1.1 christos {
931 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
932 1.1 christos TRACE_IDX (data) = trace_idx;
933 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);
934 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d1);
935 1.1 christos }
936 1.1 christos
937 1.1 christos void
938 1.1 christos trace_input_word3 (SIM_DESC sd,
939 1.1 christos sim_cpu *cpu,
940 1.1 christos int trace_idx,
941 1.1 christos unsigned_word d0,
942 1.1 christos unsigned_word d1,
943 1.1 christos unsigned_word d2)
944 1.1 christos {
945 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
946 1.1 christos TRACE_IDX (data) = trace_idx;
947 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);
948 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d1);
949 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d2);
950 1.1 christos }
951 1.1 christos
952 1.1 christos void
953 1.1 christos trace_input_word4 (SIM_DESC sd,
954 1.1 christos sim_cpu *cpu,
955 1.1 christos int trace_idx,
956 1.1 christos unsigned_word d0,
957 1.1 christos unsigned_word d1,
958 1.1 christos unsigned_word d2,
959 1.1 christos unsigned_word d3)
960 1.1 christos {
961 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
962 1.1 christos TRACE_IDX (data) = trace_idx;
963 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (d0), &d0);
964 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (d1), &d1);
965 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (d2), &d2);
966 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (d3), &d3);
967 1.1 christos }
968 1.1 christos
969 1.1 christos void
970 1.1 christos trace_input_bool1 (SIM_DESC sd,
971 1.1 christos sim_cpu *cpu,
972 1.1 christos int trace_idx,
973 1.1 christos int d0)
974 1.1 christos {
975 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
976 1.1 christos TRACE_IDX (data) = trace_idx;
977 1.1 christos save_data (sd, data, trace_fmt_bool, sizeof (d0), &d0);
978 1.1 christos }
979 1.1 christos
980 1.1 christos void
981 1.1 christos trace_input_addr1 (SIM_DESC sd,
982 1.1 christos sim_cpu *cpu,
983 1.1 christos int trace_idx,
984 1.1 christos address_word d0)
985 1.1 christos {
986 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
987 1.1 christos TRACE_IDX (data) = trace_idx;
988 1.1 christos save_data (sd, data, trace_fmt_addr, sizeof (d0), &d0);
989 1.1 christos }
990 1.1 christos
991 1.1 christos void
992 1.1 christos trace_input_fp1 (SIM_DESC sd,
993 1.1 christos sim_cpu *cpu,
994 1.1 christos int trace_idx,
995 1.1 christos fp_word f0)
996 1.1 christos {
997 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
998 1.1 christos TRACE_IDX (data) = trace_idx;
999 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
1000 1.1 christos }
1001 1.1 christos
1002 1.1 christos void
1003 1.1 christos trace_input_fp2 (SIM_DESC sd,
1004 1.1 christos sim_cpu *cpu,
1005 1.1 christos int trace_idx,
1006 1.1 christos fp_word f0,
1007 1.1 christos fp_word f1)
1008 1.1 christos {
1009 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1010 1.1 christos TRACE_IDX (data) = trace_idx;
1011 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
1012 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f1);
1013 1.1 christos }
1014 1.1 christos
1015 1.1 christos void
1016 1.1 christos trace_input_fp3 (SIM_DESC sd,
1017 1.1 christos sim_cpu *cpu,
1018 1.1 christos int trace_idx,
1019 1.1 christos fp_word f0,
1020 1.1 christos fp_word f1,
1021 1.1 christos fp_word f2)
1022 1.1 christos {
1023 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1024 1.1 christos TRACE_IDX (data) = trace_idx;
1025 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
1026 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f1);
1027 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f2);
1028 1.1 christos }
1029 1.1 christos
1030 1.1 christos void
1031 1.1 christos trace_input_fpu1 (SIM_DESC sd,
1032 1.1 christos sim_cpu *cpu,
1033 1.1 christos int trace_idx,
1034 1.1 christos sim_fpu *f0)
1035 1.1 christos {
1036 1.1 christos double d;
1037 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1038 1.1 christos TRACE_IDX (data) = trace_idx;
1039 1.1 christos d = sim_fpu_2d (f0);
1040 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1041 1.1 christos }
1042 1.1 christos
1043 1.1 christos void
1044 1.1 christos trace_input_fpu2 (SIM_DESC sd,
1045 1.1 christos sim_cpu *cpu,
1046 1.1 christos int trace_idx,
1047 1.1 christos sim_fpu *f0,
1048 1.1 christos sim_fpu *f1)
1049 1.1 christos {
1050 1.1 christos double d;
1051 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1052 1.1 christos TRACE_IDX (data) = trace_idx;
1053 1.1 christos d = sim_fpu_2d (f0);
1054 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1055 1.1 christos d = sim_fpu_2d (f1);
1056 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1057 1.1 christos }
1058 1.1 christos
1059 1.1 christos void
1060 1.1 christos trace_input_fpu3 (SIM_DESC sd,
1061 1.1 christos sim_cpu *cpu,
1062 1.1 christos int trace_idx,
1063 1.1 christos sim_fpu *f0,
1064 1.1 christos sim_fpu *f1,
1065 1.1 christos sim_fpu *f2)
1066 1.1 christos {
1067 1.1 christos double d;
1068 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1069 1.1 christos TRACE_IDX (data) = trace_idx;
1070 1.1 christos d = sim_fpu_2d (f0);
1071 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1072 1.1 christos d = sim_fpu_2d (f1);
1073 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1074 1.1 christos d = sim_fpu_2d (f2);
1075 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1076 1.1 christos }
1077 1.1 christos
1078 1.1 christos void
1079 1.1 christos trace_result_word1 (SIM_DESC sd,
1080 1.1 christos sim_cpu *cpu,
1081 1.1 christos int trace_idx,
1082 1.1 christos unsigned_word r0)
1083 1.1 christos {
1084 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1085 1.1 christos int last_input;
1086 1.1 christos
1087 1.1 christos /* Append any results to the end of the inputs */
1088 1.1 christos last_input = TRACE_INPUT_IDX (data);
1089 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &r0);
1090 1.1 christos
1091 1.1 christos trace_results (sd, cpu, trace_idx, last_input);
1092 1.1 christos }
1093 1.1 christos
1094 1.1 christos void
1095 1.1 christos trace_result0 (SIM_DESC sd,
1096 1.1 christos sim_cpu *cpu,
1097 1.1 christos int trace_idx)
1098 1.1 christos {
1099 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1100 1.1 christos int last_input;
1101 1.1 christos
1102 1.1 christos /* Append any results to the end of the inputs */
1103 1.1 christos last_input = TRACE_INPUT_IDX (data);
1104 1.1 christos
1105 1.1 christos trace_results (sd, cpu, trace_idx, last_input);
1106 1.1 christos }
1107 1.1 christos
1108 1.1 christos void
1109 1.1 christos trace_result_word2 (SIM_DESC sd,
1110 1.1 christos sim_cpu *cpu,
1111 1.1 christos int trace_idx,
1112 1.1 christos unsigned_word r0,
1113 1.1 christos unsigned_word r1)
1114 1.1 christos {
1115 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1116 1.1 christos int last_input;
1117 1.1 christos
1118 1.1 christos /* Append any results to the end of the inputs */
1119 1.1 christos last_input = TRACE_INPUT_IDX (data);
1120 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (r0), &r0);
1121 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (r1), &r1);
1122 1.1 christos
1123 1.1 christos trace_results (sd, cpu, trace_idx, last_input);
1124 1.1 christos }
1125 1.1 christos
1126 1.1 christos void
1127 1.1 christos trace_result_word4 (SIM_DESC sd,
1128 1.1 christos sim_cpu *cpu,
1129 1.1 christos int trace_idx,
1130 1.1 christos unsigned_word r0,
1131 1.1 christos unsigned_word r1,
1132 1.1 christos unsigned_word r2,
1133 1.1 christos unsigned_word r3)
1134 1.1 christos {
1135 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1136 1.1 christos int last_input;
1137 1.1 christos
1138 1.1 christos /* Append any results to the end of the inputs */
1139 1.1 christos last_input = TRACE_INPUT_IDX (data);
1140 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (r0), &r0);
1141 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (r1), &r1);
1142 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (r2), &r2);
1143 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (r3), &r3);
1144 1.1 christos
1145 1.1 christos trace_results (sd, cpu, trace_idx, last_input);
1146 1.1 christos }
1147 1.1 christos
1148 1.1 christos void
1149 1.1 christos trace_result_bool1 (SIM_DESC sd,
1150 1.1 christos sim_cpu *cpu,
1151 1.1 christos int trace_idx,
1152 1.1 christos int r0)
1153 1.1 christos {
1154 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1155 1.1 christos int last_input;
1156 1.1 christos
1157 1.1 christos /* Append any results to the end of the inputs */
1158 1.1 christos last_input = TRACE_INPUT_IDX (data);
1159 1.1 christos save_data (sd, data, trace_fmt_bool, sizeof (r0), &r0);
1160 1.1 christos
1161 1.1 christos trace_results (sd, cpu, trace_idx, last_input);
1162 1.1 christos }
1163 1.1 christos
1164 1.1 christos void
1165 1.1 christos trace_result_addr1 (SIM_DESC sd,
1166 1.1 christos sim_cpu *cpu,
1167 1.1 christos int trace_idx,
1168 1.1 christos address_word r0)
1169 1.1 christos {
1170 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1171 1.1 christos int last_input;
1172 1.1 christos
1173 1.1 christos /* Append any results to the end of the inputs */
1174 1.1 christos last_input = TRACE_INPUT_IDX (data);
1175 1.1 christos save_data (sd, data, trace_fmt_addr, sizeof (r0), &r0);
1176 1.1 christos
1177 1.1 christos trace_results (sd, cpu, trace_idx, last_input);
1178 1.1 christos }
1179 1.1 christos
1180 1.1 christos void
1181 1.1 christos trace_result_fp1 (SIM_DESC sd,
1182 1.1 christos sim_cpu *cpu,
1183 1.1 christos int trace_idx,
1184 1.1 christos fp_word f0)
1185 1.1 christos {
1186 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1187 1.1 christos int last_input;
1188 1.1 christos
1189 1.1 christos /* Append any results to the end of the inputs */
1190 1.1 christos last_input = TRACE_INPUT_IDX (data);
1191 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
1192 1.1 christos
1193 1.1 christos trace_results (sd, cpu, trace_idx, last_input);
1194 1.1 christos }
1195 1.1 christos
1196 1.1 christos void
1197 1.1 christos trace_result_fp2 (SIM_DESC sd,
1198 1.1 christos sim_cpu *cpu,
1199 1.1 christos int trace_idx,
1200 1.1 christos fp_word f0,
1201 1.1 christos fp_word f1)
1202 1.1 christos {
1203 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1204 1.1 christos int last_input;
1205 1.1 christos
1206 1.1 christos /* Append any results to the end of the inputs */
1207 1.1 christos last_input = TRACE_INPUT_IDX (data);
1208 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (f0), &f0);
1209 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (f1), &f1);
1210 1.1 christos
1211 1.1 christos trace_results (sd, cpu, trace_idx, last_input);
1212 1.1 christos }
1213 1.1 christos
1214 1.1 christos void
1215 1.1 christos trace_result_fpu1 (SIM_DESC sd,
1216 1.1 christos sim_cpu *cpu,
1217 1.1 christos int trace_idx,
1218 1.1 christos sim_fpu *f0)
1219 1.1 christos {
1220 1.1 christos double d;
1221 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1222 1.1 christos int last_input;
1223 1.1 christos
1224 1.1 christos /* Append any results to the end of the inputs */
1225 1.1 christos last_input = TRACE_INPUT_IDX (data);
1226 1.1 christos d = sim_fpu_2d (f0);
1227 1.1 christos save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1228 1.1 christos
1229 1.1 christos trace_results (sd, cpu, trace_idx, last_input);
1230 1.1 christos }
1231 1.1 christos
1232 1.1 christos void
1233 1.1 christos trace_result_string1 (SIM_DESC sd,
1234 1.1 christos sim_cpu *cpu,
1235 1.1 christos int trace_idx,
1236 1.1 christos char *s0)
1237 1.1 christos {
1238 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1239 1.1 christos int last_input;
1240 1.1 christos
1241 1.1 christos /* Append any results to the end of the inputs */
1242 1.1 christos last_input = TRACE_INPUT_IDX (data);
1243 1.1 christos save_data (sd, data, trace_fmt_string, strlen (s0) + 1, s0);
1244 1.1 christos
1245 1.1 christos trace_results (sd, cpu, trace_idx, last_input);
1246 1.1 christos }
1247 1.1 christos
1248 1.1 christos void
1249 1.1 christos trace_result_word1_string1 (SIM_DESC sd,
1250 1.1 christos sim_cpu *cpu,
1251 1.1 christos int trace_idx,
1252 1.1 christos unsigned_word r0,
1253 1.1 christos char *s0)
1254 1.1 christos {
1255 1.1 christos TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1256 1.1 christos int last_input;
1257 1.1 christos
1258 1.1 christos /* Append any results to the end of the inputs */
1259 1.1 christos last_input = TRACE_INPUT_IDX (data);
1260 1.1 christos save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &r0);
1261 1.1 christos save_data (sd, data, trace_fmt_string, strlen (s0) + 1, s0);
1262 1.1 christos
1263 1.1 christos trace_results (sd, cpu, trace_idx, last_input);
1264 1.1 christos }
1265 1.1 christos
1266 1.1 christos void
1268 1.1 christos trace_vprintf (SIM_DESC sd, sim_cpu *cpu, const char *fmt, va_list ap)
1269 1.1 christos {
1270 1.1 christos if (cpu != NULL)
1271 1.1 christos {
1272 1.1 christos if (TRACE_FILE (CPU_TRACE_DATA (cpu)) != NULL)
1273 1.1 christos vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu)), fmt, ap);
1274 1.1 christos else
1275 1.1 christos sim_io_evprintf (sd, fmt, ap);
1276 1.1 christos }
1277 1.1 christos else
1278 1.1 christos {
1279 1.1 christos if (TRACE_FILE (STATE_TRACE_DATA (sd)) != NULL)
1280 1.1 christos vfprintf (TRACE_FILE (STATE_TRACE_DATA (sd)), fmt, ap);
1281 1.1 christos else
1282 1.1 christos sim_io_evprintf (sd, fmt, ap);
1283 1.1 christos }
1284 1.1.1.3 christos }
1285 1.1 christos
1286 1.1 christos void
1287 1.1 christos trace_printf (SIM_DESC sd, sim_cpu *cpu, const char *fmt, ...)
1288 1.1.1.3 christos {
1289 1.1 christos va_list ap;
1290 1.1 christos
1291 1.1 christos va_start (ap, fmt);
1292 1.1 christos
1293 1.1 christos trace_vprintf (sd, cpu, fmt, ap);
1294 1.1 christos
1295 1.1 christos va_end (ap);
1296 1.1.1.5 christos }
1297 1.1 christos
1298 1.1 christos void
1299 1.1 christos sim_debug_printf (sim_cpu *cpu, const char *fmt, ...)
1300 1.1.1.3 christos {
1301 1.1 christos va_list ap;
1302 1.1 christos
1303 1.1 christos va_start (ap, fmt);
1304 1.1 christos
1305 1.1 christos if (CPU_DEBUG_FILE (cpu) == NULL)
1306 1.1 christos (* STATE_CALLBACK (CPU_STATE (cpu))->evprintf_filtered)
1307 1.1 christos (STATE_CALLBACK (CPU_STATE (cpu)), fmt, ap);
1308 1.1 christos else
1309 1.1 christos vfprintf (CPU_DEBUG_FILE (cpu), fmt, ap);
1310
1311 va_end (ap);
1312 }
1313