xref: /openbmc/linux/tools/perf/util/branch.h (revision ff165628d72644e37674c5485658e8bd9f4a348b)
1992c7e92SJin Yao #ifndef _PERF_BRANCH_H
2992c7e92SJin Yao #define _PERF_BRANCH_H 1
3fb71c86cSArnaldo Carvalho de Melo /*
4fb71c86cSArnaldo Carvalho de Melo  * The linux/stddef.h isn't need here, but is needed for __always_inline used
5fb71c86cSArnaldo Carvalho de Melo  * in files included from uapi/linux/perf_event.h such as
6fb71c86cSArnaldo Carvalho de Melo  * /usr/include/linux/swab.h and /usr/include/linux/byteorder/little_endian.h,
7fb71c86cSArnaldo Carvalho de Melo  * detected in at least musl libc, used in Alpine Linux. -acme
8fb71c86cSArnaldo Carvalho de Melo  */
9f1a397f3SArnaldo Carvalho de Melo #include <stdio.h>
10992c7e92SJin Yao #include <stdint.h>
11fb71c86cSArnaldo Carvalho de Melo #include <linux/compiler.h>
12fb71c86cSArnaldo Carvalho de Melo #include <linux/stddef.h>
13f1a397f3SArnaldo Carvalho de Melo #include <linux/perf_event.h>
14f1a397f3SArnaldo Carvalho de Melo #include <linux/types.h>
1542bbabedSKan Liang #include "event.h"
16f1a397f3SArnaldo Carvalho de Melo 
17f1a397f3SArnaldo Carvalho de Melo struct branch_flags {
18*ff165628SKan Liang 	union {
19*ff165628SKan Liang 		u64 value;
20*ff165628SKan Liang 		struct {
21f1a397f3SArnaldo Carvalho de Melo 			u64 mispred:1;
22f1a397f3SArnaldo Carvalho de Melo 			u64 predicted:1;
23f1a397f3SArnaldo Carvalho de Melo 			u64 in_tx:1;
24f1a397f3SArnaldo Carvalho de Melo 			u64 abort:1;
25f1a397f3SArnaldo Carvalho de Melo 			u64 cycles:16;
26f1a397f3SArnaldo Carvalho de Melo 			u64 type:4;
27f1a397f3SArnaldo Carvalho de Melo 			u64 reserved:40;
28f1a397f3SArnaldo Carvalho de Melo 		};
29*ff165628SKan Liang 	};
30*ff165628SKan Liang };
31f1a397f3SArnaldo Carvalho de Melo 
32d3300a3cSArnaldo Carvalho de Melo struct branch_info {
33d3300a3cSArnaldo Carvalho de Melo 	struct addr_map_symbol from;
34d3300a3cSArnaldo Carvalho de Melo 	struct addr_map_symbol to;
35d3300a3cSArnaldo Carvalho de Melo 	struct branch_flags    flags;
36d3300a3cSArnaldo Carvalho de Melo 	char		       *srcline_from;
37d3300a3cSArnaldo Carvalho de Melo 	char		       *srcline_to;
38d3300a3cSArnaldo Carvalho de Melo };
39d3300a3cSArnaldo Carvalho de Melo 
40f1a397f3SArnaldo Carvalho de Melo struct branch_entry {
41f1a397f3SArnaldo Carvalho de Melo 	u64			from;
42f1a397f3SArnaldo Carvalho de Melo 	u64			to;
43f1a397f3SArnaldo Carvalho de Melo 	struct branch_flags	flags;
44f1a397f3SArnaldo Carvalho de Melo };
45f1a397f3SArnaldo Carvalho de Melo 
46f1a397f3SArnaldo Carvalho de Melo struct branch_stack {
47f1a397f3SArnaldo Carvalho de Melo 	u64			nr;
4842bbabedSKan Liang 	u64			hw_idx;
49f1a397f3SArnaldo Carvalho de Melo 	struct branch_entry	entries[0];
50f1a397f3SArnaldo Carvalho de Melo };
51992c7e92SJin Yao 
5242bbabedSKan Liang /*
5342bbabedSKan Liang  * The hw_idx is only available when PERF_SAMPLE_BRANCH_HW_INDEX is applied.
5442bbabedSKan Liang  * Otherwise, the output format of a sample with branch stack is
5542bbabedSKan Liang  * struct branch_stack {
5642bbabedSKan Liang  *	u64			nr;
5742bbabedSKan Liang  *	struct branch_entry	entries[0];
5842bbabedSKan Liang  * }
5942bbabedSKan Liang  * Check whether the hw_idx is available,
6042bbabedSKan Liang  * and return the corresponding pointer of entries[0].
6142bbabedSKan Liang  */
6242bbabedSKan Liang static inline struct branch_entry *perf_sample__branch_entries(struct perf_sample *sample)
6342bbabedSKan Liang {
6442bbabedSKan Liang 	u64 *entry = (u64 *)sample->branch_stack;
6542bbabedSKan Liang 
6642bbabedSKan Liang 	entry++;
6742bbabedSKan Liang 	if (sample->no_hw_idx)
6842bbabedSKan Liang 		return (struct branch_entry *)entry;
6942bbabedSKan Liang 	return (struct branch_entry *)(++entry);
7042bbabedSKan Liang }
7142bbabedSKan Liang 
72992c7e92SJin Yao struct branch_type_stat {
73a1a8bed3SJin Yao 	bool	branch_to;
74992c7e92SJin Yao 	u64	counts[PERF_BR_MAX];
75992c7e92SJin Yao 	u64	cond_fwd;
76992c7e92SJin Yao 	u64	cond_bwd;
77992c7e92SJin Yao 	u64	cross_4k;
78992c7e92SJin Yao 	u64	cross_2m;
79992c7e92SJin Yao };
80992c7e92SJin Yao 
81992c7e92SJin Yao void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
82992c7e92SJin Yao 		       u64 from, u64 to);
83992c7e92SJin Yao 
84992c7e92SJin Yao const char *branch_type_name(int type);
85992c7e92SJin Yao void branch_type_stat_display(FILE *fp, struct branch_type_stat *st);
86992c7e92SJin Yao int branch_type_str(struct branch_type_stat *st, char *bf, int bfsize);
87992c7e92SJin Yao 
88992c7e92SJin Yao #endif /* _PERF_BRANCH_H */
89