xref: /netbsd-src/external/gpl3/gdb/dist/sim/common/sim-trace.h (revision 88241920d21b339bf319c0e979ffda80c49a2936)
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