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