xref: /openbmc/linux/tools/perf/util/branch.h (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
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>
10f1a397f3SArnaldo Carvalho de Melo #include <linux/perf_event.h>
11f1a397f3SArnaldo Carvalho de Melo #include <linux/types.h>
1208043330SArnaldo Carvalho de Melo #include "util/map_symbol.h"
139823147dSArnaldo Carvalho de Melo #include "util/sample.h"
14f1a397f3SArnaldo Carvalho de Melo 
15f1a397f3SArnaldo Carvalho de Melo struct branch_flags {
16ff165628SKan Liang 	union {
17ff165628SKan Liang 		u64 value;
18ff165628SKan Liang 		struct {
19f1a397f3SArnaldo Carvalho de Melo 			u64 mispred:1;
20f1a397f3SArnaldo Carvalho de Melo 			u64 predicted:1;
21f1a397f3SArnaldo Carvalho de Melo 			u64 in_tx:1;
22f1a397f3SArnaldo Carvalho de Melo 			u64 abort:1;
23f1a397f3SArnaldo Carvalho de Melo 			u64 cycles:16;
24f1a397f3SArnaldo Carvalho de Melo 			u64 type:4;
2520ed9fa4SJames Clark 			u64 spec:2;
260ddea8e2SAnshuman Khandual 			u64 new_type:4;
27bcb96ce6SAnshuman Khandual 			u64 priv:3;
2820ed9fa4SJames Clark 			u64 reserved:31;
29f1a397f3SArnaldo Carvalho de Melo 		};
30ff165628SKan Liang 	};
31ff165628SKan Liang };
32f1a397f3SArnaldo Carvalho de Melo 
33d3300a3cSArnaldo Carvalho de Melo struct branch_info {
34d3300a3cSArnaldo Carvalho de Melo 	struct addr_map_symbol from;
35d3300a3cSArnaldo Carvalho de Melo 	struct addr_map_symbol to;
36d3300a3cSArnaldo Carvalho de Melo 	struct branch_flags    flags;
37d3300a3cSArnaldo Carvalho de Melo 	char		       *srcline_from;
38d3300a3cSArnaldo Carvalho de Melo 	char		       *srcline_to;
39d3300a3cSArnaldo Carvalho de Melo };
40d3300a3cSArnaldo Carvalho de Melo 
41f1a397f3SArnaldo Carvalho de Melo struct branch_entry {
42f1a397f3SArnaldo Carvalho de Melo 	u64			from;
43f1a397f3SArnaldo Carvalho de Melo 	u64			to;
44f1a397f3SArnaldo Carvalho de Melo 	struct branch_flags	flags;
45f1a397f3SArnaldo Carvalho de Melo };
46f1a397f3SArnaldo Carvalho de Melo 
47f1a397f3SArnaldo Carvalho de Melo struct branch_stack {
48f1a397f3SArnaldo Carvalho de Melo 	u64			nr;
4942bbabedSKan Liang 	u64			hw_idx;
50ffe7428eSGustavo A. R. Silva 	struct branch_entry	entries[];
51f1a397f3SArnaldo Carvalho de Melo };
52992c7e92SJin Yao 
5342bbabedSKan Liang /*
5442bbabedSKan Liang  * The hw_idx is only available when PERF_SAMPLE_BRANCH_HW_INDEX is applied.
5542bbabedSKan Liang  * Otherwise, the output format of a sample with branch stack is
5642bbabedSKan Liang  * struct branch_stack {
5742bbabedSKan Liang  *	u64			nr;
5842bbabedSKan Liang  *	struct branch_entry	entries[0];
5942bbabedSKan Liang  * }
6042bbabedSKan Liang  * Check whether the hw_idx is available,
6142bbabedSKan Liang  * and return the corresponding pointer of entries[0].
6242bbabedSKan Liang  */
perf_sample__branch_entries(struct perf_sample * sample)6342bbabedSKan Liang static inline struct branch_entry *perf_sample__branch_entries(struct perf_sample *sample)
6442bbabedSKan Liang {
6542bbabedSKan Liang 	u64 *entry = (u64 *)sample->branch_stack;
6642bbabedSKan Liang 
6742bbabedSKan Liang 	entry++;
6842bbabedSKan Liang 	if (sample->no_hw_idx)
6942bbabedSKan Liang 		return (struct branch_entry *)entry;
7042bbabedSKan Liang 	return (struct branch_entry *)(++entry);
7142bbabedSKan Liang }
7242bbabedSKan Liang 
73992c7e92SJin Yao struct branch_type_stat {
74a1a8bed3SJin Yao 	bool	branch_to;
75992c7e92SJin Yao 	u64	counts[PERF_BR_MAX];
760ddea8e2SAnshuman Khandual 	u64	new_counts[PERF_BR_NEW_MAX];
77992c7e92SJin Yao 	u64	cond_fwd;
78992c7e92SJin Yao 	u64	cond_bwd;
79992c7e92SJin Yao 	u64	cross_4k;
80992c7e92SJin Yao 	u64	cross_2m;
81992c7e92SJin Yao };
82992c7e92SJin Yao 
83992c7e92SJin Yao void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
84992c7e92SJin Yao 		       u64 from, u64 to);
85992c7e92SJin Yao 
86992c7e92SJin Yao const char *branch_type_name(int type);
870ddea8e2SAnshuman Khandual const char *branch_new_type_name(int new_type);
880ddea8e2SAnshuman Khandual const char *get_branch_type(struct branch_entry *e);
89992c7e92SJin Yao void branch_type_stat_display(FILE *fp, struct branch_type_stat *st);
90992c7e92SJin Yao int branch_type_str(struct branch_type_stat *st, char *bf, int bfsize);
91992c7e92SJin Yao 
92*6ade6c64SSandipan Das const char *branch_spec_desc(int spec);
93*6ade6c64SSandipan Das 
94992c7e92SJin Yao #endif /* _PERF_BRANCH_H */
95