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