x86: fold narrowing VCVT* templates
[external/binutils.git] / sim / common / sim-trace.c
1 /* Simulator tracing/debugging support.
2    Copyright (C) 1997-2018 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
923         = disassembler (bfd_get_arch (trace_data->dis_bfd),
924                         bfd_big_endian (trace_data->dis_bfd),
925                         bfd_get_mach (trace_data->dis_bfd),
926                         trace_data->dis_bfd);
927       INIT_DISASSEMBLE_INFO (*info, cpu, dis_printf);
928       info->read_memory_func = dis_read;
929       info->arch = bfd_get_arch (bfd);
930       info->mach = bfd_get_mach (bfd);
931       disassemble_init_for_target (info);
932     }
933
934   info->application_data = cpu;
935
936   trace_printf (sd, cpu, "%s %s",
937                 trace_idx_to_str (TRACE_DISASM_IDX),
938                 TRACE_PREFIX (trace_data));
939   trace_data->disassembler (addr, info);
940   trace_printf (sd, cpu, "\n");
941 }
942
943 void
944 trace_input0 (SIM_DESC sd,
945               sim_cpu *cpu,
946               int trace_idx)
947 {
948   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
949   TRACE_IDX (data) = trace_idx;
950 }
951
952 void
953 trace_input_word1 (SIM_DESC sd,
954                    sim_cpu *cpu,
955                    int trace_idx,
956                    unsigned_word d0)
957 {
958   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
959   TRACE_IDX (data) = trace_idx;
960   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);
961 }
962
963 void
964 trace_input_word2 (SIM_DESC sd,
965                    sim_cpu *cpu,
966                    int trace_idx,
967                    unsigned_word d0,
968                    unsigned_word d1)
969 {
970   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
971   TRACE_IDX (data) = trace_idx;
972   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);
973   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d1);
974 }
975
976 void
977 trace_input_word3 (SIM_DESC sd,
978                    sim_cpu *cpu,
979                    int trace_idx,
980                    unsigned_word d0,
981                    unsigned_word d1,
982                    unsigned_word d2)
983 {
984   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
985   TRACE_IDX (data) = trace_idx;
986   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d0);
987   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d1);
988   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &d2);
989 }
990
991 void
992 trace_input_word4 (SIM_DESC sd,
993                    sim_cpu *cpu,
994                    int trace_idx,
995                    unsigned_word d0,
996                    unsigned_word d1,
997                    unsigned_word d2,
998                    unsigned_word d3)
999 {
1000   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1001   TRACE_IDX (data) = trace_idx;
1002   save_data (sd, data, trace_fmt_word, sizeof (d0), &d0);
1003   save_data (sd, data, trace_fmt_word, sizeof (d1), &d1);
1004   save_data (sd, data, trace_fmt_word, sizeof (d2), &d2);
1005   save_data (sd, data, trace_fmt_word, sizeof (d3), &d3);
1006 }
1007
1008 void
1009 trace_input_bool1 (SIM_DESC sd,
1010                    sim_cpu *cpu,
1011                    int trace_idx,
1012                    int d0)
1013 {
1014   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1015   TRACE_IDX (data) = trace_idx;
1016   save_data (sd, data, trace_fmt_bool, sizeof (d0), &d0);
1017 }
1018
1019 void
1020 trace_input_addr1 (SIM_DESC sd,
1021                    sim_cpu *cpu,
1022                    int trace_idx,
1023                    address_word d0)
1024 {
1025   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1026   TRACE_IDX (data) = trace_idx;
1027   save_data (sd, data, trace_fmt_addr, sizeof (d0), &d0);
1028 }
1029
1030 void
1031 trace_input_fp1 (SIM_DESC sd,
1032                  sim_cpu *cpu,
1033                  int trace_idx,
1034                  fp_word f0)
1035 {
1036   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1037   TRACE_IDX (data) = trace_idx;
1038   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
1039 }
1040
1041 void
1042 trace_input_fp2 (SIM_DESC sd,
1043                  sim_cpu *cpu,
1044                  int trace_idx,
1045                  fp_word f0,
1046                  fp_word f1)
1047 {
1048   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1049   TRACE_IDX (data) = trace_idx;
1050   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
1051   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f1);
1052 }
1053
1054 void
1055 trace_input_fp3 (SIM_DESC sd,
1056                  sim_cpu *cpu,
1057                  int trace_idx,
1058                  fp_word f0,
1059                  fp_word f1,
1060                  fp_word f2)
1061 {
1062   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1063   TRACE_IDX (data) = trace_idx;
1064   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
1065   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f1);
1066   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f2);
1067 }
1068
1069 void
1070 trace_input_fpu1 (SIM_DESC sd,
1071                   sim_cpu *cpu,
1072                   int trace_idx,
1073                   sim_fpu *f0)
1074 {
1075   double d;
1076   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1077   TRACE_IDX (data) = trace_idx;
1078   d = sim_fpu_2d (f0);
1079   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1080 }
1081
1082 void
1083 trace_input_fpu2 (SIM_DESC sd,
1084                   sim_cpu *cpu,
1085                   int trace_idx,
1086                   sim_fpu *f0,
1087                   sim_fpu *f1)
1088 {
1089   double d;
1090   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1091   TRACE_IDX (data) = trace_idx;
1092   d = sim_fpu_2d (f0);
1093   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1094   d = sim_fpu_2d (f1);
1095   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1096 }
1097
1098 void
1099 trace_input_fpu3 (SIM_DESC sd,
1100                   sim_cpu *cpu,
1101                   int trace_idx,
1102                   sim_fpu *f0,
1103                   sim_fpu *f1,
1104                   sim_fpu *f2)
1105 {
1106   double d;
1107   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1108   TRACE_IDX (data) = trace_idx;
1109   d = sim_fpu_2d (f0);
1110   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1111   d = sim_fpu_2d (f1);
1112   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1113   d = sim_fpu_2d (f2);
1114   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1115 }
1116
1117 void
1118 trace_result_word1 (SIM_DESC sd,
1119                     sim_cpu *cpu,
1120                     int trace_idx,
1121                     unsigned_word r0)
1122 {
1123   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1124   int last_input;
1125
1126   /* Append any results to the end of the inputs */
1127   last_input = TRACE_INPUT_IDX (data);
1128   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &r0);
1129
1130   trace_results (sd, cpu, trace_idx, last_input);
1131 }
1132
1133 void
1134 trace_result0 (SIM_DESC sd,
1135                sim_cpu *cpu,
1136                int trace_idx)
1137 {
1138   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1139   int last_input;
1140
1141   /* Append any results to the end of the inputs */
1142   last_input = TRACE_INPUT_IDX (data);
1143
1144   trace_results (sd, cpu, trace_idx, last_input);
1145 }
1146
1147 void
1148 trace_result_word2 (SIM_DESC sd,
1149                     sim_cpu *cpu,
1150                     int trace_idx,
1151                     unsigned_word r0,
1152                     unsigned_word r1)
1153 {
1154   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1155   int last_input;
1156
1157   /* Append any results to the end of the inputs */
1158   last_input = TRACE_INPUT_IDX (data);
1159   save_data (sd, data, trace_fmt_word, sizeof (r0), &r0);
1160   save_data (sd, data, trace_fmt_word, sizeof (r1), &r1);
1161
1162   trace_results (sd, cpu, trace_idx, last_input);
1163 }
1164
1165 void
1166 trace_result_word4 (SIM_DESC sd,
1167                     sim_cpu *cpu,
1168                     int trace_idx,
1169                     unsigned_word r0,
1170                     unsigned_word r1,
1171                     unsigned_word r2,
1172                     unsigned_word r3)
1173 {
1174   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1175   int last_input;
1176
1177   /* Append any results to the end of the inputs */
1178   last_input = TRACE_INPUT_IDX (data);
1179   save_data (sd, data, trace_fmt_word, sizeof (r0), &r0);
1180   save_data (sd, data, trace_fmt_word, sizeof (r1), &r1);
1181   save_data (sd, data, trace_fmt_word, sizeof (r2), &r2);
1182   save_data (sd, data, trace_fmt_word, sizeof (r3), &r3);
1183
1184   trace_results (sd, cpu, trace_idx, last_input);
1185 }
1186
1187 void
1188 trace_result_bool1 (SIM_DESC sd,
1189                     sim_cpu *cpu,
1190                     int trace_idx,
1191                     int r0)
1192 {
1193   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1194   int last_input;
1195
1196   /* Append any results to the end of the inputs */
1197   last_input = TRACE_INPUT_IDX (data);
1198   save_data (sd, data, trace_fmt_bool, sizeof (r0), &r0);
1199
1200   trace_results (sd, cpu, trace_idx, last_input);
1201 }
1202
1203 void
1204 trace_result_addr1 (SIM_DESC sd,
1205                     sim_cpu *cpu,
1206                     int trace_idx,
1207                     address_word r0)
1208 {
1209   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1210   int last_input;
1211
1212   /* Append any results to the end of the inputs */
1213   last_input = TRACE_INPUT_IDX (data);
1214   save_data (sd, data, trace_fmt_addr, sizeof (r0), &r0);
1215
1216   trace_results (sd, cpu, trace_idx, last_input);
1217 }
1218
1219 void
1220 trace_result_fp1 (SIM_DESC sd,
1221                   sim_cpu *cpu,
1222                   int trace_idx,
1223                   fp_word f0)
1224 {
1225   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1226   int last_input;
1227
1228   /* Append any results to the end of the inputs */
1229   last_input = TRACE_INPUT_IDX (data);
1230   save_data (sd, data, trace_fmt_fp, sizeof (fp_word), &f0);
1231
1232   trace_results (sd, cpu, trace_idx, last_input);
1233 }
1234
1235 void
1236 trace_result_fp2 (SIM_DESC sd,
1237                   sim_cpu *cpu,
1238                   int trace_idx,
1239                   fp_word f0,
1240                   fp_word f1)
1241 {
1242   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1243   int last_input;
1244
1245   /* Append any results to the end of the inputs */
1246   last_input = TRACE_INPUT_IDX (data);
1247   save_data (sd, data, trace_fmt_fp, sizeof (f0), &f0);
1248   save_data (sd, data, trace_fmt_fp, sizeof (f1), &f1);
1249
1250   trace_results (sd, cpu, trace_idx, last_input);
1251 }
1252
1253 void
1254 trace_result_fpu1 (SIM_DESC sd,
1255                    sim_cpu *cpu,
1256                    int trace_idx,
1257                    sim_fpu *f0)
1258 {
1259   double d;
1260   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1261   int last_input;
1262
1263   /* Append any results to the end of the inputs */
1264   last_input = TRACE_INPUT_IDX (data);
1265   d = sim_fpu_2d (f0);
1266   save_data (sd, data, trace_fmt_fp, sizeof (double), &d);
1267
1268   trace_results (sd, cpu, trace_idx, last_input);
1269 }
1270
1271 void
1272 trace_result_string1 (SIM_DESC sd,
1273                       sim_cpu *cpu,
1274                       int trace_idx,
1275                       char *s0)
1276 {
1277   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1278   int last_input;
1279
1280   /* Append any results to the end of the inputs */
1281   last_input = TRACE_INPUT_IDX (data);
1282   save_data (sd, data, trace_fmt_string, strlen (s0) + 1, s0);
1283
1284   trace_results (sd, cpu, trace_idx, last_input);
1285 }
1286
1287 void
1288 trace_result_word1_string1 (SIM_DESC sd,
1289                             sim_cpu *cpu,
1290                             int trace_idx,
1291                             unsigned_word r0,
1292                             char *s0)
1293 {
1294   TRACE_DATA *data = CPU_TRACE_DATA (cpu);
1295   int last_input;
1296
1297   /* Append any results to the end of the inputs */
1298   last_input = TRACE_INPUT_IDX (data);
1299   save_data (sd, data, trace_fmt_word, sizeof (unsigned_word), &r0);
1300   save_data (sd, data, trace_fmt_string, strlen (s0) + 1, s0);
1301
1302   trace_results (sd, cpu, trace_idx, last_input);
1303 }
1304 \f
1305 void
1306 trace_vprintf (SIM_DESC sd, sim_cpu *cpu, const char *fmt, va_list ap)
1307 {
1308   if (cpu != NULL)
1309     {
1310       if (TRACE_FILE (CPU_TRACE_DATA (cpu)) != NULL)
1311         vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu)), fmt, ap);
1312       else
1313         sim_io_evprintf (sd, fmt, ap);
1314     }
1315   else
1316     {
1317       if (TRACE_FILE (STATE_TRACE_DATA (sd)) != NULL)
1318         vfprintf (TRACE_FILE (STATE_TRACE_DATA (sd)), fmt, ap);
1319       else
1320         sim_io_evprintf (sd, fmt, ap);
1321     }
1322 }
1323
1324 void
1325 trace_printf (SIM_DESC sd, sim_cpu *cpu, const char *fmt, ...)
1326 {
1327   va_list ap;
1328
1329   va_start (ap, fmt);
1330
1331   trace_vprintf (sd, cpu, fmt, ap);
1332
1333   va_end (ap);
1334 }
1335
1336 void
1337 sim_debug_printf (sim_cpu *cpu, const char *fmt, ...)
1338 {
1339   va_list ap;
1340
1341   va_start (ap, fmt);
1342
1343   if (CPU_DEBUG_FILE (cpu) == NULL)
1344     (* STATE_CALLBACK (CPU_STATE (cpu))->evprintf_filtered)
1345       (STATE_CALLBACK (CPU_STATE (cpu)), fmt, ap);
1346   else
1347     vfprintf (CPU_DEBUG_FILE (cpu), fmt, ap);
1348
1349   va_end (ap);
1350 }