perf tools: Add support to specify pmu style event
[linux-3.10.git] / tools / perf / util / parse-events.y
1
2 %name-prefix "parse_events_"
3 %parse-param {struct list_head *list}
4 %parse-param {int *idx}
5
6 %{
7
8 #define YYDEBUG 1
9
10 #include <linux/compiler.h>
11 #include <linux/list.h>
12 #include "types.h"
13 #include "util.h"
14 #include "parse-events.h"
15
16 extern int parse_events_lex (void);
17
18 #define ABORT_ON(val) \
19 do { \
20         if (val) \
21                 YYABORT; \
22 } while (0)
23
24 %}
25
26 %token PE_VALUE PE_VALUE_SYM PE_RAW PE_TERM
27 %token PE_NAME
28 %token PE_MODIFIER_EVENT PE_MODIFIER_BP
29 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
30 %token PE_PREFIX_MEM PE_PREFIX_RAW
31 %token PE_ERROR
32 %type <num> PE_VALUE
33 %type <num> PE_VALUE_SYM
34 %type <num> PE_RAW
35 %type <num> PE_TERM
36 %type <str> PE_NAME
37 %type <str> PE_NAME_CACHE_TYPE
38 %type <str> PE_NAME_CACHE_OP_RESULT
39 %type <str> PE_MODIFIER_EVENT
40 %type <str> PE_MODIFIER_BP
41 %type <head> event_config
42 %type <term> event_term
43
44 %union
45 {
46         char *str;
47         unsigned long num;
48         struct list_head *head;
49         struct parse_events__term *term;
50 }
51 %%
52
53 events:
54 events ',' event | event
55
56 event:
57 event_def PE_MODIFIER_EVENT
58 {
59         ABORT_ON(parse_events_modifier(list, $2));
60 }
61 |
62 event_def
63
64 event_def: event_pmu |
65            event_legacy_symbol |
66            event_legacy_cache sep_dc |
67            event_legacy_mem |
68            event_legacy_tracepoint sep_dc |
69            event_legacy_numeric sep_dc |
70            event_legacy_raw sep_dc
71
72 event_pmu:
73 PE_NAME '/' event_config '/'
74 {
75         ABORT_ON(parse_events_add_pmu(list, idx, $1, $3));
76         parse_events__free_terms($3);
77 }
78
79 event_legacy_symbol:
80 PE_VALUE_SYM '/' event_config '/'
81 {
82         int type = $1 >> 16;
83         int config = $1 & 255;
84
85         ABORT_ON(parse_events_add_numeric(list, idx, type, config, $3));
86         parse_events__free_terms($3);
87 }
88 |
89 PE_VALUE_SYM sep_slash_dc
90 {
91         int type = $1 >> 16;
92         int config = $1 & 255;
93
94         ABORT_ON(parse_events_add_numeric(list, idx, type, config, NULL));
95 }
96
97 event_legacy_cache:
98 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT
99 {
100         ABORT_ON(parse_events_add_cache(list, idx, $1, $3, $5));
101 }
102 |
103 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT
104 {
105         ABORT_ON(parse_events_add_cache(list, idx, $1, $3, NULL));
106 }
107 |
108 PE_NAME_CACHE_TYPE
109 {
110         ABORT_ON(parse_events_add_cache(list, idx, $1, NULL, NULL));
111 }
112
113 event_legacy_mem:
114 PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
115 {
116         ABORT_ON(parse_events_add_breakpoint(list, idx, (void *) $2, $4));
117 }
118 |
119 PE_PREFIX_MEM PE_VALUE sep_dc
120 {
121         ABORT_ON(parse_events_add_breakpoint(list, idx, (void *) $2, NULL));
122 }
123
124 event_legacy_tracepoint:
125 PE_NAME ':' PE_NAME
126 {
127         ABORT_ON(parse_events_add_tracepoint(list, idx, $1, $3));
128 }
129
130 event_legacy_numeric:
131 PE_VALUE ':' PE_VALUE
132 {
133         ABORT_ON(parse_events_add_numeric(list, idx, $1, $3, NULL));
134 }
135
136 event_legacy_raw:
137 PE_RAW
138 {
139         ABORT_ON(parse_events_add_numeric(list, idx, PERF_TYPE_RAW, $1, NULL));
140 }
141
142 event_config:
143 event_config ',' event_term
144 {
145         struct list_head *head = $1;
146         struct parse_events__term *term = $3;
147
148         ABORT_ON(!head);
149         list_add_tail(&term->list, head);
150         $$ = $1;
151 }
152 |
153 event_term
154 {
155         struct list_head *head = malloc(sizeof(*head));
156         struct parse_events__term *term = $1;
157
158         ABORT_ON(!head);
159         INIT_LIST_HEAD(head);
160         list_add_tail(&term->list, head);
161         $$ = head;
162 }
163
164 event_term:
165 PE_NAME '=' PE_NAME
166 {
167         struct parse_events__term *term;
168
169         ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_STR,
170                  $1, $3, 0));
171         $$ = term;
172 }
173 |
174 PE_NAME '=' PE_VALUE
175 {
176         struct parse_events__term *term;
177
178         ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM,
179                  $1, NULL, $3));
180         $$ = term;
181 }
182 |
183 PE_NAME
184 {
185         struct parse_events__term *term;
186
187         ABORT_ON(parse_events__new_term(&term, PARSE_EVENTS__TERM_TYPE_NUM,
188                  $1, NULL, 1));
189         $$ = term;
190 }
191 |
192 PE_TERM '=' PE_VALUE
193 {
194         struct parse_events__term *term;
195
196         ABORT_ON(parse_events__new_term(&term, $1, NULL, NULL, $3));
197         $$ = term;
198 }
199 |
200 PE_TERM
201 {
202         struct parse_events__term *term;
203
204         ABORT_ON(parse_events__new_term(&term, $1, NULL, NULL, 1));
205         $$ = term;
206 }
207
208 sep_dc: ':' |
209
210 sep_slash_dc: '/' | ':' |
211
212 %%
213
214 void parse_events_error(struct list_head *list __used, int *idx __used,
215                         char const *msg __used)
216 {
217 }