1/* Simulator tracing/debugging support. 2 Copyright (C) 1997, 1998, 2001, 2007 Free Software Foundation, Inc. 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 9the Free Software Foundation; either version 3 of the License, or 10(at your option) any later version. 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 17You should have received a copy of the GNU General Public License 18along 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 57static MODULE_INIT_FN trace_init; 58static MODULE_UNINSTALL_FN trace_uninstall; 59 60static DECLARE_OPTION_HANDLER (trace_option_handler); 61 62enum { 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 82static 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 148static SIM_RC 149set_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 227static SIM_RC 228set_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 238static SIM_RC 239trace_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 424/* Install tracing support. */ 425 426SIM_RC 427trace_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 443static SIM_RC 444trace_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 471static void 472trace_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 496typedef 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 */ 508static int 509save_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 */ 518static void 519save_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 535static void 536print_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 616static const char * 617trace_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 638static void 639trace_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 677void 678trace_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 826void 827trace_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 843void 844trace_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 852void 853trace_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 863void 864trace_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 876void 877trace_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 891void 892trace_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 908void 909trace_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 919void 920trace_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 930void 931trace_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 941void 942trace_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 954void 955trace_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 969void 970trace_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 982void 983trace_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 998void 999trace_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 1017void 1018trace_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 1033void 1034trace_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 1047void 1048trace_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 1065void 1066trace_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 1087void 1088trace_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 1103void 1104trace_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 1119void 1120trace_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 1135void 1136trace_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 1153void 1154trace_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 1171void 1172trace_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 1187void 1188trace_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 1205void 1206trace_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. */ 1226void 1227trace_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 1309void 1310trace_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 1331void 1332debug_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} 1354