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