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