1 /* Simulator tracing/debugging support. 2 Copyright (C) 1997-2024 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 file is meant to be included by sim-basics.h. */ 21 22 #ifndef SIM_TRACE_H 23 #define SIM_TRACE_H 24 25 #include <stdarg.h> 26 27 #include "ansidecl.h" 28 #include "bfd.h" 29 #include "dis-asm.h" 30 31 /* Standard traceable entities. */ 32 33 enum { 34 /* Trace insn execution. The port itself is responsible for displaying what 35 it thinks it is decoding. */ 36 TRACE_INSN_IDX = 1, 37 38 /* Disassemble code addresses. Like insn tracing, but relies on the opcode 39 framework for displaying code. Can be slower, more accurate as to what 40 the binary code actually is, but not how the sim is decoding it. */ 41 TRACE_DISASM_IDX, 42 43 /* Trace insn decoding. 44 ??? This is more of a simulator debugging operation and might best be 45 moved to --debug-decode. */ 46 TRACE_DECODE_IDX, 47 48 /* Trace insn extraction. 49 ??? This is more of a simulator debugging operation and might best be 50 moved to --debug-extract. */ 51 TRACE_EXTRACT_IDX, 52 53 /* Trace insn execution but include line numbers. */ 54 TRACE_LINENUM_IDX, 55 56 /* Trace memory operations. 57 The difference between this and TRACE_CORE_IDX is (I think) that this 58 is intended to apply to a higher level. TRACE_CORE_IDX applies to the 59 low level core operations. */ 60 TRACE_MEMORY_IDX, 61 62 /* Include model performance data in tracing output. */ 63 TRACE_MODEL_IDX, 64 65 /* Trace ALU (Arithmetic Logic Unit) operations. */ 66 TRACE_ALU_IDX, 67 68 /* Trace memory core operations. */ 69 TRACE_CORE_IDX, 70 71 /* Trace events. */ 72 TRACE_EVENTS_IDX, 73 74 /* Trace FPU (Floating Point Unit) operations. */ 75 TRACE_FPU_IDX, 76 77 /* Trace VPU (Vector Processing Unit) operations. */ 78 TRACE_VPU_IDX, 79 80 /* Trace branching. */ 81 TRACE_BRANCH_IDX, 82 83 /* Trace syscalls. */ 84 TRACE_SYSCALL_IDX, 85 86 /* Trace cpu register accesses. Registers that are part of hardware devices 87 should use the HW_TRACE macros instead. */ 88 TRACE_REGISTER_IDX, 89 90 /* Add information useful for debugging the simulator to trace output. */ 91 TRACE_DEBUG_IDX, 92 93 /* Simulator specific trace bits begin here. */ 94 TRACE_NEXT_IDX, 95 96 }; 97 /* Maximum number of traceable entities. */ 98 #ifndef MAX_TRACE_VALUES 99 #define MAX_TRACE_VALUES 32 100 #endif 101 102 /* The -t option only prints useful values. It's easy to type and shouldn't 103 splat on the screen everything under the sun making nothing easy to 104 find. */ 105 #define TRACE_USEFUL_MASK \ 106 (TRACE_insn | TRACE_linenum | TRACE_memory | TRACE_model) 107 108 /* Masks so WITH_TRACE can have symbolic values. 109 The case choice here is on purpose. The lowercase parts are args to 110 --with-trace. */ 111 #define TRACE_insn (1 << TRACE_INSN_IDX) 112 #define TRACE_disasm (1 << TRACE_DISASM_IDX) 113 #define TRACE_decode (1 << TRACE_DECODE_IDX) 114 #define TRACE_extract (1 << TRACE_EXTRACT_IDX) 115 #define TRACE_linenum (1 << TRACE_LINENUM_IDX) 116 #define TRACE_memory (1 << TRACE_MEMORY_IDX) 117 #define TRACE_model (1 << TRACE_MODEL_IDX) 118 #define TRACE_alu (1 << TRACE_ALU_IDX) 119 #define TRACE_core (1 << TRACE_CORE_IDX) 120 #define TRACE_events (1 << TRACE_EVENTS_IDX) 121 #define TRACE_fpu (1 << TRACE_FPU_IDX) 122 #define TRACE_vpu (1 << TRACE_VPU_IDX) 123 #define TRACE_branch (1 << TRACE_BRANCH_IDX) 124 #define TRACE_syscall (1 << TRACE_SYSCALL_IDX) 125 #define TRACE_register (1 << TRACE_REGISTER_IDX) 126 #define TRACE_debug (1 << TRACE_DEBUG_IDX) 127 128 /* Return non-zero if tracing of idx is enabled (compiled in). */ 129 #define WITH_TRACE_P(idx) ((WITH_TRACE & (1 << idx)) != 0) 130 131 /* Preprocessor macros to simplify tests of WITH_TRACE. */ 132 #define WITH_TRACE_ANY_P (WITH_TRACE != 0) 133 #define WITH_TRACE_INSN_P WITH_TRACE_P (TRACE_INSN_IDX) 134 #define WITH_TRACE_DISASM_P WITH_TRACE_P (TRACE_DISASM_IDX) 135 #define WITH_TRACE_DECODE_P WITH_TRACE_P (TRACE_DECODE_IDX) 136 #define WITH_TRACE_EXTRACT_P WITH_TRACE_P (TRACE_EXTRACT_IDX) 137 #define WITH_TRACE_LINENUM_P WITH_TRACE_P (TRACE_LINENUM_IDX) 138 #define WITH_TRACE_MEMORY_P WITH_TRACE_P (TRACE_MEMORY_IDX) 139 #define WITH_TRACE_MODEL_P WITH_TRACE_P (TRACE_MODEL_IDX) 140 #define WITH_TRACE_ALU_P WITH_TRACE_P (TRACE_ALU_IDX) 141 #define WITH_TRACE_CORE_P WITH_TRACE_P (TRACE_CORE_IDX) 142 #define WITH_TRACE_EVENTS_P WITH_TRACE_P (TRACE_EVENTS_IDX) 143 #define WITH_TRACE_FPU_P WITH_TRACE_P (TRACE_FPU_IDX) 144 #define WITH_TRACE_VPU_P WITH_TRACE_P (TRACE_VPU_IDX) 145 #define WITH_TRACE_BRANCH_P WITH_TRACE_P (TRACE_BRANCH_IDX) 146 #define WITH_TRACE_SYSCALL_P WITH_TRACE_P (TRACE_SYSCALL_IDX) 147 #define WITH_TRACE_REGISTER_P WITH_TRACE_P (TRACE_REGISTER_IDX) 148 #define WITH_TRACE_DEBUG_P WITH_TRACE_P (TRACE_DEBUG_IDX) 149 150 /* Struct containing all system and cpu trace data. 151 152 System trace data is stored with the associated module. 153 System and cpu tracing must share the same space of bitmasks as they 154 are arguments to --with-trace. One could have --with-trace and 155 --with-cpu-trace or some such but that's an over-complication at this point 156 in time. Also, there may be occasions where system and cpu tracing may 157 wish to share a name. */ 158 159 typedef struct _trace_data { 160 161 /* Global summary of all the current trace options */ 162 char trace_any_p; 163 164 /* Boolean array of specified tracing flags. */ 165 /* ??? It's not clear that using an array vs a bit mask is faster. 166 Consider the case where one wants to test whether any of several bits 167 are set. */ 168 char trace_flags[MAX_TRACE_VALUES]; 169 #define TRACE_FLAGS(t) ((t)->trace_flags) 170 171 /* Tracing output goes to this or stderr if NULL. 172 We can't store `stderr' here as stderr goes through a callback. */ 173 FILE *trace_file; 174 #define TRACE_FILE(t) ((t)->trace_file) 175 176 /* Buffer to store the prefix to be printed before any trace line. */ 177 char trace_prefix[256]; 178 #define TRACE_PREFIX(t) ((t)->trace_prefix) 179 180 /* Buffer to save the inputs for the current instruction. Use a 181 union to force the buffer into correct alignment */ 182 union { 183 uint8_t i8; 184 uint16_t i16; 185 uint32_t i32; 186 uint64_t i64; 187 } trace_input_data[16]; 188 uint8_t trace_input_fmt[16]; 189 uint8_t trace_input_size[16]; 190 int trace_input_idx; 191 #define TRACE_INPUT_DATA(t) ((t)->trace_input_data) 192 #define TRACE_INPUT_FMT(t) ((t)->trace_input_fmt) 193 #define TRACE_INPUT_SIZE(t) ((t)->trace_input_size) 194 #define TRACE_INPUT_IDX(t) ((t)->trace_input_idx) 195 196 /* Category of trace being performed */ 197 int trace_idx; 198 #define TRACE_IDX(t) ((t)->trace_idx) 199 200 /* Trace range. 201 ??? Not all cpu's support this. */ 202 ADDR_RANGE range; 203 #define TRACE_RANGE(t) (& (t)->range) 204 205 /* The bfd used to disassemble code. Should compare against STATE_PROG_BFD 206 before using the disassembler helper. 207 Meant for use by the internal trace module only. */ 208 struct bfd *dis_bfd; 209 210 /* The function used to actually disassemble code. 211 Meant for use by the internal trace module only. */ 212 disassembler_ftype disassembler; 213 214 /* State used with the disassemble function. 215 Meant for use by the internal trace module only. */ 216 disassemble_info dis_info; 217 } TRACE_DATA; 218 219 /* System tracing support. */ 220 221 #define STATE_TRACE_FLAGS(sd) TRACE_FLAGS (STATE_TRACE_DATA (sd)) 222 223 /* Return non-zero if tracing of IDX is enabled for non-cpu specific 224 components. The "S" in "STRACE" refers to "System". */ 225 #define STRACE_P(sd,idx) \ 226 (WITH_TRACE_P (idx) && STATE_TRACE_FLAGS (sd)[idx] != 0) 227 228 /* Non-zero if --trace-<xxxx> was specified for SD. */ 229 #define STRACE_ANY_P(sd) (WITH_TRACE_ANY_P && (STATE_TRACE_DATA (sd)->trace_any_p)) 230 #define STRACE_INSN_P(sd) STRACE_P (sd, TRACE_INSN_IDX) 231 #define STRACE_DISASM_P(sd) STRACE_P (sd, TRACE_DISASM_IDX) 232 #define STRACE_DECODE_P(sd) STRACE_P (sd, TRACE_DECODE_IDX) 233 #define STRACE_EXTRACT_P(sd) STRACE_P (sd, TRACE_EXTRACT_IDX) 234 #define STRACE_LINENUM_P(sd) STRACE_P (sd, TRACE_LINENUM_IDX) 235 #define STRACE_MEMORY_P(sd) STRACE_P (sd, TRACE_MEMORY_IDX) 236 #define STRACE_MODEL_P(sd) STRACE_P (sd, TRACE_MODEL_IDX) 237 #define STRACE_ALU_P(sd) STRACE_P (sd, TRACE_ALU_IDX) 238 #define STRACE_CORE_P(sd) STRACE_P (sd, TRACE_CORE_IDX) 239 #define STRACE_EVENTS_P(sd) STRACE_P (sd, TRACE_EVENTS_IDX) 240 #define STRACE_FPU_P(sd) STRACE_P (sd, TRACE_FPU_IDX) 241 #define STRACE_VPU_P(sd) STRACE_P (sd, TRACE_VPU_IDX) 242 #define STRACE_BRANCH_P(sd) STRACE_P (sd, TRACE_BRANCH_IDX) 243 #define STRACE_SYSCALL_P(sd) STRACE_P (sd, TRACE_SYSCALL_IDX) 244 #define STRACE_REGISTER_P(sd) STRACE_P (sd, TRACE_REGISTER_IDX) 245 #define STRACE_DEBUG_P(sd) STRACE_P (sd, TRACE_DEBUG_IDX) 246 247 /* Helper functions for printing messages. */ 248 #define STRACE(sd, idx, fmt, args...) \ 249 do { \ 250 if (STRACE_P (sd, idx)) \ 251 trace_generic (sd, NULL, idx, fmt, ## args); \ 252 } while (0) 253 #define STRACE_INSN(sd, fmt, args...) STRACE (sd, TRACE_INSN_IDX, fmt, ## args) 254 #define STRACE_DISASM(sd, fmt, args...) STRACE (sd, TRACE_DISASM_IDX, fmt, ## args) 255 #define STRACE_DECODE(sd, fmt, args...) STRACE (sd, TRACE_DECODE_IDX, fmt, ## args) 256 #define STRACE_EXTRACT(sd, fmt, args...) STRACE (sd, TRACE_EXTRACT_IDX, fmt, ## args) 257 #define STRACE_LINENUM(sd, fmt, args...) STRACE (sd, TRACE_LINENUM_IDX, fmt, ## args) 258 #define STRACE_MEMORY(sd, fmt, args...) STRACE (sd, TRACE_MEMORY_IDX, fmt, ## args) 259 #define STRACE_MODEL(sd, fmt, args...) STRACE (sd, TRACE_MODEL_IDX, fmt, ## args) 260 #define STRACE_ALU(sd, fmt, args...) STRACE (sd, TRACE_ALU_IDX, fmt, ## args) 261 #define STRACE_CORE(sd, fmt, args...) STRACE (sd, TRACE_CORE_IDX, fmt, ## args) 262 #define STRACE_EVENTS(sd, fmt, args...) STRACE (sd, TRACE_EVENTS_IDX, fmt, ## args) 263 #define STRACE_FPU(sd, fmt, args...) STRACE (sd, TRACE_FPU_IDX, fmt, ## args) 264 #define STRACE_VPU(sd, fmt, args...) STRACE (sd, TRACE_VPU_IDX, fmt, ## args) 265 #define STRACE_BRANCH(sd, fmt, args...) STRACE (sd, TRACE_BRANCH_IDX, fmt, ## args) 266 #define STRACE_SYSCALL(sd, fmt, args...) STRACE (sd, TRACE_SYSCALL_IDX, fmt, ## args) 267 #define STRACE_REGISTER(sd, fmt, args...) STRACE (sd, TRACE_REGISTER_IDX, fmt, ## args) 268 #define STRACE_DEBUG(sd, fmt, args...) STRACE (sd, TRACE_DEBUG_IDX, fmt, ## args) 269 270 /* CPU tracing support. */ 271 272 #define CPU_TRACE_FLAGS(cpu) TRACE_FLAGS (CPU_TRACE_DATA (cpu)) 273 274 /* Return non-zero if tracing of IDX is enabled for CPU. */ 275 #define TRACE_P(cpu,idx) \ 276 (WITH_TRACE_P (idx) && CPU_TRACE_FLAGS (cpu)[idx] != 0) 277 278 /* Non-zero if --trace-<xxxx> was specified for CPU. */ 279 #define TRACE_ANY_P(cpu) (WITH_TRACE_ANY_P && (CPU_TRACE_DATA (cpu)->trace_any_p)) 280 #define TRACE_INSN_P(cpu) TRACE_P (cpu, TRACE_INSN_IDX) 281 #define TRACE_DISASM_P(cpu) TRACE_P (cpu, TRACE_DISASM_IDX) 282 #define TRACE_DECODE_P(cpu) TRACE_P (cpu, TRACE_DECODE_IDX) 283 #define TRACE_EXTRACT_P(cpu) TRACE_P (cpu, TRACE_EXTRACT_IDX) 284 #define TRACE_LINENUM_P(cpu) TRACE_P (cpu, TRACE_LINENUM_IDX) 285 #define TRACE_MEMORY_P(cpu) TRACE_P (cpu, TRACE_MEMORY_IDX) 286 #define TRACE_MODEL_P(cpu) TRACE_P (cpu, TRACE_MODEL_IDX) 287 #define TRACE_ALU_P(cpu) TRACE_P (cpu, TRACE_ALU_IDX) 288 #define TRACE_CORE_P(cpu) TRACE_P (cpu, TRACE_CORE_IDX) 289 #define TRACE_EVENTS_P(cpu) TRACE_P (cpu, TRACE_EVENTS_IDX) 290 #define TRACE_FPU_P(cpu) TRACE_P (cpu, TRACE_FPU_IDX) 291 #define TRACE_VPU_P(cpu) TRACE_P (cpu, TRACE_VPU_IDX) 292 #define TRACE_BRANCH_P(cpu) TRACE_P (cpu, TRACE_BRANCH_IDX) 293 #define TRACE_SYSCALL_P(cpu) TRACE_P (cpu, TRACE_SYSCALL_IDX) 294 #define TRACE_REGISTER_P(cpu) TRACE_P (cpu, TRACE_REGISTER_IDX) 295 #define TRACE_DEBUG_P(cpu) TRACE_P (cpu, TRACE_DEBUG_IDX) 296 #define TRACE_DISASM_P(cpu) TRACE_P (cpu, TRACE_DISASM_IDX) 297 298 /* Helper functions for printing messages. */ 299 #define TRACE(cpu, idx, fmt, args...) \ 300 do { \ 301 if (TRACE_P (cpu, idx)) \ 302 trace_generic (CPU_STATE (cpu), cpu, idx, fmt, ## args); \ 303 } while (0) 304 #define TRACE_INSN(cpu, fmt, args...) TRACE (cpu, TRACE_INSN_IDX, fmt, ## args) 305 #define TRACE_DECODE(cpu, fmt, args...) TRACE (cpu, TRACE_DECODE_IDX, fmt, ## args) 306 #define TRACE_EXTRACT(cpu, fmt, args...) TRACE (cpu, TRACE_EXTRACT_IDX, fmt, ## args) 307 #define TRACE_LINENUM(cpu, fmt, args...) TRACE (cpu, TRACE_LINENUM_IDX, fmt, ## args) 308 #define TRACE_MEMORY(cpu, fmt, args...) TRACE (cpu, TRACE_MEMORY_IDX, fmt, ## args) 309 #define TRACE_MODEL(cpu, fmt, args...) TRACE (cpu, TRACE_MODEL_IDX, fmt, ## args) 310 #define TRACE_ALU(cpu, fmt, args...) TRACE (cpu, TRACE_ALU_IDX, fmt, ## args) 311 #define TRACE_CORE(cpu, fmt, args...) TRACE (cpu, TRACE_CORE_IDX, fmt, ## args) 312 #define TRACE_EVENTS(cpu, fmt, args...) TRACE (cpu, TRACE_EVENTS_IDX, fmt, ## args) 313 #define TRACE_FPU(cpu, fmt, args...) TRACE (cpu, TRACE_FPU_IDX, fmt, ## args) 314 #define TRACE_VPU(cpu, fmt, args...) TRACE (cpu, TRACE_VPU_IDX, fmt, ## args) 315 #define TRACE_BRANCH(cpu, fmt, args...) TRACE (cpu, TRACE_BRANCH_IDX, fmt, ## args) 316 #define TRACE_SYSCALL(cpu, fmt, args...) TRACE (cpu, TRACE_SYSCALL_IDX, fmt, ## args) 317 #define TRACE_REGISTER(cpu, fmt, args...) TRACE (cpu, TRACE_REGISTER_IDX, fmt, ## args) 318 #define TRACE_DEBUG(cpu, fmt, args...) TRACE (cpu, TRACE_DEBUG_IDX, fmt, ## args) 319 #define TRACE_DISASM(cpu, addr) \ 320 do { \ 321 if (TRACE_DISASM_P (cpu)) \ 322 trace_disasm (CPU_STATE (cpu), cpu, addr); \ 323 } while (0) 324 325 /* Tracing functions. */ 326 327 /* Prime the trace buffers ready for any trace output. 328 Must be called prior to any other trace operation */ 329 extern void trace_prefix (SIM_DESC sd, 330 sim_cpu *cpu, 331 sim_cia cia, 332 address_word pc, 333 int print_linenum_p, 334 const char *file_name, 335 int line_nr, 336 const char *fmt, 337 ...) ATTRIBUTE_PRINTF (8, 9); 338 339 /* Generic trace print, assumes trace_prefix() has been called */ 340 341 extern void trace_generic (SIM_DESC sd, 342 sim_cpu *cpu, 343 int trace_idx, 344 const char *fmt, 345 ...) ATTRIBUTE_PRINTF (4, 5); 346 347 /* Disassemble the specified address. */ 348 349 extern void trace_disasm (SIM_DESC sd, sim_cpu *cpu, address_word addr); 350 351 typedef enum { 352 trace_fmt_invalid, 353 trace_fmt_word, 354 trace_fmt_fp, 355 trace_fmt_fpu, 356 trace_fmt_string, 357 trace_fmt_bool, 358 trace_fmt_addr, 359 trace_fmt_instruction_incomplete, 360 } data_fmt; 361 362 /* Trace a varying number of word sized inputs/outputs. trace_result* 363 must be called to close the trace operation. */ 364 365 extern void save_data (SIM_DESC sd, 366 TRACE_DATA *data, 367 data_fmt fmt, 368 long size, 369 const void *buf); 370 371 extern void trace_input0 (SIM_DESC sd, 372 sim_cpu *cpu, 373 int trace_idx); 374 375 extern void trace_input_word1 (SIM_DESC sd, 376 sim_cpu *cpu, 377 int trace_idx, 378 unsigned_word d0); 379 380 extern void trace_input_word2 (SIM_DESC sd, 381 sim_cpu *cpu, 382 int trace_idx, 383 unsigned_word d0, 384 unsigned_word d1); 385 386 extern void trace_input_word3 (SIM_DESC sd, 387 sim_cpu *cpu, 388 int trace_idx, 389 unsigned_word d0, 390 unsigned_word d1, 391 unsigned_word d2); 392 393 extern void trace_input_word4 (SIM_DESC sd, 394 sim_cpu *cpu, 395 int trace_idx, 396 unsigned_word d0, 397 unsigned_word d1, 398 unsigned_word d2, 399 unsigned_word d3); 400 401 extern void trace_input_addr1 (SIM_DESC sd, 402 sim_cpu *cpu, 403 int trace_idx, 404 address_word d0); 405 406 extern void trace_input_bool1 (SIM_DESC sd, 407 sim_cpu *cpu, 408 int trace_idx, 409 int d0); 410 411 extern void trace_input_fp1 (SIM_DESC sd, 412 sim_cpu *cpu, 413 int trace_idx, 414 fp_word f0); 415 416 extern void trace_input_fp2 (SIM_DESC sd, 417 sim_cpu *cpu, 418 int trace_idx, 419 fp_word f0, 420 fp_word f1); 421 422 extern void trace_input_fp3 (SIM_DESC sd, 423 sim_cpu *cpu, 424 int trace_idx, 425 fp_word f0, 426 fp_word f1, 427 fp_word f2); 428 429 extern void trace_input_fpu1 (SIM_DESC sd, 430 sim_cpu *cpu, 431 int trace_idx, 432 struct _sim_fpu *f0); 433 434 extern void trace_input_fpu2 (SIM_DESC sd, 435 sim_cpu *cpu, 436 int trace_idx, 437 struct _sim_fpu *f0, 438 struct _sim_fpu *f1); 439 440 extern void trace_input_fpu3 (SIM_DESC sd, 441 sim_cpu *cpu, 442 int trace_idx, 443 struct _sim_fpu *f0, 444 struct _sim_fpu *f1, 445 struct _sim_fpu *f2); 446 447 /* Other trace_input{_<fmt><nr-inputs>} functions can go here */ 448 449 extern void trace_result0 (SIM_DESC sd, 450 sim_cpu *cpu, 451 int trace_idx); 452 453 extern void trace_result_word1 (SIM_DESC sd, 454 sim_cpu *cpu, 455 int trace_idx, 456 unsigned_word r0); 457 458 extern void trace_result_word2 (SIM_DESC sd, 459 sim_cpu *cpu, 460 int trace_idx, 461 unsigned_word r0, 462 unsigned_word r1); 463 464 extern void trace_result_word4 (SIM_DESC sd, 465 sim_cpu *cpu, 466 int trace_idx, 467 unsigned_word r0, 468 unsigned_word r1, 469 unsigned_word r2, 470 unsigned_word r3); 471 472 extern void trace_result_bool1 (SIM_DESC sd, 473 sim_cpu *cpu, 474 int trace_idx, 475 int r0); 476 477 extern void trace_result_addr1 (SIM_DESC sd, 478 sim_cpu *cpu, 479 int trace_idx, 480 address_word r0); 481 482 extern void trace_result_fp1 (SIM_DESC sd, 483 sim_cpu *cpu, 484 int trace_idx, 485 fp_word f0); 486 487 extern void trace_result_fp2 (SIM_DESC sd, 488 sim_cpu *cpu, 489 int trace_idx, 490 fp_word f0, 491 fp_word f1); 492 493 extern void trace_result_fpu1 (SIM_DESC sd, 494 sim_cpu *cpu, 495 int trace_idx, 496 struct _sim_fpu *f0); 497 498 extern void trace_result_string1 (SIM_DESC sd, 499 sim_cpu *cpu, 500 int trace_idx, 501 char *str0); 502 503 extern void trace_result_word1_string1 (SIM_DESC sd, 504 sim_cpu *cpu, 505 int trace_idx, 506 unsigned_word r0, 507 char *s0); 508 509 /* Other trace_result{_<type><nr-results>} */ 510 511 512 /* Macros for tracing ALU instructions */ 513 514 #define TRACE_ALU_INPUT0() \ 515 do { \ 516 if (TRACE_ALU_P (CPU)) \ 517 trace_input0 (SD, CPU, TRACE_ALU_IDX); \ 518 } while (0) 519 520 #define TRACE_ALU_INPUT1(V0) \ 521 do { \ 522 if (TRACE_ALU_P (CPU)) \ 523 trace_input_word1 (SD, CPU, TRACE_ALU_IDX, (V0)); \ 524 } while (0) 525 526 #define TRACE_ALU_INPUT2(V0,V1) \ 527 do { \ 528 if (TRACE_ALU_P (CPU)) \ 529 trace_input_word2 (SD, CPU, TRACE_ALU_IDX, (V0), (V1)); \ 530 } while (0) 531 532 #define TRACE_ALU_INPUT3(V0,V1,V2) \ 533 do { \ 534 if (TRACE_ALU_P (CPU)) \ 535 trace_input_word3 (SD, CPU, TRACE_ALU_IDX, (V0), (V1), (V2)); \ 536 } while (0) 537 538 #define TRACE_ALU_INPUT4(V0,V1,V2,V3) \ 539 do { \ 540 if (TRACE_ALU_P (CPU)) \ 541 trace_input_word4 (SD, CPU, TRACE_ALU_IDX, (V0), (V1), (V2), (V3)); \ 542 } while (0) 543 544 #define TRACE_ALU_RESULT(R0) TRACE_ALU_RESULT1(R0) 545 546 #define TRACE_ALU_RESULT0() \ 547 do { \ 548 if (TRACE_ALU_P (CPU)) \ 549 trace_result0 (SD, CPU, TRACE_ALU_IDX); \ 550 } while (0) 551 552 #define TRACE_ALU_RESULT1(R0) \ 553 do { \ 554 if (TRACE_ALU_P (CPU)) \ 555 trace_result_word1 (SD, CPU, TRACE_ALU_IDX, (R0)); \ 556 } while (0) 557 558 #define TRACE_ALU_RESULT2(R0,R1) \ 559 do { \ 560 if (TRACE_ALU_P (CPU)) \ 561 trace_result_word2 (SD, CPU, TRACE_ALU_IDX, (R0), (R1)); \ 562 } while (0) 563 564 #define TRACE_ALU_RESULT4(R0,R1,R2,R3) \ 565 do { \ 566 if (TRACE_ALU_P (CPU)) \ 567 trace_result_word4 (SD, CPU, TRACE_ALU_IDX, (R0), (R1), (R2), (R3)); \ 568 } while (0) 569 570 /* Macros for tracing inputs to comparative branch instructions. */ 571 572 #define TRACE_BRANCH_INPUT1(V0) \ 573 do { \ 574 if (TRACE_BRANCH_P (CPU)) \ 575 trace_input_word1 (SD, CPU, TRACE_BRANCH_IDX, (V0)); \ 576 } while (0) 577 578 #define TRACE_BRANCH_INPUT2(V0,V1) \ 579 do { \ 580 if (TRACE_BRANCH_P (CPU)) \ 581 trace_input_word2 (SD, CPU, TRACE_BRANCH_IDX, (V0), (V1)); \ 582 } while (0) 583 584 /* Macros for tracing FPU instructions */ 585 586 #define TRACE_FP_INPUT0() \ 587 do { \ 588 if (TRACE_FPU_P (CPU)) \ 589 trace_input0 (SD, CPU, TRACE_FPU_IDX); \ 590 } while (0) 591 592 #define TRACE_FP_INPUT1(V0) \ 593 do { \ 594 if (TRACE_FPU_P (CPU)) \ 595 trace_input_fp1 (SD, CPU, TRACE_FPU_IDX, (V0)); \ 596 } while (0) 597 598 #define TRACE_FP_INPUT2(V0,V1) \ 599 do { \ 600 if (TRACE_FPU_P (CPU)) \ 601 trace_input_fp2 (SD, CPU, TRACE_FPU_IDX, (V0), (V1)); \ 602 } while (0) 603 604 #define TRACE_FP_INPUT3(V0,V1,V2) \ 605 do { \ 606 if (TRACE_FPU_P (CPU)) \ 607 trace_input_fp3 (SD, CPU, TRACE_FPU_IDX, (V0), (V1), (V2)); \ 608 } while (0) 609 610 #define TRACE_FP_INPUT_WORD1(V0) \ 611 do { \ 612 if (TRACE_FPU_P (CPU)) \ 613 trace_input_word1 (SD, CPU, TRACE_FPU_IDX, (V0)); \ 614 } while (0) 615 616 #define TRACE_FP_RESULT(R0) \ 617 do { \ 618 if (TRACE_FPU_P (CPU)) \ 619 trace_result_fp1 (SD, CPU, TRACE_FPU_IDX, (R0)); \ 620 } while (0) 621 622 #define TRACE_FP_RESULT2(R0,R1) \ 623 do { \ 624 if (TRACE_FPU_P (CPU)) \ 625 trace_result_fp2 (SD, CPU, TRACE_FPU_IDX, (R0), (R1)); \ 626 } while (0) 627 628 #define TRACE_FP_RESULT_BOOL(R0) \ 629 do { \ 630 if (TRACE_FPU_P (CPU)) \ 631 trace_result_bool1 (SD, CPU, TRACE_FPU_IDX, (R0)); \ 632 } while (0) 633 634 #define TRACE_FP_RESULT_WORD(R0) \ 635 do { \ 636 if (TRACE_FPU_P (CPU)) \ 637 trace_result_word1 (SD, CPU, TRACE_FPU_IDX, (R0)); \ 638 } while (0) 639 640 641 /* Macros for tracing branches */ 642 643 #define TRACE_BRANCH_INPUT(COND) \ 644 do { \ 645 if (TRACE_BRANCH_P (CPU)) \ 646 trace_input_bool1 (SD, CPU, TRACE_BRANCH_IDX, (COND)); \ 647 } while (0) 648 649 #define TRACE_BRANCH_RESULT(DEST) \ 650 do { \ 651 if (TRACE_BRANCH_P (CPU)) \ 652 trace_result_addr1 (SD, CPU, TRACE_BRANCH_IDX, (DEST)); \ 653 } while (0) 654 655 656 extern void trace_printf (SIM_DESC, sim_cpu *, const char *, ...) 657 ATTRIBUTE_PRINTF (3, 4); 658 659 extern void trace_vprintf (SIM_DESC, sim_cpu *, const char *, va_list) 660 ATTRIBUTE_PRINTF (3, 0); 661 662 /* Debug support. 663 This is included here because there isn't enough of it to justify 664 a sim-debug.h. */ 665 666 /* Return non-zero if debugging of IDX for CPU is enabled. */ 667 #define DEBUG_P(cpu, idx) \ 668 ((WITH_DEBUG & (1 << (idx))) != 0 \ 669 && CPU_DEBUG_FLAGS (cpu)[idx] != 0) 670 671 /* Non-zero if "--debug-insn" specified. */ 672 #define DEBUG_INSN_P(cpu) DEBUG_P (cpu, DEBUG_INSN_IDX) 673 674 /* Symbol related helpers. */ 675 int trace_load_symbols (SIM_DESC); 676 bfd_vma trace_sym_value (SIM_DESC, const char *name); 677 678 extern void sim_debug_printf (sim_cpu *, const char *, ...) 679 ATTRIBUTE_PRINTF (2, 3); 680 681 #endif /* SIM_TRACE_H */ 682