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