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