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