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