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