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