Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[firefly-linux-kernel-4.4.55.git] / tools / perf / util / parse-events.y
1 %pure-parser
2 %parse-param {void *_data}
3 %parse-param {void *scanner}
4 %lex-param {void* scanner}
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 #include "parse-events-bison.h"
16
17 extern int parse_events_lex (YYSTYPE* lvalp, void* scanner);
18
19 #define ABORT_ON(val) \
20 do { \
21         if (val) \
22                 YYABORT; \
23 } while (0)
24
25 static inc_group_count(struct list_head *list,
26                        struct parse_events_evlist *data)
27 {
28         /* Count groups only have more than 1 members */
29         if (!list_is_last(list->next, list))
30                 data->nr_groups++;
31 }
32
33 %}
34
35 %token PE_START_EVENTS PE_START_TERMS
36 %token PE_VALUE PE_VALUE_SYM_HW PE_VALUE_SYM_SW PE_RAW PE_TERM
37 %token PE_EVENT_NAME
38 %token PE_NAME
39 %token PE_MODIFIER_EVENT PE_MODIFIER_BP
40 %token PE_NAME_CACHE_TYPE PE_NAME_CACHE_OP_RESULT
41 %token PE_PREFIX_MEM PE_PREFIX_RAW PE_PREFIX_GROUP
42 %token PE_ERROR
43 %type <num> PE_VALUE
44 %type <num> PE_VALUE_SYM_HW
45 %type <num> PE_VALUE_SYM_SW
46 %type <num> PE_RAW
47 %type <num> PE_TERM
48 %type <str> PE_NAME
49 %type <str> PE_NAME_CACHE_TYPE
50 %type <str> PE_NAME_CACHE_OP_RESULT
51 %type <str> PE_MODIFIER_EVENT
52 %type <str> PE_MODIFIER_BP
53 %type <str> PE_EVENT_NAME
54 %type <num> value_sym
55 %type <head> event_config
56 %type <term> event_term
57 %type <head> event_pmu
58 %type <head> event_legacy_symbol
59 %type <head> event_legacy_cache
60 %type <head> event_legacy_mem
61 %type <head> event_legacy_tracepoint
62 %type <head> event_legacy_numeric
63 %type <head> event_legacy_raw
64 %type <head> event_def
65 %type <head> event_mod
66 %type <head> event_name
67 %type <head> event
68 %type <head> events
69 %type <head> group_def
70 %type <head> group
71 %type <head> groups
72
73 %union
74 {
75         char *str;
76         u64 num;
77         struct list_head *head;
78         struct parse_events_term *term;
79 }
80 %%
81
82 start:
83 PE_START_EVENTS start_events
84 |
85 PE_START_TERMS  start_terms
86
87 start_events: groups
88 {
89         struct parse_events_evlist *data = _data;
90
91         parse_events_update_lists($1, &data->list);
92 }
93
94 groups:
95 groups ',' group
96 {
97         struct list_head *list  = $1;
98         struct list_head *group = $3;
99
100         parse_events_update_lists(group, list);
101         $$ = list;
102 }
103 |
104 groups ',' event
105 {
106         struct list_head *list  = $1;
107         struct list_head *event = $3;
108
109         parse_events_update_lists(event, list);
110         $$ = list;
111 }
112 |
113 group
114 |
115 event
116
117 group:
118 group_def ':' PE_MODIFIER_EVENT
119 {
120         struct list_head *list = $1;
121
122         ABORT_ON(parse_events__modifier_group(list, $3));
123         $$ = list;
124 }
125 |
126 group_def
127
128 group_def:
129 PE_NAME '{' events '}'
130 {
131         struct list_head *list = $3;
132
133         inc_group_count(list, _data);
134         parse_events__set_leader($1, list);
135         $$ = list;
136 }
137 |
138 '{' events '}'
139 {
140         struct list_head *list = $2;
141
142         inc_group_count(list, _data);
143         parse_events__set_leader(NULL, list);
144         $$ = list;
145 }
146
147 events:
148 events ',' event
149 {
150         struct list_head *event = $3;
151         struct list_head *list  = $1;
152
153         parse_events_update_lists(event, list);
154         $$ = list;
155 }
156 |
157 event
158
159 event: event_mod
160
161 event_mod:
162 event_name PE_MODIFIER_EVENT
163 {
164         struct list_head *list = $1;
165
166         /*
167          * Apply modifier on all events added by single event definition
168          * (there could be more events added for multiple tracepoint
169          * definitions via '*?'.
170          */
171         ABORT_ON(parse_events__modifier_event(list, $2, false));
172         $$ = list;
173 }
174 |
175 event_name
176
177 event_name:
178 PE_EVENT_NAME event_def
179 {
180         ABORT_ON(parse_events_name($2, $1));
181         free($1);
182         $$ = $2;
183 }
184 |
185 event_def
186
187 event_def: event_pmu |
188            event_legacy_symbol |
189            event_legacy_cache sep_dc |
190            event_legacy_mem |
191            event_legacy_tracepoint sep_dc |
192            event_legacy_numeric sep_dc |
193            event_legacy_raw sep_dc
194
195 event_pmu:
196 PE_NAME '/' event_config '/'
197 {
198         struct parse_events_evlist *data = _data;
199         struct list_head *list = NULL;
200
201         ABORT_ON(parse_events_add_pmu(&list, &data->idx, $1, $3));
202         parse_events__free_terms($3);
203         $$ = list;
204 }
205
206 value_sym:
207 PE_VALUE_SYM_HW
208 |
209 PE_VALUE_SYM_SW
210
211 event_legacy_symbol:
212 value_sym '/' event_config '/'
213 {
214         struct parse_events_evlist *data = _data;
215         struct list_head *list = NULL;
216         int type = $1 >> 16;
217         int config = $1 & 255;
218
219         ABORT_ON(parse_events_add_numeric(&list, &data->idx,
220                                           type, config, $3));
221         parse_events__free_terms($3);
222         $$ = list;
223 }
224 |
225 value_sym sep_slash_dc
226 {
227         struct parse_events_evlist *data = _data;
228         struct list_head *list = NULL;
229         int type = $1 >> 16;
230         int config = $1 & 255;
231
232         ABORT_ON(parse_events_add_numeric(&list, &data->idx,
233                                           type, config, NULL));
234         $$ = list;
235 }
236
237 event_legacy_cache:
238 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT
239 {
240         struct parse_events_evlist *data = _data;
241         struct list_head *list = NULL;
242
243         ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, $5));
244         $$ = list;
245 }
246 |
247 PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT
248 {
249         struct parse_events_evlist *data = _data;
250         struct list_head *list = NULL;
251
252         ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, $3, NULL));
253         $$ = list;
254 }
255 |
256 PE_NAME_CACHE_TYPE
257 {
258         struct parse_events_evlist *data = _data;
259         struct list_head *list = NULL;
260
261         ABORT_ON(parse_events_add_cache(&list, &data->idx, $1, NULL, NULL));
262         $$ = list;
263 }
264
265 event_legacy_mem:
266 PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc
267 {
268         struct parse_events_evlist *data = _data;
269         struct list_head *list = NULL;
270
271         ABORT_ON(parse_events_add_breakpoint(&list, &data->idx,
272                                              (void *) $2, $4));
273         $$ = list;
274 }
275 |
276 PE_PREFIX_MEM PE_VALUE sep_dc
277 {
278         struct parse_events_evlist *data = _data;
279         struct list_head *list = NULL;
280
281         ABORT_ON(parse_events_add_breakpoint(&list, &data->idx,
282                                              (void *) $2, NULL));
283         $$ = list;
284 }
285
286 event_legacy_tracepoint:
287 PE_NAME ':' PE_NAME
288 {
289         struct parse_events_evlist *data = _data;
290         struct list_head *list = NULL;
291
292         ABORT_ON(parse_events_add_tracepoint(&list, &data->idx, $1, $3));
293         $$ = list;
294 }
295
296 event_legacy_numeric:
297 PE_VALUE ':' PE_VALUE
298 {
299         struct parse_events_evlist *data = _data;
300         struct list_head *list = NULL;
301
302         ABORT_ON(parse_events_add_numeric(&list, &data->idx, (u32)$1, $3, NULL));
303         $$ = list;
304 }
305
306 event_legacy_raw:
307 PE_RAW
308 {
309         struct parse_events_evlist *data = _data;
310         struct list_head *list = NULL;
311
312         ABORT_ON(parse_events_add_numeric(&list, &data->idx,
313                                           PERF_TYPE_RAW, $1, NULL));
314         $$ = list;
315 }
316
317 start_terms: event_config
318 {
319         struct parse_events_terms *data = _data;
320         data->terms = $1;
321 }
322
323 event_config:
324 event_config ',' event_term
325 {
326         struct list_head *head = $1;
327         struct parse_events_term *term = $3;
328
329         ABORT_ON(!head);
330         list_add_tail(&term->list, head);
331         $$ = $1;
332 }
333 |
334 event_term
335 {
336         struct list_head *head = malloc(sizeof(*head));
337         struct parse_events_term *term = $1;
338
339         ABORT_ON(!head);
340         INIT_LIST_HEAD(head);
341         list_add_tail(&term->list, head);
342         $$ = head;
343 }
344
345 event_term:
346 PE_NAME '=' PE_NAME
347 {
348         struct parse_events_term *term;
349
350         ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER,
351                                         $1, $3));
352         $$ = term;
353 }
354 |
355 PE_NAME '=' PE_VALUE
356 {
357         struct parse_events_term *term;
358
359         ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
360                                         $1, $3));
361         $$ = term;
362 }
363 |
364 PE_NAME '=' PE_VALUE_SYM_HW
365 {
366         struct parse_events_term *term;
367         int config = $3 & 255;
368
369         ABORT_ON(parse_events_term__sym_hw(&term, $1, config));
370         $$ = term;
371 }
372 |
373 PE_NAME
374 {
375         struct parse_events_term *term;
376
377         ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
378                                         $1, 1));
379         $$ = term;
380 }
381 |
382 PE_VALUE_SYM_HW
383 {
384         struct parse_events_term *term;
385         int config = $1 & 255;
386
387         ABORT_ON(parse_events_term__sym_hw(&term, NULL, config));
388         $$ = term;
389 }
390 |
391 PE_TERM '=' PE_NAME
392 {
393         struct parse_events_term *term;
394
395         ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3));
396         $$ = term;
397 }
398 |
399 PE_TERM '=' PE_VALUE
400 {
401         struct parse_events_term *term;
402
403         ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, $3));
404         $$ = term;
405 }
406 |
407 PE_TERM
408 {
409         struct parse_events_term *term;
410
411         ABORT_ON(parse_events_term__num(&term, (int)$1, NULL, 1));
412         $$ = term;
413 }
414
415 sep_dc: ':' |
416
417 sep_slash_dc: '/' | ':' |
418
419 %%
420
421 void parse_events_error(void *data __maybe_unused, void *scanner __maybe_unused,
422                         char const *msg __maybe_unused)
423 {
424 }